felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9eb19f8852faf1b5cc7d64bd28eefb9307c78baf

commit 9eb19f8852faf1b5cc7d64bd28eefb9307c78baf
Author: Vitor Sousa <vitorsousasi...@gmail.com>
Date:   Tue Jan 6 15:39:44 2015 -0200

    eolian_cxx: Declaring all inherited events on the concrete C++ wrapper
    
    Added declaration of all inherited events on the concrete type to
    avoid unnecessary type conversion on event callbacks.
    
    Note that when two events happens to have the same name, only the
    event of the derived class is declared in the concrete class. Access to
    such events should be made through the base class type specification.
    
    Fix on forwarding callback object (changed std::move to std::forward).
    
    Additional line break at the end of event handling methods in the
    generated headers to improve readability.
---
 src/bin/eolian_cxx/convert.cc                      | 56 +++++++++++++++++++++-
 src/lib/eolian_cxx/eo_types.hh                     |  5 +-
 src/lib/eolian_cxx/eo_validate.hh                  |  3 +-
 .../grammar/eo_class_events_generator.hh           |  9 ++--
 src/lib/eolian_cxx/grammar/eo_class_generator.hh   |  4 +-
 5 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc
index fab4c16..d029999 100644
--- a/src/bin/eolian_cxx/convert.cc
+++ b/src/bin/eolian_cxx/convert.cc
@@ -1,6 +1,7 @@
 
 #include <vector>
 #include <set>
+#include <map>
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -22,6 +23,7 @@
 namespace eolian_cxx {
 
 extern efl::eina::log_domain domain;
+typedef std::map<efl::eolian::eo_event, bool> event_map;
 
 void
 add_ancestor_recursive(const char* klass_name, std::set<std::string>& ancestor)
@@ -48,6 +50,40 @@ add_ancestor_recursive(const char* klass_name, 
std::set<std::string>& ancestor)
    eina_iterator_free(inheritances);
 }
 
+void
+add_events_recursive(event_map& events, Eolian_Class const& klass, 
std::set<std::string>& ancestors)
+{
+   for (efl::eolian::eo_event const& e : event_list(klass))
+     {
+        auto it = events.find(e);
+        if (it == events.end())
+          events[e] = true;
+        else
+          it->second = false;
+     }
+
+   Eina_Iterator* inheritances = ::eolian_class_inherits_get(&klass);
+   void* curr = 0;
+
+   EINA_ITERATOR_FOREACH(inheritances, curr)
+     {
+        const char* ancestor_name = static_cast<const char*>(curr);
+        if (!ancestor_name || ancestors.find(ancestor_name) != ancestors.end())
+          continue;
+
+        Eolian_Class const* ancestor_klass = 
::eolian_class_get_by_name(ancestor_name);
+        if (!ancestor_klass)
+          {
+             std::cerr << "Error: could not get eolian class name `" << 
ancestor_name << "'" << std::endl;
+             continue;
+          }
+        ancestors.insert(ancestor_name);
+        add_events_recursive(events, *ancestor_klass, ancestors);
+     }
+
+   eina_iterator_free(inheritances);
+}
+
 static efl::eolian::parameters_container_type
 _convert_eolian_parameters(Eina_Iterator *parameters,
                           Eolian_Function_Type func_type)
@@ -199,8 +235,24 @@ void
 convert_eolian_events(efl::eolian::eo_class& cls, Eolian_Class const& klass)
 {
    efl::eolian::events_container_type events = event_list(klass);
-   cls.events.reserve(cls.events.size() + events.size());
-   cls.events.insert(cls.events.end(), events.begin(), events.end());
+   cls.own_events.reserve(cls.own_events.size() + events.size());
+   cls.own_events.insert(cls.own_events.end(), events.begin(), events.end());
+
+   event_map concrete_events;
+   std::set<std::string> ancestors;
+
+   add_events_recursive(concrete_events, klass, ancestors);
+
+   for (auto const& e : events)
+     {
+        concrete_events[e] = true;
+     }
+
+   for (auto const& pair : concrete_events)
+     {
+        if (pair.second)
+          cls.concrete_events.push_back(pair.first);
+     }
 }
 
 efl::eolian::eo_class
diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh
index 42b034d..38f2d38 100644
--- a/src/lib/eolian_cxx/eo_types.hh
+++ b/src/lib/eolian_cxx/eo_types.hh
@@ -230,7 +230,8 @@ struct eo_class
    ancestors_container_type ancestors;
    constructors_container_type constructors;
    functions_container_type functions;
-   events_container_type events;
+   events_container_type own_events;
+   events_container_type concrete_events;
    std::string comment;
    std::string name_space;
 };
@@ -268,6 +269,8 @@ struct eo_event
    std::string eo_name;
    //parameters_container_type params; // XXX desirable.
    std::string comment;
+
+   bool operator<(eo_event const& other) const { return name < other.name; }
 };
 
 
diff --git a/src/lib/eolian_cxx/eo_validate.hh 
b/src/lib/eolian_cxx/eo_validate.hh
index 1e23751..0b6f5cf 100644
--- a/src/lib/eolian_cxx/eo_validate.hh
+++ b/src/lib/eolian_cxx/eo_validate.hh
@@ -107,7 +107,8 @@ eo_class_validate(const eo_class& cls)
           }
      }
    // events
-   _validate(cls.events, cls);
+   _validate(cls.own_events, cls);
+   _validate(cls.concrete_events, cls);
 }
 
 } } // namespace efl { namespace eolian {
diff --git a/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh 
b/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
index eeb900b..4b7a9b3 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
@@ -49,7 +49,7 @@ operator<<(std::ostream& out, event_callback_add const& x)
        << tab(8) << "::efl::eo::callback_priorities::default_)" << endl
        << tab(1) << "{" << endl
        << tab(2) << "typedef typename std::remove_reference<F>::type 
function_type;" << endl
-       << tab(2) << "::std::unique_ptr<function_type> f ( new 
function_type(std::move(callback_)) );" << endl
+       << tab(2) << "::std::unique_ptr<function_type> f ( new 
function_type(std::forward<F>(callback_)) );" << endl
        << tab(2) << "eo_do(" << add_cast_to_t(x._add_cast_to_t) << 
"_concrete_eo_ptr()," << endl
        << tab(4) << "eo_event_callback_priority_add" << endl
        << tab(4) << "(" << x._event.eo_name << ", priority_," << endl
@@ -88,15 +88,16 @@ operator<<(std::ostream& out, event_callback_call const& x)
 struct events
 {
    eo_class const& _cls;
+   events_container_type const& _events;
    bool _add_cast_to_t;
-   events(eo_class const& cls, bool add_cast_to_t = false)
-     : _cls(cls), _add_cast_to_t(add_cast_to_t) {}
+   events(eo_class const& cls, events_container_type const& evts, bool 
add_cast_to_t = false)
+     : _cls(cls), _events(evts), _add_cast_to_t(add_cast_to_t) {}
 };
 
 inline std::ostream&
 operator<<(std::ostream& out, events const& x)
 {
-   for (eo_event const& e : x._cls.events)
+   for (eo_event const& e : x._events)
      {
         out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl
            << event_callback_call(e, x._add_cast_to_t);
diff --git a/src/lib/eolian_cxx/grammar/eo_class_generator.hh 
b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
index 1abf1ba..15850ab 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
@@ -205,7 +205,7 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
        << "struct " << cls.name << endl
        << '{' << endl
        << function_declarations(cls)
-       << events(cls)
+       << events(cls, cls.own_events) << endl
        << eo_class_getter(cls)
        << class_implicit_conversion_declaration(cls)
        << abstract_address_of(cls)
@@ -226,7 +226,7 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
        << destructor(cls)
        << constructor_method_function_declarations(cls)
        << function_declarations(cls)
-       << events(cls)
+       << events(cls, cls.concrete_events) << endl
        << eo_class_getter(cls)
        << concrete_address_of(cls)
         << "private:" << endl

-- 


Reply via email to