summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono/eolian/mono/klass.hh
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-12-14 20:39:09 -0200
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2018-12-14 20:47:46 -0200
commit9603cc07eb6e04bec8aef6b4facf9865d9b9a479 (patch)
treee230baf664529d2d312b36f59795e027f3def6e7 /src/bin/eolian_mono/eolian/mono/klass.hh
parentdd5c23035312f5da3358cb30ec9359e40314e0ad (diff)
efl-mono: Fix call of virtual methods after new API
Summary: After the new API, the virtual wrapper classes (*NativeInherit) just declared the wrappers for the current class. But as they didn't have any inheritance information, reimplementing methods from a parent Eo class wouldn't work. (e.g. Efl.Ui.Button reimplementing Efl.Object FinalizeAdd). This commit changes these NativeInherit classes to mimic the inheritance chain of their regular/abstract counterparts, reusing the virtual wrapper implementations. In order to access the correct Eo class created, the methods on it were changed from static to instance methods. The instance will be held as a class member of the regular/abstract API class to keep the delegates alive and allow getting C Function pointers from them. The class_initializer method was also split in two. The method collecting the wrapper delegates was extracted in order to call the parent ones. Also avoid exception in cached strings queries as TryGetValue requires non-null keys. Test Plan: Run test suite. Reviewers: vitor.sousa, felipealmeida Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7460
Diffstat (limited to 'src/bin/eolian_mono/eolian/mono/klass.hh')
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index f10c3a3..9013329 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -357,10 +357,19 @@ struct klass
357 { 357 {
358 auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context); 358 auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context);
359 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls); 359 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
360 auto inherit_name = name_helpers::klass_inherit_name(cls);
361 std::string base_name;
362 if(!root)
363 {
364 attributes::klass_def parent_klass(get_klass(*cls.parent, cls.unit), cls.unit);
365 base_name = name_helpers::klass_full_native_inherit_name(parent_klass);
366 }
367
360 if(!as_generator 368 if(!as_generator
361 ( 369 (
362 "internal " << class_type << " " << native_inherit_name << " {\n" 370 "public " << class_type << " " << native_inherit_name << " " << (root ? "" : (": " + base_name)) <<"{\n"
363 << scope_tab << "public static byte class_initializer(IntPtr klass)\n" 371 << scope_tab << (root ? "protected IntPtr EoKlass { get; set; }\n" : "\n")
372 << scope_tab << "public " << (root ? "" : "new ") << "Efl_Op_Description[] GetEoOps()\n"
364 << scope_tab << "{\n" 373 << scope_tab << "{\n"
365 << scope_tab << scope_tab << "Efl_Op_Description[] descs = new Efl_Op_Description[" << grammar::int_ << "];\n" 374 << scope_tab << scope_tab << "Efl_Op_Description[] descs = new Efl_Op_Description[" << grammar::int_ << "];\n"
366 ) 375 )
@@ -371,20 +380,35 @@ struct klass
371 if(!as_generator(*(function_registration(index_generator, cls))) 380 if(!as_generator(*(function_registration(index_generator, cls)))
372 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false; 381 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
373 382
383 if(!root)
384 if(!as_generator(scope_tab << scope_tab << "descs = descs.Concat(base.GetEoOps()).ToArray();\n").generate(sink, attributes::unused, inative_cxt))
385 return false;
386
387 if(!as_generator(
388 scope_tab << scope_tab << "return descs;\n"
389 << scope_tab << "}\n"
390 ).generate(sink, attributes::unused, inative_cxt))
391 return false;
392
374 if(!as_generator 393 if(!as_generator
375 ( scope_tab << scope_tab << "IntPtr descs_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*" << function_count << ");\n" 394 (scope_tab << "public " << (root ? "" : "new " ) << "byte class_initializer(IntPtr klass)\n"
395 << scope_tab << "{\n"
396 << scope_tab << scope_tab << "var descs = GetEoOps();\n"
397 << scope_tab << scope_tab << "var count = descs.Length;\n"
398 << scope_tab << scope_tab << "IntPtr descs_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*count);\n"
376 << scope_tab << scope_tab << "IntPtr ptr = descs_ptr;\n" 399 << scope_tab << scope_tab << "IntPtr ptr = descs_ptr;\n"
377 << scope_tab << scope_tab << "for(int i = 0; i != " << function_count << "; ++i)\n" 400 << scope_tab << scope_tab << "for(int i = 0; i != count; ++i)\n"
378 << scope_tab << scope_tab << "{\n" 401 << scope_tab << scope_tab << "{\n"
379 << scope_tab << scope_tab << scope_tab << "Marshal.StructureToPtr(descs[i], ptr, false);\n" 402 << scope_tab << scope_tab << scope_tab << "Marshal.StructureToPtr(descs[i], ptr, false);\n"
380 << scope_tab << scope_tab << scope_tab << "ptr = IntPtr.Add(ptr, Marshal.SizeOf(descs[0]));\n" 403 << scope_tab << scope_tab << scope_tab << "ptr = IntPtr.Add(ptr, Marshal.SizeOf(descs[0]));\n"
381 << scope_tab << scope_tab << "}\n" 404 << scope_tab << scope_tab << "}\n"
382 << scope_tab << scope_tab << "Efl_Object_Ops ops;\n" 405 << scope_tab << scope_tab << "Efl_Object_Ops ops;\n"
383 << scope_tab << scope_tab << "ops.descs = descs_ptr;\n" 406 << scope_tab << scope_tab << "ops.descs = descs_ptr;\n"
384 << scope_tab << scope_tab << "ops.count = (UIntPtr)" << function_count << ";\n" 407 << scope_tab << scope_tab << "ops.count = (UIntPtr)count;\n"
385 << scope_tab << scope_tab << "IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));\n" 408 << scope_tab << scope_tab << "IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));\n"
386 << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, ops_ptr, false);\n" 409 << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, ops_ptr, false);\n"
387 << scope_tab << scope_tab << "Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n" 410 << scope_tab << scope_tab << "Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n"
411 << scope_tab << scope_tab << "EoKlass = klass;\n"
388 ).generate(sink, attributes::unused, inative_cxt)) return false; 412 ).generate(sink, attributes::unused, inative_cxt)) return false;
389 413
390 414
@@ -413,6 +437,7 @@ struct klass
413 bool is_inherit = is_inherit_context(context); 437 bool is_inherit = is_inherit_context(context);
414 438
415 std::string class_getter = "return Efl.Eo.Globals.efl_class_get(handle);"; 439 std::string class_getter = "return Efl.Eo.Globals.efl_class_get(handle);";
440 std::string native_inherit_full_name = name_helpers::klass_full_native_inherit_name(cls);
416 441
417 // The klass field is static but there is no problem if multiple C# classes inherit from this generated one 442 // The klass field is static but there is no problem if multiple C# classes inherit from this generated one
418 // as it is just a simple wrapper, forwarding the Eo calls either to the user API (where C#'s virtual method 443 // as it is just a simple wrapper, forwarding the Eo calls either to the user API (where C#'s virtual method
@@ -421,6 +446,7 @@ struct klass
421 { 446 {
422 if(!as_generator( 447 if(!as_generator(
423 scope_tab << "public " << (root ? "" : "new ") << "static System.IntPtr klass = System.IntPtr.Zero;\n" 448 scope_tab << "public " << (root ? "" : "new ") << "static System.IntPtr klass = System.IntPtr.Zero;\n"
449 << scope_tab << "public " << (root ? "" : "new ") << "static " << native_inherit_full_name << " nativeInherit = new " << native_inherit_full_name << "();\n"
424 ).generate(sink, attributes::unused, context)) 450 ).generate(sink, attributes::unused, context))
425 return false; 451 return false;
426 class_getter = "return klass;"; 452 class_getter = "return klass;";
@@ -493,7 +519,7 @@ struct klass
493 scope_tab << "///<summary>Creates a new instance.</summary>\n" 519 scope_tab << "///<summary>Creates a new instance.</summary>\n"
494 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n" 520 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
495 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n" 521 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
496 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : base(" << native_inherit_name << ".class_initializer, \"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, ref klass)\n" 522 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : base(nativeInherit.class_initializer, \"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, ref klass)\n"
497 << scope_tab << "{\n" 523 << scope_tab << "{\n"
498 << scope_tab << scope_tab << "if (init_cb != null) {\n" 524 << scope_tab << scope_tab << "if (init_cb != null) {\n"
499 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n" 525 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
@@ -518,7 +544,7 @@ struct klass
518 scope_tab << "///<summary>Creates a new instance.</summary>\n" 544 scope_tab << "///<summary>Creates a new instance.</summary>\n"
519 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n" 545 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
520 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n" 546 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
521 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : this(" << native_inherit_name << ".class_initializer, \"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, ref klass)\n" 547 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : this(nativeInherit.class_initializer, \"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, ref klass)\n"
522 << scope_tab << "{\n" 548 << scope_tab << "{\n"
523 << scope_tab << scope_tab << "if (init_cb != null) {\n" 549 << scope_tab << scope_tab << "if (init_cb != null) {\n"
524 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n" 550 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"