summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2014-11-19 13:59:21 -0200
committerVitor Sousa <vitorsousasilva@gmail.com>2015-01-05 15:52:27 -0200
commit64dede1cf1d0ab84bb8b0acfb76637621ddcdc8c (patch)
tree34f05da881f37bbbae6fd831c31b71cf692f5250
parent2b94d874fec07f3a9defee7e8d3737610af691bd (diff)
eolian_cxx: Fix callback handling on generated wrappers
Added callbacks to the event EO_EV_DEL for deleting heap-allocated function objects. This will enforce that the allocated memory, necessary for maintaining these callable objects alive, is freed at least when the underlaying Eo object is destroyed. Functions and constructor methods are now able to have multiple callback types. Removed some unused generators, since they become inconsistent now that functions are required to handle multiple callback types. Allocating callback objects in the constructor methods instead of delaying it until the final constructor is called. Created some generators to avoid code repetition. Now the generator parameters_forward_to_c replicate the behavior of the generator parameters_list. The generator parameters_list was, then, removed since it have a less intuitive name. Added a TODO comment regarding the behaviour of simple not translating callbacks that are not followed by a user data pointer. The generator parameter_type was moved from "parameters_generator.hh" to "type_generator.hh" for more consistency and convenience.
-rw-r--r--src/bindings/eo_cxx/eo_cxx_interop.hh9
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh259
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh16
-rw-r--r--src/lib/eolian_cxx/grammar/inheritance_base_generator.hh27
-rw-r--r--src/lib/eolian_cxx/grammar/parameters_generator.hh228
-rw-r--r--src/lib/eolian_cxx/grammar/type_generator.hh78
6 files changed, 375 insertions, 242 deletions
diff --git a/src/bindings/eo_cxx/eo_cxx_interop.hh b/src/bindings/eo_cxx/eo_cxx_interop.hh
index 174d5438be..fa3e44b282 100644
--- a/src/bindings/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/eo_cxx/eo_cxx_interop.hh
@@ -234,6 +234,15 @@ C get_callback()
234 (tag<typename callback_args_type<C>::type>()); 234 (tag<typename callback_args_type<C>::type>());
235} 235}
236 236
237template <typename F>
238Eina_Bool free_callback_calback(void* data, Eo* obj EINA_UNUSED
239 , Eo_Event_Description const* e EINA_UNUSED
240 , void* event_info EINA_UNUSED)
241{
242 delete (F*) data;
243 return EO_CALLBACK_CONTINUE;
244}
245
237} } // namespace efl { namespace eolian { 246} } // namespace efl { namespace eolian {
238 247
239#endif // EFL_EOLIAN_INTEROP_HH 248#endif // EFL_EOLIAN_INTEROP_HH
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 f02ca7b7a6..c7a9bbba80 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
@@ -104,12 +104,25 @@ inline std::ostream&
104operator<<(std::ostream& out, constructor_functor_type_decl const& x) 104operator<<(std::ostream& out, constructor_functor_type_decl const& x)
105{ 105{
106 out << constructor_functor_type_name(x._ctor); 106 out << constructor_functor_type_name(x._ctor);
107 auto cb_it = parameters_find_callback(x._ctor.params); 107
108 if(cb_it != x._ctor.params.cend()) 108 if (parameters_count_callbacks(x._ctor.params) == 0)
109 return out;
110
111 bool comma = false;
112 out << "<";
113 auto first = x._ctor.params.cbegin(), last = x._ctor.params.cend();
114 for(auto it = first; it != last; ++it)
109 { 115 {
110 out << "<F>"; 116 if (type_is_callback((*it).type) && it+1 != last)
117 {
118 if (comma)
119 out << ", ";
120 else
121 comma = true;
122 out << template_parameter_type((*it).type, (*it).name);
123 }
111 } 124 }
112 return out; 125 return out << ">";
113} 126}
114 127
115struct functors_constructor_methods 128struct functors_constructor_methods
@@ -127,17 +140,24 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
127 for (it = first; it != last; ++it) 140 for (it = first; it != last; ++it)
128 { 141 {
129 eo_constructor const& c = *it; 142 eo_constructor const& c = *it;
130 auto cb_it = parameters_find_callback(c.params);
131 bool has_callback = (cb_it != c.params.cend());
132 143
133 // Struct declaration 144 // Struct declaration
134 if(has_callback) 145 out << template_parameters_declaration(c.params, 1)
135 { 146 << tab(1) << "struct " << constructor_functor_type_name(c) << endl
136 out << tab(1) << "template <typename F>" << endl;
137 }
138 out << tab(1) << "struct " << constructor_functor_type_name(c) << endl
139 << tab(1) << "{" << endl; 147 << tab(1) << "{" << endl;
140 148
149 // Callbacks typedefs
150 out << parameters_cxx_generic(c.params,
151 [](param_data d)
152 {
153 if (d.is_cb)
154 d.out << tab(2)
155 << parameter_remove_reference_typedef(d.type, d.name)
156 << endl;
157 }
158 )
159 << endl;
160
141 // Struct constructor 161 // Struct constructor
142 out << tab(2) << constructor_functor_type_name(c) << "(" 162 out << tab(2) << constructor_functor_type_name(c) << "("
143 << parameters_declaration(c.params) << ")" 163 << parameters_declaration(c.params) << ")"
@@ -148,7 +168,13 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
148 d.out << endl << tab(3) << ": "; 168 d.out << endl << tab(3) << ": ";
149 else 169 else
150 d.out << ", "; 170 d.out << ", ";
151 d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")"; 171
172 if (d.is_cb)
173 d.out << callback_tmp(d.name) << "(new "
174 << template_parameter_type(d.type, d.name)
175 << "(" << parameter_forward(d.type, d.name) << "))";
176 else
177 d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")";
152 } 178 }
153 ) 179 )
154 << endl 180 << endl
@@ -156,21 +182,22 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
156 182
157 // Struct operator() 183 // Struct operator()
158 out << tab(2) << "void operator()()" << endl 184 out << tab(2) << "void operator()()" << endl
159 << tab(2) << "{" << endl; 185 << tab(2) << "{" << endl
160 if (has_callback) 186 << tab(3) << "::" << c.name << "(" << parameters_forward_to_c(c.params) << ");" << endl
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; 187 << tab(2) << "}" << endl;
167 188
168 // Struct member variables 189 // Struct member variables
169 out << tab(1) << "private:" << endl 190 out << endl
170 << parameters_cxx_generic(c.params, 191 << parameters_cxx_generic(c.params,
171 [](param_data d) 192 [](param_data d)
172 { 193 {
173 d.out << tab(2) << parameter_type(d.type) << " " << d.name << ";" << endl; 194 d.out << tab(2);
195 if (d.is_cb)
196 d.out << parameter_no_ref_type(d.type, d.name) << "* "
197 << callback_tmp(d.name);
198 else
199 d.out << parameter_type(d.type, d.name) << " " << d.name;
200 d.out << ";" << endl;
174 } 201 }
175 ); 202 );
176 203
@@ -197,12 +224,9 @@ operator<<(std::ostream& out, functions_constructor_methods const& x)
197 { 224 {
198 eo_constructor const& c = *it; 225 eo_constructor const& c = *it;
199 226
200 out << comment(c.comment, 1); 227 out << comment(c.comment, 1)
201 228 << template_parameters_declaration(c.params, 1)
202 unsigned cb_count = parameters_count_callbacks(c.params); 229 << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
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 230 << parameters_declaration(c.params) << ")" << endl
207 << tab(1) << "{" << endl 231 << tab(1) << "{" << endl
208 << tab(2) << "return " << constructor_functor_type_decl(c) << "(" 232 << tab(2) << "return " << constructor_functor_type_decl(c) << "("
@@ -228,26 +252,50 @@ operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
228 // TODO Require constructor methods of all base classes ? 252 // TODO Require constructor methods of all base classes ?
229 // 253 //
230 254
255 unsigned cb_count = 0;
256
231 constructors_container_type::const_iterator it, 257 constructors_container_type::const_iterator it,
232 first = x._cls.constructors.cbegin(), 258 first = x._cls.constructors.cbegin(),
233 last = x._cls.constructors.cend(); 259 last = x._cls.constructors.cend();
234
235 for (it = first; it != last; ++it) 260 for (it = first; it != last; ++it)
236 { 261 {
237 unsigned cb_count = parameters_count_callbacks((*it).params); 262 cb_count += parameters_count_callbacks((*it).params);
238 if(cb_count) 263 }
264
265 if (cb_count != 0)
266 {
267 out << tab(1) << "template <";
268 for (unsigned i = 0; i != cb_count; ++i)
239 { 269 {
240 out << tab(1) << "template <typename F>" << endl; 270 if (i != 0)
241 break; 271 out << ", ";
272 out << "typename F" << i;
242 } 273 }
274 out << ">" << endl;
243 } 275 }
244 276
245 out << tab(1) << x._cls.name << "("; 277 out << tab(1) << x._cls.name << "(";
246 for (it = first; it != last; ++it) 278 {
247 { 279 unsigned cb_idx = 0;
248 out << constructor_functor_type_decl(*it) 280 for (it = first; it != last; ++it)
249 << " _c" << (it-first) << ", "; 281 {
250 } 282 out << constructor_functor_type_name(*it);
283
284 if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
285 {
286 out << "<"
287 << parameters_cxx_generic((*it).params,
288 [&cb_idx](param_data d)
289 {
290 if (d.is_cb)
291 d.out << (d.cb_idx ? ", " : "") << "F" << cb_idx++;
292 })
293 << ">";
294 }
295 out << " _c" << (it-first) << ", ";
296 }
297 assert(cb_idx == cb_count);
298 }
251 out << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl 299 out << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
252 << tab(2) << ": " << x._cls.name << "(_ctors_call("; 300 << tab(2) << ": " << x._cls.name << "(_ctors_call(";
253 for (it = first; it != last; ++it) 301 for (it = first; it != last; ++it)
@@ -292,40 +340,6 @@ operator<<(std::ostream& out, constructor_eo const& x)
292 return out; 340 return out;
293} 341}
294 342
295struct constructors
296{
297 eo_class const& _cls;
298 constructors(eo_class const& cls)
299 : _cls(cls)
300 {}
301};
302
303inline std::ostream&
304operator<<(std::ostream& out, constructors const& x)
305{
306 constructors_container_type::const_iterator it,
307 first = x._cls.constructors.cbegin(),
308 last = x._cls.constructors.cend();
309 for (it = first; it != last; ++it)
310 {
311 eo_constructor const& ctor = *it;
312 out << comment(ctor.comment, 1);
313 if (parameters_count_callbacks(ctor.params))
314 out << tab(1) << "template <typename F>" << endl;
315 out << tab(1)
316 << x._cls.name
317 << '(' << parameters_declaration(ctor.params)
318 << (ctor.params.size() > 0 ? ", " : "")
319 << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
320 << tab(2) << ": " << class_name(x._cls.name)
321 << "(_c" << (it - first) << "(" << constructor_parameters_list(ctor.params)
322 << (ctor.params.size() > 0 ? ", " : "")
323 << "_p))" << endl
324 << tab(1) << "{}" << endl << endl;
325 }
326 return out;
327}
328
329struct copy_constructor 343struct copy_constructor
330{ 344{
331 eo_class const& _cls; 345 eo_class const& _cls;
@@ -363,48 +377,6 @@ operator<<(std::ostream& out, destructor const& x)
363 return out; 377 return out;
364} 378}
365 379
366struct eo_class_constructors
367{
368 eo_class const& _cls;
369 eo_class_constructors(eo_class const& cls) : _cls(cls) {}
370};
371
372inline std::ostream&
373operator<<(std::ostream& out, eo_class_constructors const& x)
374{
375 constructors_container_type::const_iterator it,
376 first = x._cls.constructors.begin(),
377 last = x._cls.constructors.end();
378 for (it = first; it != last; ++it)
379 {
380 if (parameters_count_callbacks((*it).params))
381 out << tab(1) << "template <typename F>" << endl;
382 out << tab(1)
383 << "static Eo* _c" << (it - first) << "("
384 << parameters_declaration((*it).params)
385 << ((*it).params.size() > 0 ? ", " : "")
386 << "efl::eo::parent_type _p"
387 << ')' << endl
388 << tab(1) << "{" << endl;
389
390 parameters_container_type::const_iterator callback_iter =
391 parameters_find_callback((*it).params);
392 if (callback_iter != (*it).params.cend())
393 {
394 out << tab(2)
395 << "typedef typename std::remove_reference<F>::type function_type;" << endl
396 << "function_type* _tmp_f = new F(std::forward<F>("
397 << (*callback_iter).name << "));"
398 << endl;
399 }
400 out << tab(2) << "return eo_add_ref("
401 << x._cls.eo_name << ", _p._eo_raw, " << (*it).name
402 << "(" << parameters_list((*it).params) << "));" << endl
403 << tab(1) << "}" << endl << endl;
404 }
405 return out;
406}
407
408struct function_call_constructor_methods 380struct function_call_constructor_methods
409{ 381{
410 eo_class const& _cls; 382 eo_class const& _cls;
@@ -414,31 +386,78 @@ struct function_call_constructor_methods
414inline std::ostream& 386inline std::ostream&
415operator<<(std::ostream& out, function_call_constructor_methods const& x) 387operator<<(std::ostream& out, function_call_constructor_methods const& x)
416{ 388{
389 unsigned cb_count = 0;
390
417 constructors_container_type::const_iterator it, 391 constructors_container_type::const_iterator it,
418 first = x._cls.constructors.cbegin(), 392 first = x._cls.constructors.cbegin(),
419 last = x._cls.constructors.cend(); 393 last = x._cls.constructors.cend();
420 for (it = first; it != last; ++it) 394 for (it = first; it != last; ++it)
421 { 395 {
422 unsigned cb_count = parameters_count_callbacks((*it).params); 396 unsigned param_cb_count = parameters_count_callbacks((*it).params);
423 if (cb_count) 397 for (unsigned i = 0; i != param_cb_count; ++i)
424 { 398 {
425 out << tab(1) << "template <typename F>" << endl; 399 if(cb_count == 0)
426 break; 400 out << tab(1) << "template <";
401 else
402 out << ", ";
403 out << "typename F" << cb_count++;
427 } 404 }
428 } 405 }
406 if (cb_count != 0)
407 out << ">" << endl;
408
409 unsigned cb_idx = 0;
429 out << tab(1) << "static Eo* _ctors_call("; 410 out << tab(1) << "static Eo* _ctors_call(";
430 for (it = first; it != last; ++it) 411 for (it = first; it != last; ++it)
431 { 412 {
432 out << constructor_functor_type_decl(*it) << " _c" << (it-first) << ", "; 413 out << constructor_functor_type_name(*it);
414
415 if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
416 {
417 out << "<"
418 << parameters_cxx_generic((*it).params,
419 [&cb_idx](param_data d)
420 {
421 if (d.is_cb)
422 d.out << (d.cb_idx ? ", " : "") << "F" << cb_idx++;
423 })
424 << ">";
425 }
426 out << " _c" << (it-first) << ", ";
433 } 427 }
428 assert(cb_idx == cb_count);
429
434 out << "efl::eo::parent_type _p)" << endl 430 out << "efl::eo::parent_type _p)" << endl
435 << tab(1) << "{" << endl 431 << tab(1) << "{" << endl
436 << tab(2) << "return eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, "; 432 << tab(2) << "Eo* _ret_eo = eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, ";
437 for (it = first; it != last; ++it) 433 for (it = first; it != last; ++it)
438 { 434 {
439 out << "_c" << (it-first) << "(); "; 435 out << "_c" << (it-first) << "(); ";
440 } 436 }
441 out << ");" << endl 437 out << ");" << endl << endl;
438
439 cb_idx = 0;
440 for (it = first; it != last; ++it)
441 {
442 if (parameters_count_callbacks((*it).params) == 0)
443 continue;
444
445 out << parameters_cxx_generic((*it).params,
446 [&it, &first, &cb_idx](param_data d)
447 {
448 if (d.is_cb)
449 d.out << tab(2)
450 << "eo_do(_ret_eo," << endl
451 << tab(3) << "eo_event_callback_add(EO_EV_DEL, "
452 << "&efl::eolian::free_callback_calback<F" << cb_idx++
453 << ">, _c" << (it-first) << "." << callback_tmp(d.name)
454 << "));" << endl;
455 })
456 << endl;
457 }
458 assert(cb_idx == cb_count);
459
460 out << tab(2) << "return _ret_eo;" << endl
442 << tab(1) << "}" << endl << endl; 461 << tab(1) << "}" << endl << endl;
443 462
444 return out; 463 return out;
diff --git a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
index d9c1ab9a3e..9c48106de4 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
@@ -24,7 +24,7 @@ operator<<(std::ostream& out, function_call const& x)
24 bool is_void = function_is_void(x._func); 24 bool is_void = function_is_void(x._func);
25 return out << (!is_void ? "_tmp_ret = " : "") 25 return out << (!is_void ? "_tmp_ret = " : "")
26 << "::" << x._func.impl 26 << "::" << x._func.impl
27 << "(" << parameters_list(x._func.params) << ")"; 27 << "(" << parameters_forward_to_c(x._func.params) << ")";
28} 28}
29 29
30struct function 30struct function
@@ -39,8 +39,7 @@ operator<<(std::ostream& out, function const& x)
39 eo_function const& func = x._func; 39 eo_function const& func = x._func;
40 40
41 out << comment(x._func.comment, 1); 41 out << comment(x._func.comment, 1);
42 if (parameters_count_callbacks(x._func.params) == 1) 42 out << template_parameters_declaration(func.params, 1);
43 out << tab(1) << "template <typename F>" << endl;
44 43
45 if (function_is_static(func)) 44 if (function_is_static(func))
46 out << tab(1) << "static "; 45 out << tab(1) << "static ";
@@ -55,16 +54,7 @@ operator<<(std::ostream& out, function const& x)
55 out << tab(2) 54 out << tab(2)
56 << func.ret.front().native << " _tmp_ret;" << endl; 55 << func.ret.front().native << " _tmp_ret;" << endl;
57 56
58 parameters_container_type::const_iterator callback_iter = 57 out << callbacks_heap_alloc("_eo_ptr()", func.params, 2);
59 parameters_find_callback(func.params);
60 if (callback_iter != func.params.cend())
61 {
62 out << tab(2)
63 << "typedef typename std::remove_reference<F>::type function_type;" << endl
64 << tab(2) << "function_type* _tmp_f = new function_type(std::forward<F>("
65 << (*callback_iter).name << "));"
66 << endl;
67 }
68 58
69 out << tab(2) 59 out << tab(2)
70 << "eo_do(_eo_ptr(), " << function_call(x._func) << ");" << endl; 60 << "eo_do(_eo_ptr(), " << function_call(x._func) << ");" << endl;
diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
index 778ec51f1f..36d0821826 100644
--- a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
+++ b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
@@ -155,8 +155,8 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
155 eo_function const& func = x._func; 155 eo_function const& func = x._func;
156 bool is_void = function_is_void(func); 156 bool is_void = function_is_void(func);
157 157
158 if (parameters_count_callbacks(func.params) == 1) 158 if (parameters_count_callbacks(func.params))
159 out << tab(2) << "template <typename F>" << tab(2) << endl; 159 out << template_parameters_declaration(func.params, 2) << tab(2);
160 else 160 else
161 out << tab(2) << "virtual "; 161 out << tab(2) << "virtual ";
162 162
@@ -168,12 +168,8 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
168 if (!is_void) 168 if (!is_void)
169 out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl; 169 out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl;
170 170
171 parameters_container_type::const_iterator 171 out << callbacks_heap_alloc("static_cast<T*>(this)->_eo_ptr()", func.params, 3)
172 callback_iter = parameters_find_callback(func.params); 172 << endl;
173 if (callback_iter != func.params.cend())
174 out << tab(3) << "typedef typename std::remove_reference<F>::type function_type;" << endl
175 << tab(3) << "function_type* _tmp_f = new function_type(std::forward<F>("
176 << (*callback_iter).name << "));" << endl;
177 173
178 out << tab(3) 174 out << tab(3)
179 << "eo_do_super(static_cast<T*>(this)->_eo_ptr()," << endl 175 << "eo_do_super(static_cast<T*>(this)->_eo_ptr()," << endl
@@ -291,8 +287,7 @@ struct inheritance_extension_function
291inline std::ostream& 287inline std::ostream&
292operator<<(std::ostream& out, inheritance_extension_function const& x) 288operator<<(std::ostream& out, inheritance_extension_function const& x)
293{ 289{
294 if (parameters_count_callbacks(x._func.params) == 1) 290 out << template_parameters_declaration(x._func.params, 1);
295 out << tab(1) << "template <typename F>" << endl;
296 291
297 bool is_void = function_is_void(x._func); 292 bool is_void = function_is_void(x._func);
298 out << tab(2) 293 out << tab(2)
@@ -307,16 +302,8 @@ operator<<(std::ostream& out, inheritance_extension_function const& x)
307 out << tab(3) << x._func.ret.front().native << " _tmp_ret = {};" << endl; 302 out << tab(3) << x._func.ret.front().native << " _tmp_ret = {};" << endl;
308 } 303 }
309 304
310 parameters_container_type::const_iterator callback_iter = 305 out << callbacks_heap_alloc("static_cast<U*>(this)->_eo_ptr()", x._func.params, 2)
311 parameters_find_callback(x._func.params); 306 << endl;
312 if (callback_iter != x._func.params.cend())
313 {
314 out << tab(2)
315 << "typedef typename std::remove_reference<F>::type function_type;" << endl
316 << "function_type* _tmp_f = new function_type(std::forward<F>("
317 << (*callback_iter).name << "));"
318 << endl;
319 }
320 307
321 out << tab(3) << "eo_do(static_cast<U*>(this)->_eo_ptr(), " 308 out << tab(3) << "eo_do(static_cast<U*>(this)->_eo_ptr(), "
322 << function_call(x._func) << ");" << endl; 309 << function_call(x._func) << ");" << endl;
diff --git a/src/lib/eolian_cxx/grammar/parameters_generator.hh b/src/lib/eolian_cxx/grammar/parameters_generator.hh
index 5492859b33..f6084790bb 100644
--- a/src/lib/eolian_cxx/grammar/parameters_generator.hh
+++ b/src/lib/eolian_cxx/grammar/parameters_generator.hh
@@ -11,25 +11,6 @@
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 14parameter_forward
34{ 15{
35 eolian_type_instance const& _type; 16 eolian_type_instance const& _type;
@@ -45,7 +26,7 @@ operator<<(std::ostream& out, parameter_forward const& x)
45{ 26{
46 if (type_is_callback(x._type)) 27 if (type_is_callback(x._type))
47 { 28 {
48 out << "std::forward<F>(" << x._name << ")"; 29 out << "std::forward<" << template_parameter_type(x._type, x._name) << ">(" << x._name << ")";
49 } 30 }
50 else 31 else
51 out << x._name; 32 out << x._name;
@@ -110,6 +91,134 @@ parameters_cxx_generic(parameters_container_type const& params, T fparam)
110} 91}
111 92
112struct 93struct
94callback_tmp
95{
96 std::string const& _name;
97 callback_tmp(std::string const& name)
98 : _name(name)
99 {}
100};
101
102inline std::ostream&
103operator<<(std::ostream& out, callback_tmp const& x)
104{
105 return out << "_tmp_" << x._name;
106}
107
108struct
109callback_parameter_heap_alloc
110{
111 eolian_type_instance const& _type;
112 std::string const& _name;
113 int _tab;
114 callback_parameter_heap_alloc(eolian_type_instance const& type, std::string const& name, int tab)
115 : _type(type)
116 , _name(name)
117 , _tab(tab)
118 {}
119};
120
121inline std::ostream&
122operator<<(std::ostream& out, callback_parameter_heap_alloc const& x)
123{
124 out << tab(x._tab) << parameter_remove_reference_typedef(x._type, x._name) << endl
125 << tab(x._tab) << parameter_no_ref_type(x._type, x._name) << "* "
126 << callback_tmp(x._name) << " = new "
127 << parameter_no_ref_type(x._type, x._name) << "(std::forward<"
128 << template_parameter_type(x._type, x._name) << ">(" << x._name << "));" << endl;
129 return out;
130}
131
132struct
133callback_parameter_free_ev_add
134{
135 std::string const& _eo_raw_expr;
136 eolian_type_instance const& _type;
137 std::string const& _name;
138 callback_parameter_free_ev_add(std::string const& eo_raw_expr, eolian_type_instance const& type, std::string const& name)
139 : _eo_raw_expr(eo_raw_expr)
140 , _type(type)
141 , _name(name)
142 {}
143};
144
145inline std::ostream&
146operator<<(std::ostream& out, callback_parameter_free_ev_add const& x)
147{
148 out << "eo_do(" << x._eo_raw_expr
149 << ", eo_event_callback_add(EO_EV_DEL, &efl::eolian::free_callback_calback<"
150 << parameter_no_ref_type(x._type, x._name) << ">, "
151 << callback_tmp(x._name) << "));";
152 return out;
153}
154
155struct
156callbacks_heap_alloc
157{
158 std::string const& _eo_raw_expr;
159 parameters_container_type const& _params;
160 int _tab;
161 callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, int tab)
162 : _eo_raw_expr(eo_raw_expr)
163 , _params(params)
164 , _tab(tab)
165 {}
166};
167
168inline std::ostream&
169operator<<(std::ostream& out, callbacks_heap_alloc const& x)
170{
171 auto first = x._params.cbegin(), last = x._params.cend();
172 for (auto it = first; it != last; ++it)
173 {
174 if (type_is_callback((*it).type) && it+1 != last)
175 {
176 out << callback_parameter_heap_alloc((*it).type, (*it).name, x._tab)
177 << tab(x._tab)
178 << callback_parameter_free_ev_add(x._eo_raw_expr, (*it).type, (*it).name)
179 << endl << endl;
180 ++it; // skip next.
181 }
182 }
183 return out;
184}
185
186struct
187template_parameters_declaration
188{
189 parameters_container_type const& _params;
190 int _tab;
191 template_parameters_declaration(parameters_container_type const& params, int tab)
192 : _params(params)
193 , _tab(tab)
194 {}
195};
196
197inline std::ostream&
198operator<<(std::ostream& out, template_parameters_declaration const& x)
199{
200 if (parameters_count_callbacks(x._params) == 0)
201 return out;
202
203 bool comma = false;
204 out << tab(x._tab) << "template <";
205 auto first = x._params.cbegin(), last = x._params.cend();
206 for (auto it = first; it != last; ++it)
207 {
208 if (type_is_callback((*it).type) && it+1 != last)
209 {
210 if (comma)
211 out << ", ";
212 else
213 comma = true;
214 out << "typename " << template_parameter_type((*it).type, (*it).name);
215 ++it; // skip next.
216 }
217 }
218 return out << ">" << endl;
219}
220
221struct
113parameters_declaration 222parameters_declaration
114{ 223{
115 parameters_container_type const& _params; 224 parameters_container_type const& _params;
@@ -131,8 +240,7 @@ operator<<(std::ostream& out, parameters_declaration const& x)
131 // and does not have a following userdata pointer ? 240 // and does not have a following userdata pointer ?
132 if (type_is_callback((*it).type) && it+1 != last) 241 if (type_is_callback((*it).type) && it+1 != last)
133 { 242 {
134 out << "F && " << (*it).name; 243 out << template_parameter_type((*it).type, (*it).name) << " && " << (*it).name;
135 assert(it+1 != last);
136 ++it; // skip next. 244 ++it; // skip next.
137 } 245 }
138 else 246 else
@@ -188,40 +296,6 @@ operator<<(std::ostream& out, parameters_types const& x)
188} 296}
189 297
190struct 298struct
191parameters_list
192{
193 parameters_container_type const& _params;
194 parameters_list(parameters_container_type const& params)
195 : _params(params)
196 {}
197};
198
199inline std::ostream&
200operator<<(std::ostream& out, parameters_list const& x)
201{
202 auto first = x._params.cbegin(), last = x._params.cend();
203 for (auto it = first; it != last; ++it)
204 {
205 if (it != first)
206 out << ", ";
207 if (type_is_callback((*it).type))
208 {
209 if(it + 1 != last)
210 {
211 out << to_c((*it).type, (*it).name)
212 << ", _tmp_f";
213 ++it; // skip next
214 }
215 else
216 out << it->name;
217 }
218 else
219 out << to_c((*it).type, (*it).name);
220 }
221 return out;
222}
223
224struct
225parameters_c_list 299parameters_c_list
226{ 300{
227 parameters_container_type const& _params; 301 parameters_container_type const& _params;
@@ -266,35 +340,6 @@ operator<<(std::ostream& out, parameters_cxx_list const& x)
266} 340}
267 341
268struct 342struct
269constructor_parameters_list
270{
271 parameters_container_type const& _params;
272 constructor_parameters_list(parameters_container_type const& params)
273 : _params(params)
274 {}
275};
276
277inline std::ostream&
278operator<<(std::ostream& out, constructor_parameters_list const& x)
279{
280 auto first = x._params.cbegin(),
281 last = x._params.cend();
282 for (auto it = first; it != last; ++it)
283 {
284 if (it != first)
285 out << ", ";
286 if (type_is_callback((*it).type) && it + 1 != last)
287 {
288 out << "std::forward<F>(" << (*it).name << ")";
289 ++it; // skip next.
290 }
291 else
292 out << (*it).name;
293 }
294 return out;
295}
296
297struct
298parameters_forward 343parameters_forward
299{ 344{
300 parameters_container_type const& _params; 345 parameters_container_type const& _params;
@@ -337,10 +382,17 @@ operator<<(std::ostream& out, parameters_forward_to_c const& x)
337 { 382 {
338 if (it != first) 383 if (it != first)
339 out << ", "; 384 out << ", ";
340 if (type_is_callback((*it).type) && it + 1 != last) 385 if (type_is_callback((*it).type))
341 { 386 {
342 out << to_c((*it).type, (*it).name) << ", _tmp_f"; 387 // TODO: Is it correct to simple not translate the callback type
343 ++it; // skip next 388 // when it is the last paramenter?
389 if(it + 1 != last)
390 {
391 out << to_c((*it).type, (*it).name) << ", " << callback_tmp((*it).name);
392 ++it; // skip next
393 }
394 else
395 out << (*it).name;
344 } 396 }
345 else 397 else
346 out << to_c((*it).type, (*it).name); 398 out << to_c((*it).type, (*it).name);
diff --git a/src/lib/eolian_cxx/grammar/type_generator.hh b/src/lib/eolian_cxx/grammar/type_generator.hh
index 8584a572db..fcd16005c8 100644
--- a/src/lib/eolian_cxx/grammar/type_generator.hh
+++ b/src/lib/eolian_cxx/grammar/type_generator.hh
@@ -77,6 +77,81 @@ operator<<(std::ostream& out, type_ownership const& x)
77 return out << ">()"; 77 return out << ">()";
78} 78}
79 79
80struct
81template_parameter_type
82{
83 eolian_type_instance const& _type;
84 std::string const& _name;
85 template_parameter_type(eolian_type_instance const& type, std::string const& name)
86 : _type(type)
87 , _name(name)
88 {}
89};
90
91inline std::ostream&
92operator<<(std::ostream& out, template_parameter_type const& x)
93{
94 return out << "F_" << x._name;
95}
96
97struct
98parameter_type
99{
100 eolian_type_instance const& _type;
101 std::string const& _name;
102 parameter_type(eolian_type_instance const& t, std::string const& name)
103 : _type(t)
104 , _name(name)
105 {}
106};
107
108inline std::ostream&
109operator<<(std::ostream& out, parameter_type const& x)
110{
111 if(type_is_callback(x._type))
112 out << template_parameter_type(x._type, x._name);
113 else
114 out << reinterpret_type(x._type);
115 return out;
116}
117
118struct
119parameter_no_ref_type
120{
121 eolian_type_instance const& _type;
122 std::string const& _name;
123 parameter_no_ref_type(eolian_type_instance const& type, std::string const& name)
124 : _type(type)
125 , _name(name)
126 {}
127};
128
129inline std::ostream&
130operator<<(std::ostream& out, parameter_no_ref_type const& x)
131{
132 return out << "_no_ref_" << parameter_type(x._type, x._name);
133}
134
135struct
136parameter_remove_reference_typedef
137{
138 eolian_type_instance const& _type;
139 std::string const& _name;
140 parameter_remove_reference_typedef(eolian_type_instance const& type, std::string const& name)
141 : _type(type)
142 , _name(name)
143 {}
144};
145
146inline std::ostream&
147operator<<(std::ostream& out, parameter_remove_reference_typedef const& x)
148{
149 out << "typedef typename std::remove_reference<"
150 << parameter_type(x._type, x._name)
151 << ">::type " << parameter_no_ref_type(x._type, x._name) << ";";
152 return out;
153}
154
80struct to_cxx 155struct to_cxx
81{ 156{
82 eolian_type_instance const& _type; 157 eolian_type_instance const& _type;
@@ -114,7 +189,8 @@ inline std::ostream&
114operator<<(std::ostream& out, to_c const& x) 189operator<<(std::ostream& out, to_c const& x)
115{ 190{
116 if (type_is_callback(x._type)) 191 if (type_is_callback(x._type))
117 out << "efl::eolian::get_callback<" << type_to_native_str(x._type) << ", function_type>()"; 192 out << "efl::eolian::get_callback<" << type_to_native_str(x._type)
193 << ", " << parameter_no_ref_type(x._type, x._varname) << " >()";
118 else if (type_is_binding(x._type)) 194 else if (type_is_binding(x._type))
119 out << "efl::eolian::to_c(" << x._varname << ")"; 195 out << "efl::eolian::to_c(" << x._varname << ")";
120 else 196 else