summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh10
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh30
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh178
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh12
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs104
-rw-r--r--src/tests/efl_mono/Inheritance.cs4
6 files changed, 196 insertions, 142 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 763bbc4..2d9e1b5 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -71,7 +71,11 @@ struct native_function_definition_generator
71 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context)) 71 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
72 return false; 72 return false;
73 73
74 std::string klass_inherit_name = name_helpers::klass_inherit_name(*klass); 74 std::string klass_cast_name;
75 if (klass->type != attributes::class_type::interface_)
76 klass_cast_name = name_helpers::klass_inherit_name(*klass);
77 else
78 klass_cast_name = name_helpers::klass_interface_name(*klass);
75 79
76 if(!as_generator 80 if(!as_generator
77 (scope_tab 81 (scope_tab
@@ -89,7 +93,7 @@ struct native_function_definition_generator
89 << scope_tab << scope_tab << "if(wrapper != null) {\n" 93 << scope_tab << scope_tab << "if(wrapper != null) {\n"
90 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() 94 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble()
91 << scope_tab << scope_tab << scope_tab << "try {\n" 95 << scope_tab << scope_tab << scope_tab << "try {\n"
92 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_inherit_name << ")wrapper)." << string 96 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_cast_name << ")wrapper)." << string
93 << "(" << (native_argument_invocation % ", ") << ");\n" 97 << "(" << (native_argument_invocation % ", ") << ");\n"
94 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n" 98 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n"
95 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n" 99 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
@@ -98,7 +102,7 @@ struct native_function_definition_generator
98 << eolian_mono::native_function_definition_epilogue(*klass) 102 << eolian_mono::native_function_definition_epilogue(*klass)
99 << scope_tab << scope_tab << "} else {\n" 103 << scope_tab << scope_tab << "} else {\n"
100 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string 104 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string
101 << "(Efl.Eo.Globals.efl_super(obj, " << "EoKlass)" << *(", " << argument) << ");\n" 105 << "(Efl.Eo.Globals.efl_super(obj, " << "GetEflClass())" << *(", " << argument) << ");\n"
102 << scope_tab << scope_tab << "}\n" 106 << scope_tab << scope_tab << "}\n"
103 << scope_tab << "}\n" 107 << scope_tab << "}\n"
104 ) 108 )
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index 0b8da4a..78f2d71 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -20,10 +20,10 @@
20 20
21namespace eolian_mono { 21namespace eolian_mono {
22 22
23template <typename I> 23// template <typename I>
24struct function_registration_generator 24struct function_registration_generator
25{ 25{
26 I index_generator; 26 // I index_generator;
27 attributes::klass_def const* klass; 27 attributes::klass_def const* klass;
28 28
29 template <typename OutputIterator, typename Context> 29 template <typename OutputIterator, typename Context>
@@ -34,7 +34,7 @@ struct function_registration_generator
34 return true; 34 return true;
35 else 35 else
36 { 36 {
37 auto index = index_generator(); 37 // auto index = index_generator();
38 38
39 if(!as_generator( 39 if(!as_generator(
40 scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" << 40 scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" <<
@@ -43,12 +43,13 @@ struct function_registration_generator
43 return false; 43 return false;
44 44
45 if(!as_generator 45 if(!as_generator
46 (scope_tab << scope_tab << "descs.Add(new Efl_Op_Description() {"
46#ifdef _WIN32 47#ifdef _WIN32
47 (scope_tab << scope_tab << "descs[" << index << "].api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\");\n" 48 << "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")"
48#else 49#else
49 (scope_tab << scope_tab << "descs[" << index << "].api_func = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" << string << "\");\n" 50 << "api_func = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" << string << "\")"
50#endif 51#endif
51 << scope_tab << scope_tab << "descs[" << index << "].func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate);\n" 52 ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate)});\n"
52 ) 53 )
53 .generate(sink, std::make_tuple(f.c_name, f.c_name), context)) 54 .generate(sink, std::make_tuple(f.c_name, f.c_name), context))
54 return false; 55 return false;
@@ -59,10 +60,9 @@ struct function_registration_generator
59 60
60struct function_registration_parameterized 61struct function_registration_parameterized
61{ 62{
62 template <typename I> 63 function_registration_generator operator()(attributes::klass_def const& klass) const
63 function_registration_generator<I> operator()(I i, attributes::klass_def const& klass) const
64 { 64 {
65 return {i, &klass}; 65 return {&klass};
66 } 66 }
67} const function_registration; 67} const function_registration;
68 68
@@ -70,15 +70,15 @@ struct function_registration_parameterized
70 70
71namespace efl { namespace eolian { namespace grammar { 71namespace efl { namespace eolian { namespace grammar {
72 72
73template <typename I> 73template <>
74struct is_eager_generator< ::eolian_mono::function_registration_generator<I>> : std::true_type {}; 74struct is_eager_generator< ::eolian_mono::function_registration_generator> : std::true_type {};
75template <typename I> 75template <>
76struct is_generator< ::eolian_mono::function_registration_generator<I>> : std::true_type {}; 76struct is_generator< ::eolian_mono::function_registration_generator> : std::true_type {};
77 77
78namespace type_traits { 78namespace type_traits {
79 79
80template <typename I> 80template <>
81struct attributes_needed< ::eolian_mono::function_registration_generator<I>> : std::integral_constant<int, 1> {}; 81struct attributes_needed< ::eolian_mono::function_registration_generator> : std::integral_constant<int, 1> {};
82} 82}
83 83
84} } } 84} } }
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 5dc22f5..c3d430e 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -123,58 +123,57 @@ struct klass
123 // Interface class 123 // Interface class
124 if(class_type == "interface") 124 if(class_type == "interface")
125 { 125 {
126 auto iface_cxt = context_add_tag(class_context{class_context::interface}, context); 126 auto iface_cxt = context_add_tag(class_context{class_context::interface}, context);
127 127
128 if(!as_generator(documentation).generate(sink, cls, iface_cxt)) 128 if(!as_generator(documentation).generate(sink, cls, iface_cxt))
129 return false; 129 return false;
130 130
131 // Mark the interface with the proper native Efl_Class* getter 131 // Mark the interface with the proper native Efl_Class* getter
132 if(!as_generator(lit("[") << name_helpers::interface_native_getter_attr_name(cls) << "]\n") 132 if(!as_generator(lit("[") << name_helpers::klass_native_inherit_name(cls) << "]\n")
133 .generate(sink, attributes::unused, iface_cxt)) 133 .generate(sink, attributes::unused, iface_cxt))
134 return false; 134 return false;
135 135
136 if(!as_generator 136 if(!as_generator
137 ( 137 (
138 "public " /*<< class_type*/ "interface" /*<<*/ " " << string << " : " 138 "public " /*<< class_type*/ "interface" /*<<*/ " " << string << " : "
139 ) 139 )
140 .generate(sink, name_helpers::klass_interface_name(cls), iface_cxt)) 140 .generate(sink, name_helpers::klass_interface_name(cls), iface_cxt))
141 return false; 141 return false;
142 for(auto first = std::begin(cls.immediate_inherits) 142 for(auto first = std::begin(cls.immediate_inherits)
143 , last = std::end(cls.immediate_inherits); first != last; ++first) 143 , last = std::end(cls.immediate_inherits); first != last; ++first)
144 { 144 {
145 if(first->type != attributes::class_type::regular && first->type != attributes::class_type::abstract_) 145 if(first->type != attributes::class_type::regular && first->type != attributes::class_type::abstract_)
146 if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt)) 146 if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt))
147 return false; 147 return false;
148 } 148 }
149 149
150 if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt)) 150 if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt))
151 return false; 151 return false;
152 152
153 if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt)) 153 if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt))
154 return false; 154 return false;
155 155
156 if(!as_generator(*(scope_tab << function_declaration)).generate(sink, cls.functions, iface_cxt)) 156 if(!as_generator(*(scope_tab << function_declaration)).generate(sink, cls.functions, iface_cxt))
157 return false; 157 return false;
158 158
159 if(!as_generator(*(scope_tab << async_function_declaration)).generate(sink, cls.functions, iface_cxt)) 159 if(!as_generator(*(scope_tab << async_function_declaration)).generate(sink, cls.functions, iface_cxt))
160 return false; 160 return false;
161 161
162 if(!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt)) 162 if(!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt))
163 return false; 163 return false;
164 164
165 for (auto &&p : cls.parts) 165 for (auto &&p : cls.parts)
166 if (!as_generator( 166 if (!as_generator(
167 documentation(1) 167 documentation(1)
168 << name_helpers::klass_full_concrete_or_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n" 168 << name_helpers::klass_full_concrete_or_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n"
169 ).generate(sink, p, iface_cxt)) 169 ).generate(sink, p, iface_cxt))
170 return false; 170 return false;
171
172 if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, iface_cxt))
173 return false;
174 171
175 // End of interface declaration 172 if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, iface_cxt))
176 if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false; 173 return false;
177 174
175 // End of interface declaration
176 if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false;
178 } 177 }
179 178
180 // Events arguments go in the top namespace to avoid the Concrete suffix clutter in interface events. 179 // Events arguments go in the top namespace to avoid the Concrete suffix clutter in interface events.
@@ -276,17 +275,6 @@ struct klass
276 275
277 276
278 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false; 277 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
279
280 // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces)
281 if(!as_generator(lit("public class ") << name_helpers::interface_native_getter_attr_name(cls) << " : Efl.Eo.NativeGetterAttr\n"
282 << "{\n"
283 << scope_tab << "public override IntPtr GetEflClass()\n"
284 << scope_tab << "{\n"
285 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
286 << scope_tab << "}\n"
287 << "}\n")
288 .generate(sink, attributes::unused, concrete_cxt))
289 return false;
290 } 278 }
291 279
292 // Inheritable class 280 // Inheritable class
@@ -298,6 +286,7 @@ struct klass
298 if(!as_generator 286 if(!as_generator
299 ( 287 (
300 documentation 288 documentation
289 << "[" << name_helpers::klass_native_inherit_name(cls) << "]\n"
301 << "public " << class_type << " " << name_helpers::klass_concrete_name(cls) << " : " 290 << "public " << class_type << " " << name_helpers::klass_concrete_name(cls) << " : "
302 << (klass_full_concrete_or_interface_name % ",") // classes 291 << (klass_full_concrete_or_interface_name % ",") // classes
303 << (inherit_classes.empty() ? "" : ",") 292 << (inherit_classes.empty() ? "" : ",")
@@ -359,16 +348,8 @@ struct klass
359 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 348 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
360 } 349 }
361 350
362 std::size_t function_count = get_implementable_function_count(cls);
363
364 int function_registration_index = 0;
365 auto index_generator = [&function_registration_index]
366 {
367 return function_registration_index++;
368 };
369
370 // Native Inherit class 351 // Native Inherit class
371 if(class_type == "class") 352 //if(class_type == "class")
372 { 353 {
373 auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context); 354 auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context);
374 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls); 355 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
@@ -382,21 +363,21 @@ struct klass
382 363
383 if(!as_generator 364 if(!as_generator
384 ( 365 (
385 "public " << class_type << " " << native_inherit_name << " " << (root ? "" : (": " + base_name)) <<"{\n" 366 "public class " << native_inherit_name << " " << (root ? ": Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n"
386 << scope_tab << (root ? "protected IntPtr EoKlass { get; set; }\n" : "\n") 367 // << scope_tab << (root ? "protected IntPtr EoKlass { get; set; }\n" : "\n")
387 << scope_tab << "public " << (root ? "" : "new ") << "Efl_Op_Description[] GetEoOps()\n" 368 << scope_tab << "public " << /*(root ? "" : "new ")*/ "override " << "System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n"
388 << scope_tab << "{\n" 369 << scope_tab << "{\n"
389 << scope_tab << scope_tab << "Efl_Op_Description[] descs = new Efl_Op_Description[" << grammar::int_ << "];\n" 370 << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<Efl_Op_Description>();\n"
390 ) 371 )
391 .generate(sink, function_count, inative_cxt)) 372 .generate(sink, attributes::unused, inative_cxt))
392 return false; 373 return false;
393 374
394 // Native wrapper registration 375 // Native wrapper registration
395 if(!as_generator(*(function_registration(index_generator, cls))) 376 if(!as_generator(*(function_registration(cls)))
396 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false; 377 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
397 378
398 if(!root) 379 if(!root)
399 if(!as_generator(scope_tab << scope_tab << "descs = descs.Concat(base.GetEoOps()).ToArray();\n").generate(sink, attributes::unused, inative_cxt)) 380 if(!as_generator(scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type));\n").generate(sink, attributes::unused, inative_cxt))
400 return false; 381 return false;
401 382
402 if(!as_generator( 383 if(!as_generator(
@@ -405,32 +386,23 @@ struct klass
405 ).generate(sink, attributes::unused, inative_cxt)) 386 ).generate(sink, attributes::unused, inative_cxt))
406 return false; 387 return false;
407 388
408 if(!as_generator 389 // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces)
409 (scope_tab << "public " << (root ? "" : "new " ) << "byte class_initializer(IntPtr klass)\n" 390 if(!as_generator(
410 << scope_tab << "{\n" 391 scope_tab << "public override IntPtr GetEflClass()\n"
411 << scope_tab << scope_tab << "var descs = GetEoOps();\n" 392 << scope_tab << "{\n"
412 << scope_tab << scope_tab << "var count = descs.Length;\n" 393 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
413 << scope_tab << scope_tab << "IntPtr descs_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*count);\n" 394 << scope_tab << "}\n"
414 << scope_tab << scope_tab << "IntPtr ptr = descs_ptr;\n" 395 ).generate(sink, attributes::unused, inative_cxt))
415 << scope_tab << scope_tab << "for(int i = 0; i != count; ++i)\n" 396 return false;
416 << scope_tab << scope_tab << "{\n" 397
417 << scope_tab << scope_tab << scope_tab << "Marshal.StructureToPtr(descs[i], ptr, false);\n" 398 if(!as_generator(
418 << scope_tab << scope_tab << scope_tab << "ptr = IntPtr.Add(ptr, Marshal.SizeOf(descs[0]));\n" 399 scope_tab << "public static " << (root ? "" : "new ") << " IntPtr GetEflClassStatic()\n"
419 << scope_tab << scope_tab << "}\n" 400 << scope_tab << "{\n"
420 << scope_tab << scope_tab << "Efl_Object_Ops ops;\n" 401 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
421 << scope_tab << scope_tab << "ops.descs = descs_ptr;\n" 402 << scope_tab << "}\n"
422 << scope_tab << scope_tab << "ops.count = (UIntPtr)count;\n" 403 ).generate(sink, attributes::unused, inative_cxt))
423 << scope_tab << scope_tab << "IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));\n" 404 return false;
424 << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, ops_ptr, false);\n" 405
425 << scope_tab << scope_tab << "Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n"
426 << scope_tab << scope_tab << "EoKlass = klass;\n"
427 ).generate(sink, attributes::unused, inative_cxt)) return false;
428
429
430 if(!as_generator(scope_tab << scope_tab << "return 1;\n"
431 << scope_tab << "}\n")
432 .generate(sink, attributes::unused, inative_cxt)) return false;
433 //
434 // Native method definitions 406 // Native method definitions
435 if(!as_generator(*(native_function_definition(cls))) 407 if(!as_generator(*(native_function_definition(cls)))
436 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false; 408 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
@@ -451,8 +423,9 @@ struct klass
451 bool root = !helpers::has_regular_ancestor(cls); 423 bool root = !helpers::has_regular_ancestor(cls);
452 bool is_inherit = is_inherit_context(context); 424 bool is_inherit = is_inherit_context(context);
453 425
454 std::string class_getter = "return Efl.Eo.Globals.efl_class_get(handle);"; 426 std::string class_getter = name_helpers::klass_get_name(cls) + "()";
455 std::string native_inherit_full_name = name_helpers::klass_full_native_inherit_name(cls); 427 std::string native_inherit_full_name = name_helpers::klass_full_native_inherit_name(cls);
428 auto inherit_name = name_helpers::klass_concrete_name(cls);
456 429
457 // The klass field is static but there is no problem if multiple C# classes inherit from this generated one 430 // The klass field is static but there is no problem if multiple C# classes inherit from this generated one
458 // as it is just a simple wrapper, forwarding the Eo calls either to the user API (where C#'s virtual method 431 // as it is just a simple wrapper, forwarding the Eo calls either to the user API (where C#'s virtual method
@@ -464,7 +437,6 @@ struct klass
464 << scope_tab << "public " << (root ? "" : "new ") << "static " << native_inherit_full_name << " nativeInherit = new " << native_inherit_full_name << "();\n" 437 << scope_tab << "public " << (root ? "" : "new ") << "static " << native_inherit_full_name << " nativeInherit = new " << native_inherit_full_name << "();\n"
465 ).generate(sink, attributes::unused, context)) 438 ).generate(sink, attributes::unused, context))
466 return false; 439 return false;
467 class_getter = "return klass;";
468 } 440 }
469 441
470 std::string raw_klass_modifier; 442 std::string raw_klass_modifier;
@@ -477,7 +449,10 @@ struct klass
477 scope_tab << "///<summary>Pointer to the native class description.</summary>\n" 449 scope_tab << "///<summary>Pointer to the native class description.</summary>\n"
478 << scope_tab << "public " << raw_klass_modifier << "System.IntPtr NativeClass {\n" 450 << scope_tab << "public " << raw_klass_modifier << "System.IntPtr NativeClass {\n"
479 << scope_tab << scope_tab << "get {\n" 451 << scope_tab << scope_tab << "get {\n"
480 << scope_tab << scope_tab << scope_tab << class_getter << "\n" //return klass; }\n" 452 << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof (" << inherit_name << "))\n"
453 << scope_tab << scope_tab << scope_tab << scope_tab << "return " << native_inherit_full_name << ".GetEflClassStatic();\n"
454 << scope_tab << scope_tab << scope_tab << "else\n"
455 << scope_tab << scope_tab << scope_tab << scope_tab << "return Efl.Eo.Globals.klasses[((object)this).GetType()];\n"
481 << scope_tab << scope_tab << "}\n" 456 << scope_tab << scope_tab << "}\n"
482 << scope_tab << "}\n" 457 << scope_tab << "}\n"
483 ).generate(sink, attributes::unused, context)) 458 ).generate(sink, attributes::unused, context))
@@ -534,7 +509,8 @@ struct klass
534 scope_tab << "///<summary>Creates a new instance.</summary>\n" 509 scope_tab << "///<summary>Creates a new instance.</summary>\n"
535 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n" 510 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
536 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n" 511 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
537 << 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" 512 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : "
513 "base(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
538 << scope_tab << "{\n" 514 << scope_tab << "{\n"
539 << scope_tab << scope_tab << "if (init_cb != null) {\n" 515 << scope_tab << scope_tab << "if (init_cb != null) {\n"
540 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n" 516 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
@@ -543,7 +519,7 @@ struct klass
543 << scope_tab << "}\n" 519 << scope_tab << "}\n"
544 520
545 << scope_tab << "///<summary>Internal constructor to forward the wrapper initialization to the root class.</summary>\n" 521 << scope_tab << "///<summary>Internal constructor to forward the wrapper initialization to the root class.</summary>\n"
546 << scope_tab << "protected " << inherit_name << "(Efl.Eo.Globals.class_initializer class_initializer, String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent, ref IntPtr target_klass) : base(class_initializer, klass_name, base_klass, managed_type, parent, ref target_klass) {}\n" 522 << scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent) : base(klass_name, base_klass, managed_type, parent) {}\n"
547 523
548 << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n" 524 << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
549 << scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n" 525 << scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
@@ -559,7 +535,7 @@ struct klass
559 scope_tab << "///<summary>Creates a new instance.</summary>\n" 535 scope_tab << "///<summary>Creates a new instance.</summary>\n"
560 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n" 536 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
561 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n" 537 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
562 << 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" 538 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : this(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
563 << scope_tab << "{\n" 539 << scope_tab << "{\n"
564 << scope_tab << scope_tab << "if (init_cb != null) {\n" 540 << scope_tab << scope_tab << "if (init_cb != null) {\n"
565 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n" 541 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
@@ -567,22 +543,22 @@ struct klass
567 << scope_tab << scope_tab << "FinishInstantiation();\n" 543 << scope_tab << scope_tab << "FinishInstantiation();\n"
568 << scope_tab << "}\n" 544 << scope_tab << "}\n"
569 545
570 << scope_tab << "protected " << inherit_name << "(Efl.Eo.Globals.class_initializer class_initializer, String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent, ref IntPtr target_klass)\n" 546 << scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
571 << scope_tab << "{\n" 547 << scope_tab << "{\n"
572 << scope_tab << scope_tab << "inherited = this.GetType() != managed_type;\n" 548 << scope_tab << scope_tab << "inherited = ((object)this).GetType() != managed_type;\n"
573 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n" 549 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
574 << scope_tab << scope_tab << "if (inherited) {\n" 550 << scope_tab << scope_tab << "if (inherited) {\n"
575 << scope_tab << scope_tab << scope_tab << "if (target_klass == System.IntPtr.Zero) {\n" 551 << scope_tab << scope_tab << scope_tab << "if (!Efl.Eo.Globals.klasses.ContainsKey(((object)this).GetType())) {\n"
576 << scope_tab << scope_tab << scope_tab << scope_tab << "lock (klassAllocLock) {\n" 552 << scope_tab << scope_tab << scope_tab << scope_tab << "lock (klassAllocLock) {\n"
577 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (target_klass == System.IntPtr.Zero) {\n" 553 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "actual_klass = Efl.Eo.Globals.register_class(klass_name, base_klass, ((object)this).GetType());\n"
578 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "target_klass = Efl.Eo.Globals.register_class(class_initializer, klass_name, base_klass, this.GetType());\n" 554 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (actual_klass == System.IntPtr.Zero) {\n"
579 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (target_klass == System.IntPtr.Zero) {\n"
580 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "throw new System.InvalidOperationException(\"Failed to initialize class '" << inherit_name << "'\");\n" 555 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "throw new System.InvalidOperationException(\"Failed to initialize class '" << inherit_name << "'\");\n"
581 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n" 556 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
582 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n" 557 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.klasses[((object)this).GetType()] = actual_klass;\n"
583 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n" 558 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
584 << scope_tab << scope_tab << scope_tab << "}\n" 559 << scope_tab << scope_tab << scope_tab << "}\n"
585 << scope_tab << scope_tab << scope_tab << "actual_klass = target_klass;\n" 560 << scope_tab << scope_tab << scope_tab << "else\n"
561 << scope_tab << scope_tab << scope_tab << scope_tab << "actual_klass = Efl.Eo.Globals.klasses[((object)this).GetType()];\n"
586 << scope_tab << scope_tab << "}\n" 562 << scope_tab << scope_tab << "}\n"
587 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n" 563 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
588 << scope_tab << scope_tab << "register_event_proxies();\n" 564 << scope_tab << scope_tab << "register_event_proxies();\n"
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index a5cf5c0..8910447 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -379,18 +379,6 @@ inline std::string klass_get_full_name(T const& clsname)
379 return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname); 379 return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname);
380} 380}
381 381
382template<typename T>
383inline std::string interface_native_getter_attr_name(T const& clsname)
384{
385 return klass_interface_name(clsname) + "NativeGetterAttr";
386}
387
388template<typename T>
389inline std::string interface_native_getter_attr_full_name(T const& clsname)
390{
391 return klass_full_interface_name(clsname) + "NativeGetterAttr";
392}
393
394// Events 382// Events
395inline std::string managed_event_name(std::string const& name) 383inline std::string managed_event_name(std::string const& name)
396{ 384{
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index fee5a23..fe96088 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -150,11 +150,14 @@ public class Globals {
150 [DllImport(efl.Libs.Eo)] public static extern IntPtr 150 [DllImport(efl.Libs.Eo)] public static extern IntPtr
151 efl_object_legacy_only_event_description_get([MarshalAs(UnmanagedType.LPStr)] String name); 151 efl_object_legacy_only_event_description_get([MarshalAs(UnmanagedType.LPStr)] String name);
152 152
153 public static System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr> klasses
154 = new System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr>();
155
153 public const int RTLD_NOW = 2; 156 public const int RTLD_NOW = 2;
154 157
155 public delegate byte class_initializer(IntPtr klass); 158 public delegate byte class_initializer(IntPtr klass);
156 159
157 public static IntPtr register_class(class_initializer initializer, String class_name, IntPtr base_klass, System.Type type) 160 public static IntPtr register_class(String class_name, IntPtr base_klass, System.Type type)
158 { 161 {
159 ClassDescription description; 162 ClassDescription description;
160 description.version = 2; // EO_VERSION 163 description.version = 2; // EO_VERSION
@@ -165,39 +168,113 @@ public class Globals {
165 description.class_constructor = IntPtr.Zero; 168 description.class_constructor = IntPtr.Zero;
166 description.class_destructor = IntPtr.Zero; 169 description.class_destructor = IntPtr.Zero;
167 170
168 if(initializer != null) 171 class_initializer init = (IntPtr kls) =>
169 description.class_initializer = Marshal.GetFunctionPointerForDelegate(initializer); 172 {
173 return Globals.class_initializer_call(kls, type);
174 };
175
176 description.class_initializer = Marshal.GetFunctionPointerForDelegate(init);
170 177
171 IntPtr description_ptr = Eina.MemoryNative.Alloc(Marshal.SizeOf(description)); 178 IntPtr description_ptr = Eina.MemoryNative.Alloc(Marshal.SizeOf(description));
172 Marshal.StructureToPtr(description, description_ptr, false); 179 Marshal.StructureToPtr(description, description_ptr, false);
173 180
174 var interface_list = EoG.get_efl_interfaces(type); 181 var interface_list = EoG.get_efl_interfaces(type);
175 182
183 System.Console.WriteLine ("Interafaces: {0}", interface_list.Count);
184
176 Eina.Log.Debug("Going to register!"); 185 Eina.Log.Debug("Going to register!");
177 IntPtr klass = EoG.call_efl_class_new(description_ptr, base_klass, interface_list); 186 IntPtr klass = EoG.call_efl_class_new(description_ptr, base_klass, interface_list);
178 if(klass == IntPtr.Zero) 187 if(klass == IntPtr.Zero)
188 {
179 Eina.Log.Error("klass was not registered"); 189 Eina.Log.Error("klass was not registered");
190 Console.WriteLine("klass was not registered");
191 }
180 else 192 else
181 Eina.Log.Debug("Registered class successfully"); 193 Eina.Log.Debug("Registered class successfully");
182 return klass; 194 return klass;
183 } 195 }
184 public static List<IntPtr> get_efl_interfaces(System.Type type) 196 public static List<IntPtr> get_efl_interfaces(System.Type type)
185 { 197 {
198 System.Type base_type = type.BaseType;
199
186 var ifaces_lst = new List<IntPtr>(); 200 var ifaces_lst = new List<IntPtr>();
201 var base_ifaces = base_type.GetInterfaces();
187 var ifaces = type.GetInterfaces(); 202 var ifaces = type.GetInterfaces();
188 foreach (var iface in ifaces) 203 foreach (var iface in ifaces)
189 { 204 {
190 var attrs = System.Attribute.GetCustomAttributes(iface); 205 if (!System.Array.Exists(base_ifaces, element => element == iface))
191 foreach (var attr in attrs)
192 { 206 {
193 if (attr is Efl.Eo.NativeGetterAttr) { 207 var attrs = System.Attribute.GetCustomAttributes(iface);
194 ifaces_lst.Add(((Efl.Eo.NativeGetterAttr)attr).GetEflClass()); 208 foreach (var attr in attrs)
209 {
210 if (attr is Efl.Eo.NativeClass) {
211 ifaces_lst.Add(((Efl.Eo.NativeClass)attr).GetEflClass());
195 break; 212 break;
196 } 213 }
214 }
197 } 215 }
198 } 216 }
199 return ifaces_lst; 217 return ifaces_lst;
200 } 218 }
219 private static Efl.Eo.NativeClass get_native_class(System.Type type)
220 {
221 var attrs = System.Attribute.GetCustomAttributes(type);
222 foreach (var attr in attrs)
223 {
224 if (attr is Efl.Eo.NativeClass) {
225 return (Efl.Eo.NativeClass)attr;
226 }
227 }
228 return null;
229 }
230 public static byte class_initializer_call(IntPtr klass, System.Type type)
231 {
232 Console.WriteLine("class_intiailizer_call 0x{1} {0}", type, klass);
233 Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType);
234
235 if (nativeClass != null)
236 {
237 Console.WriteLine("nativeClass != null");
238 var descs = nativeClass.GetEoOps(type);
239 var count = descs.Count;
240
241 var all_interfaces = type.GetInterfaces();
242 var base_interfaces = type.BaseType.GetInterfaces();
243 foreach (var iface in all_interfaces)
244 {
245 if (!System.Array.Exists(base_interfaces, element => element == iface))
246 {
247 var nc = get_native_class(iface);
248 if(nc != null)
249 {
250 var moredescs = nc.GetEoOps(type);
251 Console.WriteLine("adding {0} more descs to registration", moredescs.Count);
252 descs.AddRange(moredescs);
253 count = descs.Count;
254 }
255 }
256 }
257
258 IntPtr descs_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*count);
259 IntPtr ptr = descs_ptr;
260 for(int i = 0; i != count; ++i)
261 {
262 Marshal.StructureToPtr(descs[i], ptr, false);
263 ptr = IntPtr.Add(ptr, Marshal.SizeOf(descs[0]));
264 }
265 Efl_Object_Ops ops;
266 ops.descs = descs_ptr;
267 ops.count = (UIntPtr)count;
268 IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));
269 Marshal.StructureToPtr(ops, ops_ptr, false);
270 Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);
271 //EoKlass = klass;
272 }
273 else
274 Console.WriteLine("nativeClass == null");
275
276 return 1;
277 }
201 public static IntPtr call_efl_class_new(IntPtr desc, IntPtr bk, List<IntPtr> il = null) 278 public static IntPtr call_efl_class_new(IntPtr desc, IntPtr bk, List<IntPtr> il = null)
202 { 279 {
203 IntPtr nul = IntPtr.Zero; 280 IntPtr nul = IntPtr.Zero;
@@ -259,11 +336,17 @@ public class Globals {
259 public static IntPtr instantiate_start(IntPtr klass, Efl.Object parent) 336 public static IntPtr instantiate_start(IntPtr klass, Efl.Object parent)
260 { 337 {
261 Eina.Log.Debug($"Instantiating from klass 0x{klass.ToInt64():x}"); 338 Eina.Log.Debug($"Instantiating from klass 0x{klass.ToInt64():x}");
339 Console.WriteLine($"Instantiating from klass 0x{klass.ToInt64():x}");
262 System.IntPtr parent_ptr = System.IntPtr.Zero; 340 System.IntPtr parent_ptr = System.IntPtr.Zero;
263 if(parent != null) 341 if(parent != null)
264 parent_ptr = parent.NativeHandle; 342 parent_ptr = parent.NativeHandle;
265 343
266 System.IntPtr eo = Efl.Eo.Globals._efl_add_internal_start("file", 0, klass, parent_ptr, 1, 0); 344 System.IntPtr eo = Efl.Eo.Globals._efl_add_internal_start("file", 0, klass, parent_ptr, 1, 0);
345 if (eo == System.IntPtr.Zero)
346 {
347 throw new Exception("Instantiation failed");
348 }
349
267 Console.WriteLine($"Eo instance right after internal_start 0x{eo.ToInt64():x} with refcount {Efl.Eo.Globals.efl_ref_count(eo)}"); 350 Console.WriteLine($"Eo instance right after internal_start 0x{eo.ToInt64():x} with refcount {Efl.Eo.Globals.efl_ref_count(eo)}");
268 Console.WriteLine($"Parent was 0x{parent_ptr.ToInt64()}"); 351 Console.WriteLine($"Parent was 0x{parent_ptr.ToInt64()}");
269 return eo; 352 return eo;
@@ -415,9 +498,10 @@ public static class Config
415 AllowMultiple = false, 498 AllowMultiple = false,
416 Inherited = true) 499 Inherited = true)
417] 500]
418public abstract class NativeGetterAttr : System.Attribute 501public abstract class NativeClass : System.Attribute
419{ 502{
420 public abstract IntPtr GetEflClass(); 503 public abstract IntPtr GetEflClass();
504 public abstract System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type);
421} 505}
422 506
423public interface IWrapper 507public interface IWrapper
diff --git a/src/tests/efl_mono/Inheritance.cs b/src/tests/efl_mono/Inheritance.cs
index 30ca391..344c6da 100644
--- a/src/tests/efl_mono/Inheritance.cs
+++ b/src/tests/efl_mono/Inheritance.cs
@@ -24,11 +24,13 @@ class TestInheritance
24 { 24 {
25 override public void IntOut (int x, out int y) 25 override public void IntOut (int x, out int y)
26 { 26 {
27 Console.WriteLine("IntOut");
27 y = 10*x; 28 y = 10*x;
28 } 29 }
29 30
30 public string StringshareTest (string i) 31 public string StringshareTest (string i)
31 { 32 {
33 Console.WriteLine("StringshareTest");
32 return "Hello World"; 34 return "Hello World";
33 } 35 }
34 } 36 }
@@ -44,8 +46,8 @@ class TestInheritance
44 { 46 {
45 var obj = new Inherit2(); 47 var obj = new Inherit2();
46 int i = Dummy.InheritHelper.ReceiveDummyAndCallIntOut(obj); 48 int i = Dummy.InheritHelper.ReceiveDummyAndCallIntOut(obj);
47 string s = Dummy.InheritHelper.ReceiveDummyAndCallInStringshare(obj);
48 Test.AssertEquals (50, i); 49 Test.AssertEquals (50, i);
50 string s = Dummy.InheritHelper.ReceiveDummyAndCallInStringshare(obj);
49 Test.AssertEquals ("Hello World", s); 51 Test.AssertEquals ("Hello World", s);
50 } 52 }
51} 53}