eolian_cxx: Fix Eolian C++ generated wrapper inconsistencies
authorVitor Sousa <vitorsousasilva@gmail.com>
Tue, 11 Nov 2014 22:37:47 +0000 (20:37 -0200)
committerVitor Sousa <vitorsousasilva@gmail.com>
Mon, 5 Jan 2015 17:52:27 +0000 (15:52 -0200)
In convert.cc: Reading functions instead of implements to convert the
Eolian_Class. It avoids creation of methods that do not belong to the
class, in special it avoids calling the default constructor twice in the
generated code.

No longer generating one constructor in the C++ wrapper for each eolian
class constructor, since the correct behavior demands that all constructor
should be called. Now the wrappers have "constructor methods" that
must be called when creating a new object.

Updated test cases and examples to match the new interface. Some class
constructors and some test cases have to be removed since they were based
on the wrong assumption that constructors are mutually exclusive.

Created new generators for forwarding parameters and for looping over
the relevant parameters to the C++ wrapper executing a generic lambda.

Added a TODO comment regarding the call of constructor methods of all
base classes. Currently there is no base type with constructors, so this
situation should be discussed more.

Added a TODO comment regarding the way callback parameters are being
processed.

15 files changed:
src/bin/eolian_cxx/convert.cc
src/examples/eolian_cxx/colourable.c
src/examples/eolian_cxx/colourable.eo
src/examples/eolian_cxx/colourable_cxx.cc
src/examples/eolian_cxx/colourable_stub.h
src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
src/examples/eolian_cxx/eolian_cxx_simple_01.cc
src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc
src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
src/lib/eolian_cxx/grammar/eo_class_generator.hh
src/lib/eolian_cxx/grammar/parameters_generator.hh
src/tests/eolian_cxx/callback.c
src/tests/eolian_cxx/callback.eo
src/tests/eolian_cxx/eolian_cxx_test_callback.cc

index 4e68b87..acb2c78 100644 (file)
@@ -205,45 +205,23 @@ convert_eolian_class_new(Eolian_Class const& klass)
 }
 
 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),
@@ -251,10 +229,38 @@ convert_eolian_implements(efl::eolian::eo_class& cls, Eolian_Class const& klass)
                  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");
+          }
      }
 }
 
@@ -263,7 +269,7 @@ convert_eolian_class(const Eolian_Class& klass)
 {
    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;
index a677f64..1c7ff5e 100644 (file)
@@ -51,24 +51,6 @@ _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self EINA_UNUSED)
 }
 
 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)
index e0b011b..3693818 100644 (file)
@@ -4,15 +4,6 @@ class Colourable (Eo.Base)
     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;
@@ -60,7 +51,6 @@ class Colourable (Eo.Base)
         Eo.Base.destructor;
     }
     constructors {
-        .rgb_composite_constructor;
         .rgb_24bits_constructor;
     }
     events {
index 4d9ef78..bd4fa46 100644 (file)
@@ -35,18 +35,6 @@ _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self EINA_UNUSED)
 }
 
 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
index ae3ac94..f6d758c 100644 (file)
@@ -15,7 +15,6 @@ typedef struct _Colourable_Data  Colourable_Data;
 
 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);
index 2c64784..8c41c0e 100644 (file)
@@ -27,20 +27,21 @@ void
 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();
 }
 
index b3fe196..b258f05 100644 (file)
@@ -16,10 +16,6 @@ using namespace efl;
 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))
    {}
@@ -52,7 +48,8 @@ main()
    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;
index c64a93c..47b98cb 100644 (file)
@@ -18,11 +18,15 @@ main()
    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());
index 0a35f93..1120978 100644 (file)
@@ -18,11 +18,15 @@ main()
    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());
index fff99be..f02ca7b 100644 (file)
@@ -77,6 +77,189 @@ operator<<(std::ostream& out, class_inheritance const& x)
    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;
@@ -222,6 +405,45 @@ operator<<(std::ostream& out, eo_class_constructors const& x)
    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
index 656a791..2b82d84 100644 (file)
@@ -37,15 +37,17 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
        << "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\");"
index f25c6d0..5492859 100644 (file)
 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;
@@ -28,6 +127,8 @@ operator<<(std::ostream& out, parameters_declaration const& x)
      {
         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;
@@ -193,6 +294,59 @@ operator<<(std::ostream& out, constructor_parameters_list const& x)
    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 {
 
index 1371128..5192fa0 100644 (file)
@@ -28,7 +28,7 @@ static Eina_Bool _callback_callback_added(void* data EINA_UNUSED, Eo* obj EINA_U
   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());
@@ -37,27 +37,6 @@ static void _callback_default_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd
                                  , &_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);
index a22885e..16dd76e 100644 (file)
@@ -3,21 +3,6 @@ class Callback (Eo.Base)
    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;
@@ -32,12 +17,10 @@ class Callback (Eo.Base)
          }
       }
    }
-    constructors {
-        .default_constructor;
-        .constructor;
-        .constructor2;
-    }
+   implements {
+      Eo.Base.constructor;
+   }
    events {
      call_on_add;
    }
-}
\ No newline at end of file
+}
index 81b6ac5..5c5d95f 100644 (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;
@@ -124,7 +112,6 @@ END_TEST
 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);