summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2014-11-11 20:37:47 -0200
committerVitor Sousa <vitorsousasilva@gmail.com>2015-01-05 15:52:27 -0200
commit132abc353454a2653b5b2b40d6de5f1689323a37 (patch)
tree2184e0c8361e0da179cf72c1071d2e6be4af9af7
parented8ce801cb56644c12b395797c3f9e22a508811f (diff)
eolian_cxx: Fix Eolian C++ generated wrapper inconsistencies
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.
-rw-r--r--src/bin/eolian_cxx/convert.cc72
-rw-r--r--src/examples/eolian_cxx/colourable.c18
-rw-r--r--src/examples/eolian_cxx/colourable.eo10
-rw-r--r--src/examples/eolian_cxx/colourable_cxx.cc12
-rw-r--r--src/examples/eolian_cxx/colourable_stub.h1
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc27
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_inherit_01.cc7
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_simple_01.cc8
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc8
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh222
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_generator.hh6
-rw-r--r--src/lib/eolian_cxx/grammar/parameters_generator.hh154
-rw-r--r--src/tests/eolian_cxx/callback.c23
-rw-r--r--src/tests/eolian_cxx/callback.eo25
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_callback.cc13
15 files changed, 452 insertions, 154 deletions
diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc
index 4e68b87..acb2c78 100644
--- a/src/bin/eolian_cxx/convert.cc
+++ b/src/bin/eolian_cxx/convert.cc
@@ -205,45 +205,23 @@ convert_eolian_class_new(Eolian_Class const& klass)
205} 205}
206 206
207void 207void
208convert_eolian_implements(efl::eolian::eo_class& cls, Eolian_Class const& klass) 208convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
209{ 209{
210 efl::eina::iterator<const Eolian_Implement> itr = implements_get(klass); 210 for(efl::eina::iterator<const Eolian_Function> first ( ::eolian_class_functions_get(&klass, EOLIAN_METHOD))
211 efl::eina::iterator<const Eolian_Implement> end; 211 , last; first != last; ++first)
212
213 while (itr != end)
214 { 212 {
215 const Eolian_Implement impl = *itr; 213 Eolian_Function const& func = *first;
216 assert(!!implement_function(impl)); 214 Eolian_Function_Type const func_type = function_op_type(func);
217 assert(!!implement_class(impl));
218 Eolian_Function const& func = *implement_function(impl);
219 Eolian_Class const& icls = *implement_class(impl);
220 215
221 if (implement_is_property_get(impl)) 216 if (function_is_constructor(klass, func))
222 {
223 cls.functions.push_back
224 (_convert_property_get_to_function(icls, func));
225 }
226 else if (implement_is_property_set(impl))
227 {
228 cls.functions.push_back
229 (_convert_property_set_to_function(icls, func));
230 }
231 else if (function_op_type(func) == eolian_cxx::property.value)
232 {
233 cls.functions.push_back
234 (_convert_property_get_to_function(icls, func));
235 cls.functions.push_back
236 (_convert_property_set_to_function(icls, func));
237 }
238 else if (function_is_constructor(klass, func))
239 { 217 {
240 cls.constructors.push_back({ 218 cls.constructors.push_back({
241 function_impl(func), 219 function_impl(func),
242 _convert_eolian_parameters(func), 220 _convert_eolian_parameters(func),
243 convert_comments_function(icls, func) 221 convert_comments_function(klass, func)
244 }); 222 });
245 } 223 }
246 else if (implement_is_visible(impl)) 224 else if (function_is_visible(func, func_type))
247 { 225 {
248 cls.functions.push_back({ 226 cls.functions.push_back({
249 function_type(func), 227 function_type(func),
@@ -251,10 +229,38 @@ convert_eolian_implements(efl::eolian::eo_class& cls, Eolian_Class const& klass)
251 function_impl(func), 229 function_impl(func),
252 function_return_type(func), 230 function_return_type(func),
253 _convert_eolian_parameters(func), 231 _convert_eolian_parameters(func),
254 convert_comments_function(icls, func, eolian_cxx::method) 232 convert_comments_function(klass, func, eolian_cxx::method)
255 }); 233 });
256 } 234 }
257 ++itr; 235 }
236 for(efl::eina::iterator<const Eolian_Function> first ( ::eolian_class_functions_get(&klass, EOLIAN_PROPERTY))
237 , last; first != last; ++first)
238 {
239 Eolian_Function const& func = *first;
240 Eolian_Function_Type t = ::eolian_function_type_get(&func);
241
242 if(t == EOLIAN_PROP_GET)
243 {
244 cls.functions.push_back
245 (_convert_property_get_to_function(klass, func));
246 }
247 else if(t == EOLIAN_PROP_SET)
248 {
249 cls.functions.push_back
250 (_convert_property_set_to_function(klass, func));
251 }
252 else if(t == EOLIAN_PROPERTY)
253 {
254 cls.functions.push_back
255 (_convert_property_get_to_function(klass, func));
256 cls.functions.push_back
257 (_convert_property_set_to_function(klass, func));
258 }
259 else
260 {
261 std::cerr << "Error: Inconsistent type for Eolian function \'" << ::eolian_function_name_get(&func) << "\'." << std::endl;
262 throw std::runtime_error("Invalid Eolian function type");
263 }
258 } 264 }
259} 265}
260 266
@@ -263,7 +269,7 @@ convert_eolian_class(const Eolian_Class& klass)
263{ 269{
264 efl::eolian::eo_class cls(eolian_cxx::convert_eolian_class_new(klass)); 270 efl::eolian::eo_class cls(eolian_cxx::convert_eolian_class_new(klass));
265 eolian_cxx::convert_eolian_inheritances(cls, klass); 271 eolian_cxx::convert_eolian_inheritances(cls, klass);
266 eolian_cxx::convert_eolian_implements(cls, klass); 272 eolian_cxx::convert_eolian_functions(cls, klass);
267 eolian_cxx::convert_eolian_events(cls, klass); 273 eolian_cxx::convert_eolian_events(cls, klass);
268 efl::eolian::eo_class_validate(cls); 274 efl::eolian::eo_class_validate(cls);
269 return cls; 275 return cls;
diff --git a/src/examples/eolian_cxx/colourable.c b/src/examples/eolian_cxx/colourable.c
index a677f64..1c7ff5e 100644
--- a/src/examples/eolian_cxx/colourable.c
+++ b/src/examples/eolian_cxx/colourable.c
@@ -51,24 +51,6 @@ _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self EINA_UNUSED)
51} 51}
52 52
53void 53void
54_colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b)
55{
56 if(!_colourable_impl_logdomain)
57 {
58 _colourable_impl_logdomain
59 = eina_log_domain_register("colourable", EINA_COLOR_BLUE);
60 }
61 self->r = r;
62 self->g = g;
63 self->b = b;
64 DBG("_colourable_rgb_composite_constructor(0x%2.x, %0x2.x, %0x2.x)\n",
65 (unsigned int)self->r,
66 (unsigned int)self->g,
67 (unsigned int)self->b);
68 eo_do_super(obj, MY_CLASS, eo_constructor());
69}
70
71void
72_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb) 54_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
73{ 55{
74 if(!_colourable_impl_logdomain) 56 if(!_colourable_impl_logdomain)
diff --git a/src/examples/eolian_cxx/colourable.eo b/src/examples/eolian_cxx/colourable.eo
index e0b011b..3693818 100644
--- a/src/examples/eolian_cxx/colourable.eo
+++ b/src/examples/eolian_cxx/colourable.eo
@@ -4,15 +4,6 @@ class Colourable (Eo.Base)
4 legacy_prefix: legacy; 4 legacy_prefix: legacy;
5 data: Colourable_Data; 5 data: Colourable_Data;
6 methods { 6 methods {
7 rgb_composite_constructor {
8 /*@ Composite RGB Constructor. */
9 legacy: null;
10 params {
11 @in int r; /*@ The red component. */
12 @in int g; /*@ The green component. */
13 @in int b; /*@ The blue component. */
14 }
15 }
16 rgb_24bits_constructor { 7 rgb_24bits_constructor {
17 /*@ RGB Constructor. */ 8 /*@ RGB Constructor. */
18 legacy: null; 9 legacy: null;
@@ -60,7 +51,6 @@ class Colourable (Eo.Base)
60 Eo.Base.destructor; 51 Eo.Base.destructor;
61 } 52 }
62 constructors { 53 constructors {
63 .rgb_composite_constructor;
64 .rgb_24bits_constructor; 54 .rgb_24bits_constructor;
65 } 55 }
66 events { 56 events {
diff --git a/src/examples/eolian_cxx/colourable_cxx.cc b/src/examples/eolian_cxx/colourable_cxx.cc
index 4d9ef78..bd4fa46 100644
--- a/src/examples/eolian_cxx/colourable_cxx.cc
+++ b/src/examples/eolian_cxx/colourable_cxx.cc
@@ -35,18 +35,6 @@ _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self EINA_UNUSED)
35} 35}
36 36
37void 37void
38_colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b)
39{
40 EINA_CXX_DOM_LOG_DBG(domain) << std::showbase << std::hex
41 << __func__ << " [ (r, g, b) = ("
42 << r << ", " << g << ", " << b << ") ]" << std::endl;
43 self->r = r;
44 self->g = g;
45 self->b = b;
46 eo_do_super(obj, MY_CLASS, eo_constructor());
47}
48
49void
50_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb) 38_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
51{ 39{
52 EINA_CXX_DOM_LOG_DBG(domain) << std::showbase << std::hex 40 EINA_CXX_DOM_LOG_DBG(domain) << std::showbase << std::hex
diff --git a/src/examples/eolian_cxx/colourable_stub.h b/src/examples/eolian_cxx/colourable_stub.h
index ae3ac94..f6d758c 100644
--- a/src/examples/eolian_cxx/colourable_stub.h
+++ b/src/examples/eolian_cxx/colourable_stub.h
@@ -15,7 +15,6 @@ typedef struct _Colourable_Data Colourable_Data;
15 15
16void _colourable_eo_base_constructor(Eo *obj, Colourable_Data *self); 16void _colourable_eo_base_constructor(Eo *obj, Colourable_Data *self);
17void _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self); 17void _colourable_eo_base_destructor(Eo *obj, Colourable_Data *self);
18void _colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b);
19void _colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb); 18void _colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb);
20void _colourable_print_colour(Eo *obj, Colourable_Data *self); 19void _colourable_print_colour(Eo *obj, Colourable_Data *self);
21void _colourable_print_colour(Eo *obj, Colourable_Data *self); 20void _colourable_print_colour(Eo *obj, Colourable_Data *self);
diff --git a/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc b/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
index 2c64784..8c41c0e 100644
--- a/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
@@ -27,20 +27,21 @@ void
27example_callbacks() 27example_callbacks()
28{ 28{
29 int count = 0; 29 int count = 0;
30 efl::ecore::poller poller 30 efl::ecore::poller poller(
31 (ECORE_POLLER_CORE, 1, 31 poller.ecore_poller_constructor(ECORE_POLLER_CORE, 1,
32 [&count, &poller] 32 [&count, &poller]
33 { 33 {
34 if (++count == 5) 34 if (++count == 5)
35 { 35 {
36 std::cout << std::endl; 36 std::cout << std::endl;
37 ecore_main_loop_quit(); 37 ecore_main_loop_quit();
38 return false; 38 return false;
39 } 39 }
40 poller.interval_set(2*poller.interval_get()); 40 poller.interval_set(2*poller.interval_get());
41 std::cout << "."<< std::flush; 41 std::cout << "." << std::flush;
42 return true; 42 return true;
43 }); 43 })
44 );
44 ::ecore_main_loop_begin(); 45 ::ecore_main_loop_begin();
45} 46}
46 47
diff --git a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
index b3fe196..b258f05 100644
--- a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
@@ -16,10 +16,6 @@ using namespace efl;
16struct ColourableCircle 16struct ColourableCircle
17 : efl::eo::inherit<ColourableCircle, ::colourable> 17 : efl::eo::inherit<ColourableCircle, ::colourable>
18{ 18{
19 ColourableCircle(int r, int g, int b)
20 : inherit_base(r, g, b)
21 {}
22
23 ColourableCircle(int rgb) 19 ColourableCircle(int rgb)
24 : inherit_base(efl::eo::args<::colourable>(rgb)) 20 : inherit_base(efl::eo::args<::colourable>(rgb))
25 {} 21 {}
@@ -52,7 +48,8 @@ main()
52 efl::eo::eo_init init; 48 efl::eo::eo_init init;
53 eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG); 49 eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG);
54 50
55 ColourableCircle obj1(0xc0, 0xff, 0xee); 51 ColourableCircle obj1(0x0);
52 obj1.composite_colour_set(0xc0, 0xff, 0xee);
56 53
57 ColourableCircle obj2(0xc0ffee); 54 ColourableCircle obj2(0xc0ffee);
58 int r, g, b; 55 int r, g, b;
diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
index c64a93c..47b98cb 100644
--- a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
@@ -18,11 +18,15 @@ main()
18 eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG); 18 eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
19 19
20 int r, g, b; 20 int r, g, b;
21 ::colourable obj1(0x123456); 21 ::colourable obj1(
22 obj1.colourable_rgb_24bits_constructor(0x123456)
23 );
22 obj1.colour_set(0xc0ffee); 24 obj1.colour_set(0xc0ffee);
23 obj1.composite_colour_get(&r, &g, &b); 25 obj1.composite_colour_get(&r, &g, &b);
24 26
25 ::colourablesquare obj2(10); 27 ::colourablesquare obj2(
28 obj2.colourablesquare_size_constructor(10)
29 );
26 obj2.composite_colour_set(r, g, b); 30 obj2.composite_colour_set(r, g, b);
27 obj2.size_set(11); 31 obj2.size_set(11);
28 assert(obj1.colour_get() == obj2.colour_get()); 32 assert(obj1.colour_get() == obj2.colour_get());
diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc
index 0a35f93..1120978 100644
--- a/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc
@@ -18,11 +18,15 @@ main()
18 eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG); 18 eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
19 19
20 int r, g, b; 20 int r, g, b;
21 ::colourable obj1(0x123456); 21 ::colourable obj1(
22 obj1.colourable_rgb_24bits_constructor(0x123456)
23 );
22 obj1.colour_set(0xc0ffee); 24 obj1.colour_set(0xc0ffee);
23 obj1.composite_colour_get(&r, &g, &b); 25 obj1.composite_colour_get(&r, &g, &b);
24 26
25 ::colourablesquare obj2(0x123456); 27 ::colourablesquare obj2(
28 obj2.colourablesquare_size_constructor(0x123456)
29 );
26 obj2.composite_colour_set(r, g, b); 30 obj2.composite_colour_set(r, g, b);
27 obj2.size_set(11); 31 obj2.size_set(11);
28 assert(obj1.colour_get() == obj2.colour_get()); 32 assert(obj1.colour_get() == obj2.colour_get());
diff --git a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
index fff99be..f02ca7b 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
@@ -77,6 +77,189 @@ operator<<(std::ostream& out, class_inheritance const& x)
77 return out; 77 return out;
78} 78}
79 79
80struct constructor_functor_type_name
81{
82 eo_constructor const& _ctor;
83 constructor_functor_type_name(eo_constructor const& ctor)
84 : _ctor(ctor)
85 {}
86};
87
88inline std::ostream&
89operator<<(std::ostream& out, constructor_functor_type_name const& x)
90{
91 out << "_c_" << x._ctor.name;
92 return out;
93}
94
95struct constructor_functor_type_decl
96{
97 eo_constructor const& _ctor;
98 constructor_functor_type_decl(eo_constructor const& ctor)
99 : _ctor(ctor)
100 {}
101};
102
103inline std::ostream&
104operator<<(std::ostream& out, constructor_functor_type_decl const& x)
105{
106 out << constructor_functor_type_name(x._ctor);
107 auto cb_it = parameters_find_callback(x._ctor.params);
108 if(cb_it != x._ctor.params.cend())
109 {
110 out << "<F>";
111 }
112 return out;
113}
114
115struct functors_constructor_methods
116{
117 eo_class const& _cls;
118 functors_constructor_methods(eo_class const& cls) : _cls(cls) {}
119};
120
121inline std::ostream&
122operator<<(std::ostream& out, functors_constructor_methods const& x)
123{
124 constructors_container_type::const_iterator it,
125 first = x._cls.constructors.cbegin(),
126 last = x._cls.constructors.cend();
127 for (it = first; it != last; ++it)
128 {
129 eo_constructor const& c = *it;
130 auto cb_it = parameters_find_callback(c.params);
131 bool has_callback = (cb_it != c.params.cend());
132
133 // Struct declaration
134 if(has_callback)
135 {
136 out << tab(1) << "template <typename F>" << endl;
137 }
138 out << tab(1) << "struct " << constructor_functor_type_name(c) << endl
139 << tab(1) << "{" << endl;
140
141 // Struct constructor
142 out << tab(2) << constructor_functor_type_name(c) << "("
143 << parameters_declaration(c.params) << ")"
144 << parameters_cxx_generic(c.params,
145 [](param_data d)
146 {
147 if(d.pos == 0u)
148 d.out << endl << tab(3) << ": ";
149 else
150 d.out << ", ";
151 d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")";
152 }
153 )
154 << endl
155 << tab(2) << "{}" << endl;
156
157 // Struct operator()
158 out << tab(2) << "void operator()()" << endl
159 << tab(2) << "{" << endl;
160 if (has_callback)
161 {
162 out << tab(3) << "typedef typename std::remove_reference<F>::type function_type;" << endl
163 << tab(3) << "function_type* _tmp_f = new F(this->" << (*cb_it).name << ");" << endl;
164 }
165 out << tab(3) << "::" << c.name << "(" << parameters_forward_to_c(c.params) << ");" << endl
166 << tab(2) << "}" << endl;
167
168 // Struct member variables
169 out << tab(1) << "private:" << endl
170 << parameters_cxx_generic(c.params,
171 [](param_data d)
172 {
173 d.out << tab(2) << parameter_type(d.type) << " " << d.name << ";" << endl;
174 }
175 );
176
177 // Close struct
178 out << tab(1) << "};" << endl << endl;
179 }
180
181 return out;
182}
183
184struct functions_constructor_methods
185{
186 eo_class const& _cls;
187 functions_constructor_methods(eo_class const& cls) : _cls(cls) {}
188};
189
190inline std::ostream&
191operator<<(std::ostream& out, functions_constructor_methods const& x)
192{
193 constructors_container_type::const_iterator it,
194 first = x._cls.constructors.cbegin(),
195 last = x._cls.constructors.cend();
196 for (it = first; it != last; ++it)
197 {
198 eo_constructor const& c = *it;
199
200 out << comment(c.comment, 1);
201
202 unsigned cb_count = parameters_count_callbacks(c.params);
203 if(cb_count)
204 out << tab(1) << "template <typename F>" << endl;
205 out << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
206 << parameters_declaration(c.params) << ")" << endl
207 << tab(1) << "{" << endl
208 << tab(2) << "return " << constructor_functor_type_decl(c) << "("
209 << parameters_forward(c.params) << ");" << endl
210 << tab(1) << "}" << endl << endl;
211 }
212
213 return out;
214}
215
216struct constructor_with_constructor_methods
217{
218 eo_class const& _cls;
219 constructor_with_constructor_methods(eo_class const& cls)
220 : _cls(cls)
221 {}
222};
223
224inline std::ostream&
225operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
226{
227 //
228 // TODO Require constructor methods of all base classes ?
229 //
230
231 constructors_container_type::const_iterator it,
232 first = x._cls.constructors.cbegin(),
233 last = x._cls.constructors.cend();
234
235 for (it = first; it != last; ++it)
236 {
237 unsigned cb_count = parameters_count_callbacks((*it).params);
238 if(cb_count)
239 {
240 out << tab(1) << "template <typename F>" << endl;
241 break;
242 }
243 }
244
245 out << tab(1) << x._cls.name << "(";
246 for (it = first; it != last; ++it)
247 {
248 out << constructor_functor_type_decl(*it)
249 << " _c" << (it-first) << ", ";
250 }
251 out << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
252 << tab(2) << ": " << x._cls.name << "(_ctors_call(";
253 for (it = first; it != last; ++it)
254 {
255 out << "_c" << (it-first) << ", ";
256 }
257 out << "_p))" << endl
258 << tab(1) << "{}" << endl << endl;
259
260 return out;
261}
262
80struct constructor_eo 263struct constructor_eo
81{ 264{
82 eo_class const& _cls; 265 eo_class const& _cls;
@@ -222,6 +405,45 @@ operator<<(std::ostream& out, eo_class_constructors const& x)
222 return out; 405 return out;
223} 406}
224 407
408struct function_call_constructor_methods
409{
410 eo_class const& _cls;
411 function_call_constructor_methods(eo_class const& cls) : _cls(cls) {}
412};
413
414inline std::ostream&
415operator<<(std::ostream& out, function_call_constructor_methods const& x)
416{
417 constructors_container_type::const_iterator it,
418 first = x._cls.constructors.cbegin(),
419 last = x._cls.constructors.cend();
420 for (it = first; it != last; ++it)
421 {
422 unsigned cb_count = parameters_count_callbacks((*it).params);
423 if (cb_count)
424 {
425 out << tab(1) << "template <typename F>" << endl;
426 break;
427 }
428 }
429 out << tab(1) << "static Eo* _ctors_call(";
430 for (it = first; it != last; ++it)
431 {
432 out << constructor_functor_type_decl(*it) << " _c" << (it-first) << ", ";
433 }
434 out << "efl::eo::parent_type _p)" << endl
435 << tab(1) << "{" << endl
436 << tab(2) << "return eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, ";
437 for (it = first; it != last; ++it)
438 {
439 out << "_c" << (it-first) << "(); ";
440 }
441 out << ");" << endl
442 << tab(1) << "}" << endl << endl;
443
444 return out;
445}
446
225} } } // namespace efl { namespace eolian { namespace grammar { 447} } } // namespace efl { namespace eolian { namespace grammar {
226 448
227#endif // EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH 449#endif // EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
diff --git a/src/lib/eolian_cxx/grammar/eo_class_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
index 656a791..2b82d84 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
@@ -37,15 +37,17 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
37 << "struct " << cls.name << endl 37 << "struct " << cls.name << endl
38 << tab(2) << ": " << class_inheritance(cls) 38 << tab(2) << ": " << class_inheritance(cls)
39 << '{' << endl 39 << '{' << endl
40 << functors_constructor_methods(cls)
41 << functions_constructor_methods(cls)
42 << constructor_with_constructor_methods(cls)
40 << constructor_eo(cls) 43 << constructor_eo(cls)
41 << constructors(cls)
42 << copy_constructor(cls) 44 << copy_constructor(cls)
43 << destructor(cls) 45 << destructor(cls)
44 << functions(cls.functions) 46 << functions(cls.functions)
45 << events(cls) 47 << events(cls)
46 << eo_class_getter(cls) 48 << eo_class_getter(cls)
47 << "private:" << endl 49 << "private:" << endl
48 << eo_class_constructors(cls) 50 << function_call_constructor_methods(cls)
49 << "};" << endl 51 << "};" << endl
50 << "static_assert(sizeof(" << cls.name << ") == sizeof(Eo*), \"sizeof(" << cls.name << ") != sizeof(Eo*)\");" << endl 52 << "static_assert(sizeof(" << cls.name << ") == sizeof(Eo*), \"sizeof(" << cls.name << ") != sizeof(Eo*)\");" << endl
51 << "static_assert(std::is_standard_layout<" << cls.name << ">::value, \"'" << cls.name << "' is not standard layout\");" 53 << "static_assert(std::is_standard_layout<" << cls.name << ">::value, \"'" << cls.name << "' is not standard layout\");"
diff --git a/src/lib/eolian_cxx/grammar/parameters_generator.hh b/src/lib/eolian_cxx/grammar/parameters_generator.hh
index f25c6d0..5492859 100644
--- a/src/lib/eolian_cxx/grammar/parameters_generator.hh
+++ b/src/lib/eolian_cxx/grammar/parameters_generator.hh
@@ -11,6 +11,105 @@
11namespace efl { namespace eolian { namespace grammar { 11namespace efl { namespace eolian { namespace grammar {
12 12
13struct 13struct
14parameter_type
15{
16 eolian_type_instance const& _type;
17 parameter_type(eolian_type_instance const& t)
18 : _type(t)
19 {}
20};
21
22inline std::ostream&
23operator<<(std::ostream& out, parameter_type const& x)
24{
25 if(type_is_callback(x._type))
26 out << "F";
27 else
28 out << reinterpret_type(x._type);
29 return out;
30}
31
32struct
33parameter_forward
34{
35 eolian_type_instance const& _type;
36 std::string const& _name;
37 parameter_forward(eolian_type_instance const& type, std::string const& name)
38 : _type(type)
39 , _name(name)
40 {}
41};
42
43inline std::ostream&
44operator<<(std::ostream& out, parameter_forward const& x)
45{
46 if (type_is_callback(x._type))
47 {
48 out << "std::forward<F>(" << x._name << ")";
49 }
50 else
51 out << x._name;
52 return out;
53}
54
55struct param_data
56{
57 std::ostream& out;
58 unsigned pos;
59 eolian_type_instance const& type;
60 std::string const& name;
61 int cb_idx;
62 bool is_cb;
63 param_data(std::ostream& out_, unsigned pos_, eolian_type_instance const& type_, std::string const& name_, int cb_idx_)
64 : out(out_)
65 , pos(pos_)
66 , type(type_)
67 , name(name_)
68 , cb_idx(cb_idx_)
69 , is_cb(cb_idx_ >= 0)
70 {}
71};
72
73template <typename T>
74struct
75_parameters_cxx_generic
76{
77 parameters_container_type const& _params;
78 T _fparam;
79 _parameters_cxx_generic(parameters_container_type const& params, T fparam)
80 : _params(params)
81 , _fparam(fparam)
82 {}
83};
84
85template <typename T>
86std::ostream&
87operator<<(std::ostream& out, _parameters_cxx_generic<T> const& x)
88{
89 int cb_idx = 0u;
90 auto first = x._params.cbegin(),
91 last = x._params.cend();
92 for (auto it = first; it != last; ++it)
93 {
94 if (type_is_callback((*it).type) && it+1 != last)
95 {
96 x._fparam(param_data(out, it - first, (*it).type, (*it).name, cb_idx++));
97 ++it; // skip next.
98 }
99 else
100 x._fparam(param_data(out, it - first, (*it).type, (*it).name, -1));
101 }
102 return out;
103}
104
105template <typename T>
106_parameters_cxx_generic<T>
107parameters_cxx_generic(parameters_container_type const& params, T fparam)
108{
109 return _parameters_cxx_generic<T>(params, fparam);
110}
111
112struct
14parameters_declaration 113parameters_declaration
15{ 114{
16 parameters_container_type const& _params; 115 parameters_container_type const& _params;
@@ -28,6 +127,8 @@ operator<<(std::ostream& out, parameters_declaration const& x)
28 { 127 {
29 if (it != first) 128 if (it != first)
30 out << ", "; 129 out << ", ";
130 // TODO What to do when callback happens in the middle of parameters
131 // and does not have a following userdata pointer ?
31 if (type_is_callback((*it).type) && it+1 != last) 132 if (type_is_callback((*it).type) && it+1 != last)
32 { 133 {
33 out << "F && " << (*it).name; 134 out << "F && " << (*it).name;
@@ -193,6 +294,59 @@ operator<<(std::ostream& out, constructor_parameters_list const& x)
193 return out; 294 return out;
194} 295}
195 296
297struct
298parameters_forward
299{
300 parameters_container_type const& _params;
301 parameters_forward(parameters_container_type const& params)
302 : _params(params)
303 {}
304};
305
306inline std::ostream&
307operator<<(std::ostream& out, parameters_forward const& x)
308{
309 auto first = x._params.cbegin(), last = x._params.cend();
310 for (auto it = first; it != last; ++it)
311 {
312 if (it != first)
313 out << ", ";
314 out << parameter_forward((*it).type, (*it).name);
315 if (type_is_callback((*it).type) && it+1 != last)
316 {
317 ++it; // skip next.
318 }
319 }
320 return out;
321}
322
323struct
324parameters_forward_to_c
325{
326 parameters_container_type const& _params;
327 parameters_forward_to_c(parameters_container_type const& params)
328 : _params(params)
329 {}
330};
331
332inline std::ostream&
333operator<<(std::ostream& out, parameters_forward_to_c const& x)
334{
335 auto first = x._params.cbegin(), last = x._params.cend();
336 for (auto it = first; it != last; ++it)
337 {
338 if (it != first)
339 out << ", ";
340 if (type_is_callback((*it).type) && it + 1 != last)
341 {
342 out << to_c((*it).type, (*it).name) << ", _tmp_f";
343 ++it; // skip next
344 }
345 else
346 out << to_c((*it).type, (*it).name);
347 }
348 return out;
349}
196 350
197} } } // namespace efl { namespace eolian { namespace grammar { 351} } } // namespace efl { namespace eolian { namespace grammar {
198 352
diff --git a/src/tests/eolian_cxx/callback.c b/src/tests/eolian_cxx/callback.c
index 1371128..5192fa0 100644
--- a/src/tests/eolian_cxx/callback.c
+++ b/src/tests/eolian_cxx/callback.c
@@ -28,7 +28,7 @@ static Eina_Bool _callback_callback_added(void* data EINA_UNUSED, Eo* obj EINA_U
28 return EINA_TRUE; 28 return EINA_TRUE;
29} 29}
30 30
31static void _callback_default_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED) 31static void _callback_eo_base_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED)
32{ 32{
33 pd->callbacks = 0; 33 pd->callbacks = 0;
34 eo_do_super(obj, MY_CLASS, eo_constructor()); 34 eo_do_super(obj, MY_CLASS, eo_constructor());
@@ -37,27 +37,6 @@ static void _callback_default_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd
37 , &_callback_callback_added, pd); 37 , &_callback_callback_added, pd);
38} 38}
39 39
40static void _callback_constructor(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
41{
42 pd->callbacks = 0;
43 eo_do_super(obj, MY_CLASS, eo_constructor());
44
45 eo_event_callback_priority_add(EO_BASE_EVENT_CALLBACK_ADD, EO_CALLBACK_PRIORITY_DEFAULT
46 , &_callback_callback_added, pd);
47 cb(data);
48}
49
50static void _callback_constructor2(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data
51 , Ecore_Cb cb2 EINA_UNUSED)
52{
53 pd->callbacks = 0;
54 eo_do_super(obj, MY_CLASS, eo_constructor());
55
56 eo_event_callback_priority_add(EO_BASE_EVENT_CALLBACK_ADD, EO_CALLBACK_PRIORITY_DEFAULT
57 , &_callback_callback_added, pd);
58 cb(data);
59}
60
61static void _callback_onecallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data) 40static void _callback_onecallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
62{ 41{
63 cb(data); 42 cb(data);
diff --git a/src/tests/eolian_cxx/callback.eo b/src/tests/eolian_cxx/callback.eo
index a22885e..16dd76e 100644
--- a/src/tests/eolian_cxx/callback.eo
+++ b/src/tests/eolian_cxx/callback.eo
@@ -3,21 +3,6 @@ class Callback (Eo.Base)
3 legacy_prefix: null; 3 legacy_prefix: null;
4 data: Callback_Data; 4 data: Callback_Data;
5 methods { 5 methods {
6 default_constructor {
7 }
8 constructor {
9 params {
10 @in Ecore_Cb cb;
11 @in void* data;
12 }
13 }
14 constructor2 {
15 params {
16 @in Ecore_Cb cb;
17 @in void* data;
18 @in Ecore_Cb cb2;
19 }
20 }
21 onecallback { 6 onecallback {
22 params { 7 params {
23 @in Ecore_Cb cb; 8 @in Ecore_Cb cb;
@@ -32,12 +17,10 @@ class Callback (Eo.Base)
32 } 17 }
33 } 18 }
34 } 19 }
35 constructors { 20 implements {
36 .default_constructor; 21 Eo.Base.constructor;
37 .constructor; 22 }
38 .constructor2;
39 }
40 events { 23 events {
41 call_on_add; 24 call_on_add;
42 } 25 }
43} \ No newline at end of file 26}
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_callback.cc b/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
index 81b6ac5..5c5d95f 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
@@ -12,18 +12,6 @@
12 12
13void foo(void*) {} 13void foo(void*) {}
14 14
15START_TEST(eolian_cxx_test_callback_constructor)
16{
17 efl::eo::eo_init i;
18
19 bool called1 = false, called2 = false;
20 ::callback c1 (std::bind([&called1] { called1 = true; }));
21 ::callback c2 (std::bind([&called2] { called2 = true; }), &foo);
22 fail_if(!called1);
23 fail_if(!called2);
24}
25END_TEST
26
27START_TEST(eolian_cxx_test_callback_method) 15START_TEST(eolian_cxx_test_callback_method)
28{ 16{
29 efl::eo::eo_init i; 17 efl::eo::eo_init i;
@@ -124,7 +112,6 @@ END_TEST
124void 112void
125eolian_cxx_test_callback(TCase* tc) 113eolian_cxx_test_callback(TCase* tc)
126{ 114{
127 tcase_add_test(tc, eolian_cxx_test_callback_constructor);
128 tcase_add_test(tc, eolian_cxx_test_callback_method); 115 tcase_add_test(tc, eolian_cxx_test_callback_method);
129 tcase_add_test(tc, eolian_cxx_test_callback_event_add); 116 tcase_add_test(tc, eolian_cxx_test_callback_event_add);
130 tcase_add_test(tc, eolian_cxx_test_callback_event_del); 117 tcase_add_test(tc, eolian_cxx_test_callback_event_del);