felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=adc2e674af528c01ca5bb11d56edc475bce5cc4d

commit adc2e674af528c01ca5bb11d56edc475bce5cc4d
Author: Felipe Magno de Almeida <fel...@expertisesolutions.com.br>
Date:   Thu Jan 17 21:33:09 2019 +0900

    eolian-mono: Add interface registration to inherited classes
    
    Summary: Depends on D7635, D7634
    
    Reviewers: woohyun, bu5hm4n, segfaultxavi, lauromoura
    
    Reviewed By: woohyun
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D7636
---
 .../eolian_mono/eolian/mono/function_definition.hh |  10 +-
 .../eolian/mono/function_registration.hh           |  30 ++--
 src/bin/eolian_mono/eolian/mono/klass.hh           | 178 +++++++++------------
 src/bin/eolian_mono/eolian/mono/name_helpers.hh    |  12 --
 src/bindings/mono/eo_mono/iwrapper.cs              | 104 ++++++++++--
 src/tests/efl_mono/Inheritance.cs                  |   4 +-
 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 763bbc451f..2d9e1b5d5a 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
     
if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type),
 f.return_type, context))
       return false;
 
-    std::string klass_inherit_name = name_helpers::klass_inherit_name(*klass);
+    std::string klass_cast_name;
+    if (klass->type != attributes::class_type::interface_)
+      klass_cast_name = name_helpers::klass_inherit_name(*klass);
+    else
+      klass_cast_name = name_helpers::klass_interface_name(*klass);
 
     if(!as_generator
        (scope_tab
@@ -89,7 +93,7 @@ struct native_function_definition_generator
         << scope_tab << scope_tab << "if(wrapper != null) {\n"
         << scope_tab << scope_tab << scope_tab << 
eolian_mono::native_function_definition_preamble()
         << scope_tab << scope_tab << scope_tab << "try {\n"
-        << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != 
" void" ? "_ret_var = " : "") << "((" << klass_inherit_name << ")wrapper)." << 
string
+        << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != 
" void" ? "_ret_var = " : "") << "((" << klass_cast_name << ")wrapper)." << 
string
         << "(" << (native_argument_invocation % ", ") << ");\n"
         << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n"
         << 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
         << eolian_mono::native_function_definition_epilogue(*klass)
         << scope_tab << scope_tab << "} else {\n"
         << scope_tab << scope_tab << scope_tab << (return_type != " void" ? 
"return " : "") << string
-        << "(Efl.Eo.Globals.efl_super(obj, " << "EoKlass)" << *(", " << 
argument) << ");\n"
+        << "(Efl.Eo.Globals.efl_super(obj, " << "GetEflClass())" << *(", " << 
argument) << ");\n"
         << scope_tab << scope_tab << "}\n"
         << scope_tab << "}\n"
        )
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh 
b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index 0b8da4a05a..78f2d718c7 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 @@
 
 namespace eolian_mono {
 
-template <typename I>
+// template <typename I>
 struct function_registration_generator
 {
-  I index_generator;
+  // I index_generator;
   attributes::klass_def const* klass;
   
   template <typename OutputIterator, typename Context>
@@ -34,7 +34,7 @@ struct function_registration_generator
       return true;
     else
       {
-    auto index = index_generator();
+    // auto index = index_generator();
 
     if(!as_generator(
             scope_tab << scope_tab << f.c_name << "_static_delegate = new " << 
f.c_name << "_delegate(" <<
@@ -43,12 +43,13 @@ struct function_registration_generator
       return false;
 
     if(!as_generator
+       (scope_tab << scope_tab << "descs.Add(new Efl_Op_Description() {"
 #ifdef _WIN32
-       (scope_tab << scope_tab << "descs[" << index << "].api_func = 
Marshal.StringToHGlobalAnsi(\"" << string << "\");\n"
+        << "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")"
 #else
-       (scope_tab << scope_tab << "descs[" << index << "].api_func = 
Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" << string << "\");\n"
+        << "api_func = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" 
<< string << "\")"
 #endif
-        << scope_tab << scope_tab << "descs[" << index << "].func = 
Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate);\n"
+        ", func = Marshal.GetFunctionPointerForDelegate(" << string << 
"_static_delegate)});\n"
        )
        .generate(sink, std::make_tuple(f.c_name, f.c_name), context))
       return false;
@@ -59,10 +60,9 @@ struct function_registration_generator
   
 struct function_registration_parameterized
 {
-  template <typename I>
-  function_registration_generator<I> operator()(I i, attributes::klass_def 
const& klass) const
+  function_registration_generator operator()(attributes::klass_def const& 
klass) const
   {
-    return {i, &klass};
+    return {&klass};
   }
 } const function_registration;
 
@@ -70,15 +70,15 @@ struct function_registration_parameterized
 
 namespace efl { namespace eolian { namespace grammar {
 
-template <typename I>
-struct is_eager_generator< ::eolian_mono::function_registration_generator<I>> 
: std::true_type {};
-template <typename I>
-struct is_generator< ::eolian_mono::function_registration_generator<I>> : 
std::true_type {};
+template <>
+struct is_eager_generator< ::eolian_mono::function_registration_generator> : 
std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::function_registration_generator> : 
std::true_type {};
 
 namespace type_traits {
 
-template <typename I>
-struct attributes_needed< ::eolian_mono::function_registration_generator<I>> : 
std::integral_constant<int, 1> {};
+template <>
+struct attributes_needed< ::eolian_mono::function_registration_generator> : 
std::integral_constant<int, 1> {};
 }
       
 } } }
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh 
b/src/bin/eolian_mono/eolian/mono/klass.hh
index 5dc22f5d38..c3d430e24c 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
      // Interface class
      if(class_type == "interface")
      {
-     auto iface_cxt = context_add_tag(class_context{class_context::interface}, 
context);
+       auto iface_cxt = 
context_add_tag(class_context{class_context::interface}, context);
 
-     if(!as_generator(documentation).generate(sink, cls, iface_cxt))
-       return false;
+       if(!as_generator(documentation).generate(sink, cls, iface_cxt))
+         return false;
 
-     // Mark the interface with the proper native Efl_Class* getter
-     if(!as_generator(lit("[") << 
name_helpers::interface_native_getter_attr_name(cls) << "]\n")
-        .generate(sink, attributes::unused, iface_cxt))
-       return false;
+       // Mark the interface with the proper native Efl_Class* getter
+       if(!as_generator(lit("[") << 
name_helpers::klass_native_inherit_name(cls) << "]\n")
+          .generate(sink, attributes::unused, iface_cxt))
+         return false;
 
-     if(!as_generator
+       if(!as_generator
         (
          "public " /*<< class_type*/ "interface" /*<<*/ " " << string << " : "
          )
         .generate(sink, name_helpers::klass_interface_name(cls), iface_cxt))
-       return false;
-     for(auto first = std::begin(cls.immediate_inherits)
-           , last = std::end(cls.immediate_inherits); first != last; ++first)
-       {
-          if(first->type != attributes::class_type::regular && first->type != 
attributes::class_type::abstract_)
-            if(!as_generator("\n" << scope_tab << string << " 
,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt))
-              return false;
-       }
+         return false;
+       for(auto first = std::begin(cls.immediate_inherits)
+             , last = std::end(cls.immediate_inherits); first != last; ++first)
+         {
+            if(first->type != attributes::class_type::regular && first->type 
!= attributes::class_type::abstract_)
+              if(!as_generator("\n" << scope_tab << string << " 
,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt))
+                return false;
+         }
 
-     if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, 
IDisposable").generate(sink, attributes::unused, iface_cxt))
-       return false;
+       if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, 
IDisposable").generate(sink, attributes::unused, iface_cxt))
+         return false;
 
-     if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt))
-       return false;
+       if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt))
+         return false;
 
-     if(!as_generator(*(scope_tab << function_declaration)).generate(sink, 
cls.functions, iface_cxt))
-       return false;
+       if(!as_generator(*(scope_tab << function_declaration)).generate(sink, 
cls.functions, iface_cxt))
+         return false;
 
-     if(!as_generator(*(scope_tab << 
async_function_declaration)).generate(sink, cls.functions, iface_cxt))
-       return false;
+       if(!as_generator(*(scope_tab << 
async_function_declaration)).generate(sink, cls.functions, iface_cxt))
+         return false;
 
-     if(!as_generator(*(event_declaration)).generate(sink, cls.events, 
iface_cxt))
-       return false;
+       if(!as_generator(*(event_declaration)).generate(sink, cls.events, 
iface_cxt))
+         return false;
 
-     for (auto &&p : cls.parts)
-       if (!as_generator(
+       for (auto &&p : cls.parts)
+         if (!as_generator(
               documentation(1)
               << name_helpers::klass_full_concrete_or_interface_name(p.klass) 
<< " " << utils::capitalize(p.name) << "{ get;}\n"
             ).generate(sink, p, iface_cxt))
-         return false;
-
-     if (!as_generator(*(property_wrapper_definition)).generate(sink, 
cls.properties, iface_cxt))
-       return false;
+           return false;
 
-     // End of interface declaration
-     if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) 
return false;
+       if (!as_generator(*(property_wrapper_definition)).generate(sink, 
cls.properties, iface_cxt))
+         return false;
 
+       // End of interface declaration
+       if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) 
return false;
      }
 
      // Events arguments go in the top namespace to avoid the Concrete suffix 
clutter in interface events.
@@ -276,17 +275,6 @@ struct klass
 
 
          if(!as_generator("}\n").generate(sink, attributes::unused, 
concrete_cxt)) return false;
-
-         // Attribute getter of the native 'Efl_Class *' handle (for proper 
inheritance from additional explicit interfaces)
-         if(!as_generator(lit("public class ") << 
name_helpers::interface_native_getter_attr_name(cls) << " : 
Efl.Eo.NativeGetterAttr\n"
-              << "{\n"
-              << scope_tab << "public override IntPtr GetEflClass()\n"
-              << scope_tab << "{\n"
-              << scope_tab << scope_tab << "return " << 
name_helpers::klass_get_full_name(cls) << "();\n"
-              << scope_tab << "}\n"
-              << "}\n")
-            .generate(sink, attributes::unused, concrete_cxt))
-           return false;
        }
 
      // Inheritable class
@@ -298,6 +286,7 @@ struct klass
         if(!as_generator
             (
              documentation
+             << "[" << name_helpers::klass_native_inherit_name(cls) << "]\n"
              << "public " << class_type << " " << 
name_helpers::klass_concrete_name(cls) << " : "
              << (klass_full_concrete_or_interface_name % ",") // classes
              << (inherit_classes.empty() ? "" : ",")
@@ -359,16 +348,8 @@ struct klass
          if(!as_generator("}\n").generate(sink, attributes::unused, 
inherit_cxt)) return false;
        }
 
-     std::size_t function_count = get_implementable_function_count(cls);
-
-     int function_registration_index = 0;
-     auto index_generator = [&function_registration_index]
-       {
-         return function_registration_index++;
-       };
-     
      // Native Inherit class
-     if(class_type == "class")
+     //if(class_type == "class")
        {
          auto inative_cxt = 
context_add_tag(class_context{class_context::inherit_native}, context);
          auto native_inherit_name = 
name_helpers::klass_native_inherit_name(cls);
@@ -382,21 +363,21 @@ struct klass
 
          if(!as_generator
             (
-             "public " << class_type << " " << native_inherit_name << " " << 
(root ? "" : (": " + base_name)) <<"{\n"
-             << scope_tab << (root ? "protected IntPtr EoKlass { get; set; 
}\n" : "\n")
-             << scope_tab << "public " << (root ? "" : "new ") << 
"Efl_Op_Description[] GetEoOps()\n"
+             "public class " << native_inherit_name << " " << (root ? ": 
Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n"
+             // << scope_tab << (root ? "protected IntPtr EoKlass { get; set; 
}\n" : "\n")
+             << scope_tab << "public " << /*(root ? "" : "new ")*/ "override " 
<< "System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type 
type)\n"
              << scope_tab << "{\n"
-             << scope_tab << scope_tab << "Efl_Op_Description[] descs = new 
Efl_Op_Description[" << grammar::int_ << "];\n"
+             << scope_tab << scope_tab << "var descs = new 
System.Collections.Generic.List<Efl_Op_Description>();\n"
             )
-            .generate(sink, function_count, inative_cxt))
+            .generate(sink, attributes::unused, inative_cxt))
            return false;
 
          // Native wrapper registration
-         if(!as_generator(*(function_registration(index_generator, cls)))
+         if(!as_generator(*(function_registration(cls)))
             .generate(sink, helpers::get_all_implementable_methods(cls), 
inative_cxt)) return false;
 
          if(!root)
-           if(!as_generator(scope_tab << scope_tab << "descs = 
descs.Concat(base.GetEoOps()).ToArray();\n").generate(sink, attributes::unused, 
inative_cxt))
+           if(!as_generator(scope_tab << scope_tab << 
"descs.AddRange(base.GetEoOps(type));\n").generate(sink, attributes::unused, 
inative_cxt))
              return false;
 
          if(!as_generator(
@@ -405,32 +386,23 @@ struct klass
             ).generate(sink, attributes::unused, inative_cxt))
            return false;
 
-         if(!as_generator
-            (scope_tab << "public " << (root ? "" : "new " ) << "byte 
class_initializer(IntPtr klass)\n"
-             << scope_tab << "{\n"
-             << scope_tab << scope_tab << "var descs = GetEoOps();\n"
-             << scope_tab << scope_tab << "var count = descs.Length;\n"
-             << scope_tab << scope_tab << "IntPtr descs_ptr = 
Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*count);\n"
-             << scope_tab << scope_tab << "IntPtr ptr = descs_ptr;\n"
-             << scope_tab << scope_tab << "for(int i = 0; i != count; ++i)\n"
-             << scope_tab << scope_tab << "{\n"
-             << scope_tab << scope_tab << scope_tab << 
"Marshal.StructureToPtr(descs[i], ptr, false);\n"
-             << scope_tab << scope_tab << scope_tab << "ptr = IntPtr.Add(ptr, 
Marshal.SizeOf(descs[0]));\n"
-             << scope_tab << scope_tab << "}\n"
-             << scope_tab << scope_tab << "Efl_Object_Ops ops;\n"
-             << scope_tab << scope_tab << "ops.descs = descs_ptr;\n"
-             << scope_tab << scope_tab << "ops.count = (UIntPtr)count;\n"
-             << scope_tab << scope_tab << "IntPtr ops_ptr = 
Marshal.AllocHGlobal(Marshal.SizeOf(ops));\n"
-             << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, 
ops_ptr, false);\n"
-             << scope_tab << scope_tab << 
"Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n"
-             << scope_tab << scope_tab << "EoKlass = klass;\n"
-            ).generate(sink, attributes::unused, inative_cxt)) return false;
-
-
-         if(!as_generator(scope_tab << scope_tab << "return 1;\n"
-                          << scope_tab << "}\n")
-            .generate(sink, attributes::unused, inative_cxt)) return false;
-         //
+         // Attribute getter of the native 'Efl_Class *' handle (for proper 
inheritance from additional explicit interfaces)
+         if(!as_generator(
+                 scope_tab << "public override IntPtr GetEflClass()\n"
+              << scope_tab << "{\n"
+              << scope_tab << scope_tab << "return " << 
name_helpers::klass_get_full_name(cls) << "();\n"
+              << scope_tab << "}\n"
+           ).generate(sink, attributes::unused, inative_cxt))
+           return false;
+
+         if(!as_generator(
+              scope_tab << "public static " << (root ? "" : "new ") << " 
IntPtr GetEflClassStatic()\n"
+              << scope_tab << "{\n"
+              << scope_tab << scope_tab << "return " << 
name_helpers::klass_get_full_name(cls) << "();\n"
+              << scope_tab << "}\n"
+           ).generate(sink, attributes::unused, inative_cxt))
+           return false;
+         
          // Native method definitions
          if(!as_generator(*(native_function_definition(cls)))
             .generate(sink, helpers::get_all_implementable_methods(cls), 
inative_cxt)) return false;
@@ -451,8 +423,9 @@ struct klass
      bool root = !helpers::has_regular_ancestor(cls);
      bool is_inherit = is_inherit_context(context);
 
-     std::string class_getter = "return Efl.Eo.Globals.efl_class_get(handle);";
+     std::string class_getter = name_helpers::klass_get_name(cls) + "()";
      std::string native_inherit_full_name = 
name_helpers::klass_full_native_inherit_name(cls);
+     auto inherit_name = name_helpers::klass_concrete_name(cls);
 
      // The klass field is static but there is no problem if multiple C# 
classes inherit from this generated one
      // 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
              << scope_tab << "public " << (root ? "" : "new ") << "static " << 
native_inherit_full_name << " nativeInherit = new " << native_inherit_full_name 
<< "();\n"
              ).generate(sink, attributes::unused, context))
             return false;
-          class_getter = "return klass;";
        }
 
      std::string raw_klass_modifier;
@@ -477,7 +449,10 @@ struct klass
                 scope_tab << "///<summary>Pointer to the native class 
description.</summary>\n"
                 << scope_tab << "public " << raw_klass_modifier << 
"System.IntPtr NativeClass {\n"
                 << scope_tab << scope_tab << "get {\n"
-                << scope_tab << scope_tab << scope_tab << class_getter << "\n" 
//return klass; }\n"
+                << scope_tab << scope_tab << scope_tab << "if 
(((object)this).GetType() == typeof (" << inherit_name << "))\n"
+                << scope_tab << scope_tab << scope_tab << scope_tab << "return 
" << native_inherit_full_name << ".GetEflClassStatic();\n"
+                << scope_tab << scope_tab << scope_tab << "else\n"
+                << scope_tab << scope_tab << scope_tab << scope_tab << "return 
Efl.Eo.Globals.klasses[((object)this).GetType()];\n"
                 << scope_tab << scope_tab << "}\n"
                 << scope_tab << "}\n"
             ).generate(sink, attributes::unused, context))
@@ -534,7 +509,8 @@ struct klass
                      scope_tab << "///<summary>Creates a new 
instance.</summary>\n"
                      << scope_tab << "///<param name=\"parent\">Parent 
instance.</param>\n"
                      << scope_tab << "///<param name=\"init_cb\">Delegate to 
call constructing methods that should be run inside the constructor.</param>\n"
-                     << 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"
+                     << scope_tab << "public " << inherit_name << "(Efl.Object 
parent = null, ConstructingMethod init_cb=null) : "
+                     "base(\"" << inherit_name << "\", " << 
name_helpers::klass_get_name(cls) <<  "(), typeof(" << inherit_name << "), 
parent)\n"
                      << scope_tab << "{\n"
                      << scope_tab << scope_tab << "if (init_cb != null) {\n"
                      << scope_tab << scope_tab << scope_tab << 
"init_cb(this);\n"
@@ -543,7 +519,7 @@ struct klass
                      << scope_tab << "}\n"
 
                      << scope_tab << "///<summary>Internal constructor to 
forward the wrapper initialization to the root class.</summary>\n"
-                     << 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"
+                     << 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"
 
                      << scope_tab << "///<summary>Constructs an instance from 
a native pointer.</summary>\n"
                      << scope_tab << "public " << inherit_name << 
"(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
@@ -559,7 +535,7 @@ struct klass
              scope_tab << "///<summary>Creates a new instance.</summary>\n"
              << scope_tab << "///<param name=\"parent\">Parent 
instance.</param>\n"
              << scope_tab << "///<param name=\"init_cb\">Delegate to call 
constructing methods that should be run inside the constructor.</param>\n"
-             << 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"
+             << 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"
              << scope_tab << "{\n"
              << scope_tab << scope_tab << "if (init_cb != null) {\n"
              << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
@@ -567,22 +543,22 @@ struct klass
              << scope_tab << scope_tab << "FinishInstantiation();\n"
              << scope_tab << "}\n"
 
-             << 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"
+             << scope_tab << "protected " << inherit_name << "(String 
klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
              << scope_tab << "{\n"
-             << scope_tab << scope_tab << "inherited = this.GetType() != 
managed_type;\n"
+             << scope_tab << scope_tab << "inherited = 
((object)this).GetType() != managed_type;\n"
              << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
              << scope_tab << scope_tab << "if (inherited) {\n"
-             << scope_tab << scope_tab << scope_tab << "if (target_klass == 
System.IntPtr.Zero) {\n"
+             << scope_tab << scope_tab << scope_tab << "if 
(!Efl.Eo.Globals.klasses.ContainsKey(((object)this).GetType())) {\n"
              << scope_tab << scope_tab << scope_tab << scope_tab << "lock 
(klassAllocLock) {\n"
-             << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab 
<< "if (target_klass == System.IntPtr.Zero) {\n"
-             << 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"
-             << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab 
<< scope_tab << "if (target_klass == System.IntPtr.Zero) {\n"
+             << 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"
+             << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab 
<< scope_tab << "if (actual_klass == System.IntPtr.Zero) {\n"
              << 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"
              << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab 
<< scope_tab << "}\n"
-             << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab 
<< "}\n"
+             << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab 
<< scope_tab << "Efl.Eo.Globals.klasses[((object)this).GetType()] = 
actual_klass;\n"
              << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
              << scope_tab << scope_tab << scope_tab << "}\n"
-             << scope_tab << scope_tab << scope_tab << "actual_klass = 
target_klass;\n"
+             << scope_tab << scope_tab << scope_tab << "else\n"
+             << scope_tab << scope_tab << scope_tab << scope_tab << 
"actual_klass = Efl.Eo.Globals.klasses[((object)this).GetType()];\n"
              << scope_tab << scope_tab << "}\n"
              << scope_tab << scope_tab << "handle = 
Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
              << 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 a5cf5c0149..8910447ae1 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)
   return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname);
 }
 
-template<typename T>
-inline std::string interface_native_getter_attr_name(T const& clsname)
-{
-  return klass_interface_name(clsname) + "NativeGetterAttr";
-}
-
-template<typename T>
-inline std::string interface_native_getter_attr_full_name(T const& clsname)
-{
-  return klass_full_interface_name(clsname) + "NativeGetterAttr";
-}
-
 // Events
 inline std::string managed_event_name(std::string const& name)
 {
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs 
b/src/bindings/mono/eo_mono/iwrapper.cs
index fee5a23e34..fe96088626 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -150,11 +150,14 @@ public class Globals {
     [DllImport(efl.Libs.Eo)] public static extern IntPtr
         
efl_object_legacy_only_event_description_get([MarshalAs(UnmanagedType.LPStr)] 
String name);
 
+    public static 
System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr> 
klasses
+        = new System.Collections.Concurrent.ConcurrentDictionary<System.Type, 
System.IntPtr>();
+    
     public const int RTLD_NOW = 2;
 
     public delegate byte class_initializer(IntPtr klass);
-    
-    public static IntPtr register_class(class_initializer initializer, String 
class_name, IntPtr base_klass, System.Type type)
+
+    public static IntPtr register_class(String class_name, IntPtr base_klass, 
System.Type type)
     {
         ClassDescription description;
         description.version = 2; // EO_VERSION
@@ -165,39 +168,113 @@ public class Globals {
         description.class_constructor = IntPtr.Zero;
         description.class_destructor = IntPtr.Zero;
 
-        if(initializer != null)
-            description.class_initializer = 
Marshal.GetFunctionPointerForDelegate(initializer);
+        class_initializer init = (IntPtr kls) =>
+            {
+                return Globals.class_initializer_call(kls, type);
+            };
+        
+        description.class_initializer = 
Marshal.GetFunctionPointerForDelegate(init);
 
         IntPtr description_ptr = 
Eina.MemoryNative.Alloc(Marshal.SizeOf(description));
         Marshal.StructureToPtr(description, description_ptr, false);
 
         var interface_list = EoG.get_efl_interfaces(type);
 
+        System.Console.WriteLine ("Interafaces: {0}", interface_list.Count);
+
         Eina.Log.Debug("Going to register!");
         IntPtr klass = EoG.call_efl_class_new(description_ptr, base_klass, 
interface_list);
         if(klass == IntPtr.Zero)
+        {
             Eina.Log.Error("klass was not registered");
+            Console.WriteLine("klass was not registered");
+        }
         else
             Eina.Log.Debug("Registered class successfully");
         return klass;
     }
     public static List<IntPtr> get_efl_interfaces(System.Type type)
     {
+        System.Type base_type = type.BaseType;
+        
         var ifaces_lst = new List<IntPtr>();
+        var base_ifaces = base_type.GetInterfaces();
         var ifaces = type.GetInterfaces();
         foreach (var iface in ifaces)
         {
-            var attrs = System.Attribute.GetCustomAttributes(iface);
-            foreach (var attr in attrs)
+            if (!System.Array.Exists(base_ifaces, element => element == iface))
             {
-                if (attr is Efl.Eo.NativeGetterAttr) {
-                    
ifaces_lst.Add(((Efl.Eo.NativeGetterAttr)attr).GetEflClass());
+               var attrs = System.Attribute.GetCustomAttributes(iface);
+               foreach (var attr in attrs)
+               {
+                  if (attr is Efl.Eo.NativeClass) {
+                    ifaces_lst.Add(((Efl.Eo.NativeClass)attr).GetEflClass());
                     break;
-                }
+                  }
+               }
             }
         }
         return ifaces_lst;
     }
+    private static Efl.Eo.NativeClass get_native_class(System.Type type)
+    {
+        var attrs = System.Attribute.GetCustomAttributes(type);
+        foreach (var attr in attrs)
+        {
+            if (attr is Efl.Eo.NativeClass) {
+                return (Efl.Eo.NativeClass)attr;
+            }
+        }
+        return null;
+    }
+    public static byte class_initializer_call(IntPtr klass, System.Type type)
+    {
+        Console.WriteLine("class_intiailizer_call 0x{1} {0}", type, klass);
+        Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType);
+
+        if (nativeClass != null)
+        {
+            Console.WriteLine("nativeClass != null");
+            var descs = nativeClass.GetEoOps(type);
+            var count = descs.Count;
+
+            var all_interfaces = type.GetInterfaces();
+            var base_interfaces = type.BaseType.GetInterfaces();
+            foreach (var iface in all_interfaces)
+            {
+                if (!System.Array.Exists(base_interfaces, element => element 
== iface))
+                {
+                    var nc = get_native_class(iface);
+                    if(nc != null)
+                    {
+                        var moredescs = nc.GetEoOps(type);
+                        Console.WriteLine("adding {0} more descs to 
registration", moredescs.Count);
+                        descs.AddRange(moredescs);
+                        count = descs.Count;
+                    }
+                }
+            }
+            
+            IntPtr descs_ptr = 
Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*count);
+            IntPtr ptr = descs_ptr;
+            for(int i = 0; i != count; ++i)
+            {
+               Marshal.StructureToPtr(descs[i], ptr, false);
+               ptr = IntPtr.Add(ptr, Marshal.SizeOf(descs[0]));
+            }
+            Efl_Object_Ops ops;
+            ops.descs = descs_ptr;
+            ops.count = (UIntPtr)count;
+            IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));
+            Marshal.StructureToPtr(ops, ops_ptr, false);
+            Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, 
IntPtr.Zero);
+            //EoKlass = klass;
+        }
+        else
+            Console.WriteLine("nativeClass == null");
+            
+       return 1;
+    }
     public static IntPtr call_efl_class_new(IntPtr desc, IntPtr bk, 
List<IntPtr> il = null)
     {
         IntPtr nul = IntPtr.Zero;
@@ -259,11 +336,17 @@ public class Globals {
     public static IntPtr instantiate_start(IntPtr klass, Efl.Object parent)
     {
         Eina.Log.Debug($"Instantiating from klass 0x{klass.ToInt64():x}");
+        Console.WriteLine($"Instantiating from klass 0x{klass.ToInt64():x}");
         System.IntPtr parent_ptr = System.IntPtr.Zero;
         if(parent != null)
             parent_ptr = parent.NativeHandle;
 
         System.IntPtr eo = Efl.Eo.Globals._efl_add_internal_start("file", 0, 
klass, parent_ptr, 1, 0);
+        if (eo == System.IntPtr.Zero)
+        {
+            throw new Exception("Instantiation failed");
+        }
+        
         Console.WriteLine($"Eo instance right after internal_start 
0x{eo.ToInt64():x} with refcount {Efl.Eo.Globals.efl_ref_count(eo)}");
         Console.WriteLine($"Parent was 0x{parent_ptr.ToInt64()}");
         return eo;
@@ -415,9 +498,10 @@ public static class Config
                        AllowMultiple = false,
                        Inherited = true)
 ]
-public abstract class NativeGetterAttr : System.Attribute
+public abstract class NativeClass : System.Attribute
 {
     public abstract IntPtr GetEflClass();
+    public abstract System.Collections.Generic.List<Efl_Op_Description> 
GetEoOps(System.Type type);
 }
 
 public interface IWrapper
diff --git a/src/tests/efl_mono/Inheritance.cs 
b/src/tests/efl_mono/Inheritance.cs
index 30ca391e87..344c6da71f 100644
--- a/src/tests/efl_mono/Inheritance.cs
+++ b/src/tests/efl_mono/Inheritance.cs
@@ -24,11 +24,13 @@ class TestInheritance
     {
         override public void IntOut (int x, out int y)
         {
+            Console.WriteLine("IntOut");
             y = 10*x;
         }
 
         public string StringshareTest (string i)
         {
+            Console.WriteLine("StringshareTest");
             return "Hello World";
         }
     }
@@ -44,8 +46,8 @@ class TestInheritance
     {
         var obj = new Inherit2();
         int i = Dummy.InheritHelper.ReceiveDummyAndCallIntOut(obj);
-        string s = Dummy.InheritHelper.ReceiveDummyAndCallInStringshare(obj);
         Test.AssertEquals (50, i);
+        string s = Dummy.InheritHelper.ReceiveDummyAndCallInStringshare(obj);
         Test.AssertEquals ("Hello World", s);
     }
 }

-- 


Reply via email to