}
void
-convert_eolian_implements(efl::eolian::eo_class& cls, Eolian_Class const& klass)
+convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
{
- efl::eina::iterator<const Eolian_Implement> itr = implements_get(klass);
- efl::eina::iterator<const Eolian_Implement> end;
-
- while (itr != end)
+ for(efl::eina::iterator<const Eolian_Function> first ( ::eolian_class_functions_get(&klass, EOLIAN_METHOD))
+ , last; first != last; ++first)
{
- const Eolian_Implement impl = *itr;
- assert(!!implement_function(impl));
- assert(!!implement_class(impl));
- Eolian_Function const& func = *implement_function(impl);
- Eolian_Class const& icls = *implement_class(impl);
+ Eolian_Function const& func = *first;
+ Eolian_Function_Type const func_type = function_op_type(func);
- if (implement_is_property_get(impl))
- {
- cls.functions.push_back
- (_convert_property_get_to_function(icls, func));
- }
- else if (implement_is_property_set(impl))
- {
- cls.functions.push_back
- (_convert_property_set_to_function(icls, func));
- }
- else if (function_op_type(func) == eolian_cxx::property.value)
- {
- cls.functions.push_back
- (_convert_property_get_to_function(icls, func));
- cls.functions.push_back
- (_convert_property_set_to_function(icls, func));
- }
- else if (function_is_constructor(klass, func))
+ if (function_is_constructor(klass, func))
{
cls.constructors.push_back({
function_impl(func),
_convert_eolian_parameters(func),
- convert_comments_function(icls, func)
+ convert_comments_function(klass, func)
});
}
- else if (implement_is_visible(impl))
+ else if (function_is_visible(func, func_type))
{
cls.functions.push_back({
function_type(func),
function_impl(func),
function_return_type(func),
_convert_eolian_parameters(func),
- convert_comments_function(icls, func, eolian_cxx::method)
+ convert_comments_function(klass, func, eolian_cxx::method)
});
}
- ++itr;
+ }
+ for(efl::eina::iterator<const Eolian_Function> first ( ::eolian_class_functions_get(&klass, EOLIAN_PROPERTY))
+ , last; first != last; ++first)
+ {
+ Eolian_Function const& func = *first;
+ Eolian_Function_Type t = ::eolian_function_type_get(&func);
+
+ if(t == EOLIAN_PROP_GET)
+ {
+ cls.functions.push_back
+ (_convert_property_get_to_function(klass, func));
+ }
+ else if(t == EOLIAN_PROP_SET)
+ {
+ cls.functions.push_back
+ (_convert_property_set_to_function(klass, func));
+ }
+ else if(t == EOLIAN_PROPERTY)
+ {
+ cls.functions.push_back
+ (_convert_property_get_to_function(klass, func));
+ cls.functions.push_back
+ (_convert_property_set_to_function(klass, func));
+ }
+ else
+ {
+ std::cerr << "Error: Inconsistent type for Eolian function \'" << ::eolian_function_name_get(&func) << "\'." << std::endl;
+ throw std::runtime_error("Invalid Eolian function type");
+ }
}
}
{
efl::eolian::eo_class cls(eolian_cxx::convert_eolian_class_new(klass));
eolian_cxx::convert_eolian_inheritances(cls, klass);
- eolian_cxx::convert_eolian_implements(cls, klass);
+ eolian_cxx::convert_eolian_functions(cls, klass);
eolian_cxx::convert_eolian_events(cls, klass);
efl::eolian::eo_class_validate(cls);
return cls;
}
void
-_colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b)
-{
- if(!_colourable_impl_logdomain)
- {
- _colourable_impl_logdomain
- = eina_log_domain_register("colourable", EINA_COLOR_BLUE);
- }
- self->r = r;
- self->g = g;
- self->b = b;
- DBG("_colourable_rgb_composite_constructor(0x%2.x, %0x2.x, %0x2.x)\n",
- (unsigned int)self->r,
- (unsigned int)self->g,
- (unsigned int)self->b);
- eo_do_super(obj, MY_CLASS, eo_constructor());
-}
-
-void
_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
{
if(!_colourable_impl_logdomain)
legacy_prefix: legacy;
data: Colourable_Data;
methods {
- rgb_composite_constructor {
- /*@ Composite RGB Constructor. */
- legacy: null;
- params {
- @in int r; /*@ The red component. */
- @in int g; /*@ The green component. */
- @in int b; /*@ The blue component. */
- }
- }
rgb_24bits_constructor {
/*@ RGB Constructor. */
legacy: null;
Eo.Base.destructor;
}
constructors {
- .rgb_composite_constructor;
.rgb_24bits_constructor;
}
events {
}
void
-_colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b)
-{
- EINA_CXX_DOM_LOG_DBG(domain) << std::showbase << std::hex
- << __func__ << " [ (r, g, b) = ("
- << r << ", " << g << ", " << b << ") ]" << std::endl;
- self->r = r;
- self->g = g;
- self->b = b;
- eo_do_super(obj, MY_CLASS, eo_constructor());
-}
-
-void
_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
{
EINA_CXX_DOM_LOG_DBG(domain) << std::showbase << std::hex
void _colourable_eo_base_constructor(Eo *obj, Colourable_Data *self);
void _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self);
-void _colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b);
void _colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb);
void _colourable_print_colour(Eo *obj, Colourable_Data *self);
void _colourable_print_colour(Eo *obj, Colourable_Data *self);
example_callbacks()
{
int count = 0;
- efl::ecore::poller poller
- (ECORE_POLLER_CORE, 1,
+ efl::ecore::poller poller(
+ poller.ecore_poller_constructor(ECORE_POLLER_CORE, 1,
[&count, &poller]
- {
- if (++count == 5)
- {
- std::cout << std::endl;
- ecore_main_loop_quit();
- return false;
- }
- poller.interval_set(2*poller.interval_get());
- std::cout << "."<< std::flush;
- return true;
- });
+ {
+ if (++count == 5)
+ {
+ std::cout << std::endl;
+ ecore_main_loop_quit();
+ return false;
+ }
+ poller.interval_set(2*poller.interval_get());
+ std::cout << "." << std::flush;
+ return true;
+ })
+ );
::ecore_main_loop_begin();
}
struct ColourableCircle
: efl::eo::inherit<ColourableCircle, ::colourable>
{
- ColourableCircle(int r, int g, int b)
- : inherit_base(r, g, b)
- {}
-
ColourableCircle(int rgb)
: inherit_base(efl::eo::args<::colourable>(rgb))
{}
efl::eo::eo_init init;
eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG);
- ColourableCircle obj1(0xc0, 0xff, 0xee);
+ ColourableCircle obj1(0x0);
+ obj1.composite_colour_set(0xc0, 0xff, 0xee);
ColourableCircle obj2(0xc0ffee);
int r, g, b;
eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
int r, g, b;
- ::colourable obj1(0x123456);
+ ::colourable obj1(
+ obj1.colourable_rgb_24bits_constructor(0x123456)
+ );
obj1.colour_set(0xc0ffee);
obj1.composite_colour_get(&r, &g, &b);
- ::colourablesquare obj2(10);
+ ::colourablesquare obj2(
+ obj2.colourablesquare_size_constructor(10)
+ );
obj2.composite_colour_set(r, g, b);
obj2.size_set(11);
assert(obj1.colour_get() == obj2.colour_get());
eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
int r, g, b;
- ::colourable obj1(0x123456);
+ ::colourable obj1(
+ obj1.colourable_rgb_24bits_constructor(0x123456)
+ );
obj1.colour_set(0xc0ffee);
obj1.composite_colour_get(&r, &g, &b);
- ::colourablesquare obj2(0x123456);
+ ::colourablesquare obj2(
+ obj2.colourablesquare_size_constructor(0x123456)
+ );
obj2.composite_colour_set(r, g, b);
obj2.size_set(11);
assert(obj1.colour_get() == obj2.colour_get());
return out;
}
+struct constructor_functor_type_name
+{
+ eo_constructor const& _ctor;
+ constructor_functor_type_name(eo_constructor const& ctor)
+ : _ctor(ctor)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, constructor_functor_type_name const& x)
+{
+ out << "_c_" << x._ctor.name;
+ return out;
+}
+
+struct constructor_functor_type_decl
+{
+ eo_constructor const& _ctor;
+ constructor_functor_type_decl(eo_constructor const& ctor)
+ : _ctor(ctor)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, constructor_functor_type_decl const& x)
+{
+ out << constructor_functor_type_name(x._ctor);
+ auto cb_it = parameters_find_callback(x._ctor.params);
+ if(cb_it != x._ctor.params.cend())
+ {
+ out << "<F>";
+ }
+ return out;
+}
+
+struct functors_constructor_methods
+{
+ eo_class const& _cls;
+ functors_constructor_methods(eo_class const& cls) : _cls(cls) {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, functors_constructor_methods const& x)
+{
+ constructors_container_type::const_iterator it,
+ first = x._cls.constructors.cbegin(),
+ last = x._cls.constructors.cend();
+ for (it = first; it != last; ++it)
+ {
+ eo_constructor const& c = *it;
+ auto cb_it = parameters_find_callback(c.params);
+ bool has_callback = (cb_it != c.params.cend());
+
+ // Struct declaration
+ if(has_callback)
+ {
+ out << tab(1) << "template <typename F>" << endl;
+ }
+ out << tab(1) << "struct " << constructor_functor_type_name(c) << endl
+ << tab(1) << "{" << endl;
+
+ // Struct constructor
+ out << tab(2) << constructor_functor_type_name(c) << "("
+ << parameters_declaration(c.params) << ")"
+ << parameters_cxx_generic(c.params,
+ [](param_data d)
+ {
+ if(d.pos == 0u)
+ d.out << endl << tab(3) << ": ";
+ else
+ d.out << ", ";
+ d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")";
+ }
+ )
+ << endl
+ << tab(2) << "{}" << endl;
+
+ // Struct operator()
+ out << tab(2) << "void operator()()" << endl
+ << tab(2) << "{" << endl;
+ if (has_callback)
+ {
+ out << tab(3) << "typedef typename std::remove_reference<F>::type function_type;" << endl
+ << tab(3) << "function_type* _tmp_f = new F(this->" << (*cb_it).name << ");" << endl;
+ }
+ out << tab(3) << "::" << c.name << "(" << parameters_forward_to_c(c.params) << ");" << endl
+ << tab(2) << "}" << endl;
+
+ // Struct member variables
+ out << tab(1) << "private:" << endl
+ << parameters_cxx_generic(c.params,
+ [](param_data d)
+ {
+ d.out << tab(2) << parameter_type(d.type) << " " << d.name << ";" << endl;
+ }
+ );
+
+ // Close struct
+ out << tab(1) << "};" << endl << endl;
+ }
+
+ return out;
+}
+
+struct functions_constructor_methods
+{
+ eo_class const& _cls;
+ functions_constructor_methods(eo_class const& cls) : _cls(cls) {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, functions_constructor_methods const& x)
+{
+ constructors_container_type::const_iterator it,
+ first = x._cls.constructors.cbegin(),
+ last = x._cls.constructors.cend();
+ for (it = first; it != last; ++it)
+ {
+ eo_constructor const& c = *it;
+
+ out << comment(c.comment, 1);
+
+ unsigned cb_count = parameters_count_callbacks(c.params);
+ if(cb_count)
+ out << tab(1) << "template <typename F>" << endl;
+ out << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
+ << parameters_declaration(c.params) << ")" << endl
+ << tab(1) << "{" << endl
+ << tab(2) << "return " << constructor_functor_type_decl(c) << "("
+ << parameters_forward(c.params) << ");" << endl
+ << tab(1) << "}" << endl << endl;
+ }
+
+ return out;
+}
+
+struct constructor_with_constructor_methods
+{
+ eo_class const& _cls;
+ constructor_with_constructor_methods(eo_class const& cls)
+ : _cls(cls)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
+{
+ //
+ // TODO Require constructor methods of all base classes ?
+ //
+
+ constructors_container_type::const_iterator it,
+ first = x._cls.constructors.cbegin(),
+ last = x._cls.constructors.cend();
+
+ for (it = first; it != last; ++it)
+ {
+ unsigned cb_count = parameters_count_callbacks((*it).params);
+ if(cb_count)
+ {
+ out << tab(1) << "template <typename F>" << endl;
+ break;
+ }
+ }
+
+ out << tab(1) << x._cls.name << "(";
+ for (it = first; it != last; ++it)
+ {
+ out << constructor_functor_type_decl(*it)
+ << " _c" << (it-first) << ", ";
+ }
+ out << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
+ << tab(2) << ": " << x._cls.name << "(_ctors_call(";
+ for (it = first; it != last; ++it)
+ {
+ out << "_c" << (it-first) << ", ";
+ }
+ out << "_p))" << endl
+ << tab(1) << "{}" << endl << endl;
+
+ return out;
+}
+
struct constructor_eo
{
eo_class const& _cls;
return out;
}
+struct function_call_constructor_methods
+{
+ eo_class const& _cls;
+ function_call_constructor_methods(eo_class const& cls) : _cls(cls) {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, function_call_constructor_methods const& x)
+{
+ constructors_container_type::const_iterator it,
+ first = x._cls.constructors.cbegin(),
+ last = x._cls.constructors.cend();
+ for (it = first; it != last; ++it)
+ {
+ unsigned cb_count = parameters_count_callbacks((*it).params);
+ if (cb_count)
+ {
+ out << tab(1) << "template <typename F>" << endl;
+ break;
+ }
+ }
+ out << tab(1) << "static Eo* _ctors_call(";
+ for (it = first; it != last; ++it)
+ {
+ out << constructor_functor_type_decl(*it) << " _c" << (it-first) << ", ";
+ }
+ out << "efl::eo::parent_type _p)" << endl
+ << tab(1) << "{" << endl
+ << tab(2) << "return eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, ";
+ for (it = first; it != last; ++it)
+ {
+ out << "_c" << (it-first) << "(); ";
+ }
+ out << ");" << endl
+ << tab(1) << "}" << endl << endl;
+
+ return out;
+}
+
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
<< "struct " << cls.name << endl
<< tab(2) << ": " << class_inheritance(cls)
<< '{' << endl
+ << functors_constructor_methods(cls)
+ << functions_constructor_methods(cls)
+ << constructor_with_constructor_methods(cls)
<< constructor_eo(cls)
- << constructors(cls)
<< copy_constructor(cls)
<< destructor(cls)
<< functions(cls.functions)
<< events(cls)
<< eo_class_getter(cls)
<< "private:" << endl
- << eo_class_constructors(cls)
+ << function_call_constructor_methods(cls)
<< "};" << endl
<< "static_assert(sizeof(" << cls.name << ") == sizeof(Eo*), \"sizeof(" << cls.name << ") != sizeof(Eo*)\");" << endl
<< "static_assert(std::is_standard_layout<" << cls.name << ">::value, \"'" << cls.name << "' is not standard layout\");"
namespace efl { namespace eolian { namespace grammar {
struct
+parameter_type
+{
+ eolian_type_instance const& _type;
+ parameter_type(eolian_type_instance const& t)
+ : _type(t)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameter_type const& x)
+{
+ if(type_is_callback(x._type))
+ out << "F";
+ else
+ out << reinterpret_type(x._type);
+ return out;
+}
+
+struct
+parameter_forward
+{
+ eolian_type_instance const& _type;
+ std::string const& _name;
+ parameter_forward(eolian_type_instance const& type, std::string const& name)
+ : _type(type)
+ , _name(name)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameter_forward const& x)
+{
+ if (type_is_callback(x._type))
+ {
+ out << "std::forward<F>(" << x._name << ")";
+ }
+ else
+ out << x._name;
+ return out;
+}
+
+struct param_data
+{
+ std::ostream& out;
+ unsigned pos;
+ eolian_type_instance const& type;
+ std::string const& name;
+ int cb_idx;
+ bool is_cb;
+ param_data(std::ostream& out_, unsigned pos_, eolian_type_instance const& type_, std::string const& name_, int cb_idx_)
+ : out(out_)
+ , pos(pos_)
+ , type(type_)
+ , name(name_)
+ , cb_idx(cb_idx_)
+ , is_cb(cb_idx_ >= 0)
+ {}
+};
+
+template <typename T>
+struct
+_parameters_cxx_generic
+{
+ parameters_container_type const& _params;
+ T _fparam;
+ _parameters_cxx_generic(parameters_container_type const& params, T fparam)
+ : _params(params)
+ , _fparam(fparam)
+ {}
+};
+
+template <typename T>
+std::ostream&
+operator<<(std::ostream& out, _parameters_cxx_generic<T> const& x)
+{
+ int cb_idx = 0u;
+ auto first = x._params.cbegin(),
+ last = x._params.cend();
+ for (auto it = first; it != last; ++it)
+ {
+ if (type_is_callback((*it).type) && it+1 != last)
+ {
+ x._fparam(param_data(out, it - first, (*it).type, (*it).name, cb_idx++));
+ ++it; // skip next.
+ }
+ else
+ x._fparam(param_data(out, it - first, (*it).type, (*it).name, -1));
+ }
+ return out;
+}
+
+template <typename T>
+_parameters_cxx_generic<T>
+parameters_cxx_generic(parameters_container_type const& params, T fparam)
+{
+ return _parameters_cxx_generic<T>(params, fparam);
+}
+
+struct
parameters_declaration
{
parameters_container_type const& _params;
{
if (it != first)
out << ", ";
+ // TODO What to do when callback happens in the middle of parameters
+ // and does not have a following userdata pointer ?
if (type_is_callback((*it).type) && it+1 != last)
{
out << "F && " << (*it).name;
return out;
}
+struct
+parameters_forward
+{
+ parameters_container_type const& _params;
+ parameters_forward(parameters_container_type const& params)
+ : _params(params)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameters_forward const& x)
+{
+ auto first = x._params.cbegin(), last = x._params.cend();
+ for (auto it = first; it != last; ++it)
+ {
+ if (it != first)
+ out << ", ";
+ out << parameter_forward((*it).type, (*it).name);
+ if (type_is_callback((*it).type) && it+1 != last)
+ {
+ ++it; // skip next.
+ }
+ }
+ return out;
+}
+
+struct
+parameters_forward_to_c
+{
+ parameters_container_type const& _params;
+ parameters_forward_to_c(parameters_container_type const& params)
+ : _params(params)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameters_forward_to_c const& x)
+{
+ auto first = x._params.cbegin(), last = x._params.cend();
+ for (auto it = first; it != last; ++it)
+ {
+ if (it != first)
+ out << ", ";
+ if (type_is_callback((*it).type) && it + 1 != last)
+ {
+ out << to_c((*it).type, (*it).name) << ", _tmp_f";
+ ++it; // skip next
+ }
+ else
+ out << to_c((*it).type, (*it).name);
+ }
+ return out;
+}
} } } // namespace efl { namespace eolian { namespace grammar {
return EINA_TRUE;
}
-static void _callback_default_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED)
+static void _callback_eo_base_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED)
{
pd->callbacks = 0;
eo_do_super(obj, MY_CLASS, eo_constructor());
, &_callback_callback_added, pd);
}
-static void _callback_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
-{
- pd->callbacks = 0;
- eo_do_super(obj, MY_CLASS, eo_constructor());
-
- eo_event_callback_priority_add(EO_BASE_EVENT_CALLBACK_ADD, EO_CALLBACK_PRIORITY_DEFAULT
- , &_callback_callback_added, pd);
- cb(data);
-}
-
-static void _callback_constructor2(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data
- , Ecore_Cb cb2 EINA_UNUSED)
-{
- pd->callbacks = 0;
- eo_do_super(obj, MY_CLASS, eo_constructor());
-
- eo_event_callback_priority_add(EO_BASE_EVENT_CALLBACK_ADD, EO_CALLBACK_PRIORITY_DEFAULT
- , &_callback_callback_added, pd);
- cb(data);
-}
-
static void _callback_onecallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
{
cb(data);
legacy_prefix: null;
data: Callback_Data;
methods {
- default_constructor {
- }
- constructor {
- params {
- @in Ecore_Cb cb;
- @in void* data;
- }
- }
- constructor2 {
- params {
- @in Ecore_Cb cb;
- @in void* data;
- @in Ecore_Cb cb2;
- }
- }
onecallback {
params {
@in Ecore_Cb cb;
}
}
}
- constructors {
- .default_constructor;
- .constructor;
- .constructor2;
- }
+ implements {
+ Eo.Base.constructor;
+ }
events {
call_on_add;
}
-}
\ No newline at end of file
+}
void foo(void*) {}
-START_TEST(eolian_cxx_test_callback_constructor)
-{
- efl::eo::eo_init i;
-
- bool called1 = false, called2 = false;
- ::callback c1 (std::bind([&called1] { called1 = true; }));
- ::callback c2 (std::bind([&called2] { called2 = true; }), &foo);
- fail_if(!called1);
- fail_if(!called2);
-}
-END_TEST
-
START_TEST(eolian_cxx_test_callback_method)
{
efl::eo::eo_init i;
void
eolian_cxx_test_callback(TCase* tc)
{
- tcase_add_test(tc, eolian_cxx_test_callback_constructor);
tcase_add_test(tc, eolian_cxx_test_callback_method);
tcase_add_test(tc, eolian_cxx_test_callback_event_add);
tcase_add_test(tc, eolian_cxx_test_callback_event_del);