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.
This commit is contained in:
Vitor Sousa 2015-01-06 15:39:44 -02:00 committed by Felipe Magno de Almeida
parent 4b950b55c0
commit 9eb19f8852
5 changed files with 67 additions and 10 deletions

View File

@ -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

View File

@ -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; }
};

View File

@ -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 {

View File

@ -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);

View File

@ -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