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