From 9eb19f8852faf1b5cc7d64bd28eefb9307c78baf Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Tue, 6 Jan 2015 15:39:44 -0200 Subject: [PATCH] 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 +-- .../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 fab4c1608c..d029999411 100644 --- a/src/bin/eolian_cxx/convert.cc +++ b/src/bin/eolian_cxx/convert.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,7 @@ namespace eolian_cxx { extern efl::eina::log_domain domain; +typedef std::map event_map; void add_ancestor_recursive(const char* klass_name, std::set& ancestor) @@ -48,6 +50,40 @@ add_ancestor_recursive(const char* klass_name, std::set& ancestor) eina_iterator_free(inheritances); } +void +add_events_recursive(event_map& events, Eolian_Class const& klass, std::set& 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(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 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 42b034dcef..38f2d38127 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 1e23751f4f..0b6f5cffca 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 eeb900b398..4b7a9b3d4d 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::type function_type;" << endl - << tab(2) << "::std::unique_ptr f ( new function_type(std::move(callback_)) );" << endl + << tab(2) << "::std::unique_ptr f ( new function_type(std::forward(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 1abf1ba675..15850abfd3 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