summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-02-06 17:50:28 -0200
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-03-01 23:04:08 -0300
commitdd89eb2fd1755c2816d97f28822639e03ed38608 (patch)
tree9931650c7db8f267e88b87103fe1c9cc85e0d594 /src/bin
parent6d61ca915195a5ff4c5dc24c271d37fa22d64314 (diff)
efl-mono: Add support for Efl.Class
Efl.Class (in practice, the return from the *_class_get() functions) can be used as argument to functions, like in Efl.Object.provider_find and Efl.Ui.Widget_Factory.item_class(get/set). This commits adds support by representing Efl.Class instances as System.Type in the C# API, allowing someone to do things like: `factory.ItemClass == typeof(MyFramework.MyButton)` It also supports user-defined classes that inherit from efl classes.
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh29
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh44
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh3
3 files changed, 49 insertions, 27 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 6c02de6..e70729b 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -347,6 +347,15 @@ struct klass
347 return false; 347 return false;
348 } 348 }
349 349
350 // Copied from nativeinherit class, used when setting up providers.
351 if(!as_generator(
352 scope_tab << "private static " << (root ? "" : "new ") << " IntPtr GetEflClassStatic()\n"
353 << scope_tab << "{\n"
354 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
355 << scope_tab << "}\n"
356 ).generate(sink, attributes::unused, inherit_cxt))
357 return false;
358
350 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 359 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
351 } 360 }
352 361
@@ -454,7 +463,7 @@ struct klass
454 << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof (" << inherit_name << "))\n" 463 << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof (" << inherit_name << "))\n"
455 << scope_tab << scope_tab << scope_tab << scope_tab << "return " << native_inherit_full_name << ".GetEflClassStatic();\n" 464 << scope_tab << scope_tab << scope_tab << scope_tab << "return " << native_inherit_full_name << ".GetEflClassStatic();\n"
456 << scope_tab << scope_tab << scope_tab << "else\n" 465 << scope_tab << scope_tab << scope_tab << "else\n"
457 << scope_tab << scope_tab << scope_tab << scope_tab << "return Efl.Eo.Globals.klasses[((object)this).GetType()];\n" 466 << scope_tab << scope_tab << scope_tab << scope_tab << "return Efl.Eo.ClassRegister.klassFromType[((object)this).GetType()];\n"
458 << scope_tab << scope_tab << "}\n" 467 << scope_tab << scope_tab << "}\n"
459 << scope_tab << "}\n" 468 << scope_tab << "}\n"
460 ).generate(sink, attributes::unused, context)) 469 ).generate(sink, attributes::unused, context))
@@ -512,7 +521,7 @@ struct klass
512 // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters. 521 // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
513 << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n" 522 << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n"
514 << scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") :\n" 523 << scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") :\n"
515 << scope_tab << scope_tab << (root ? "this" : "base") << "(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n" 524 << scope_tab << scope_tab << (root ? "this" : "base") << "(" << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
516 << scope_tab << "{\n" 525 << scope_tab << "{\n"
517 << *(scope_tab << scope_tab << constructor_invocation << "\n" ) 526 << *(scope_tab << scope_tab << constructor_invocation << "\n" )
518 << scope_tab << scope_tab << "FinishInstantiation();\n" 527 << scope_tab << scope_tab << "FinishInstantiation();\n"
@@ -531,7 +540,7 @@ struct klass
531 { 540 {
532 return as_generator( 541 return as_generator(
533 scope_tab << "///<summary>Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.</summary>\n" 542 scope_tab << "///<summary>Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.</summary>\n"
534 << 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" 543 << scope_tab << "protected " << inherit_name << "(IntPtr base_klass, System.Type managed_type, Efl.Object parent) : base(base_klass, managed_type, parent) {}\n"
535 ).generate(sink, attributes::unused, context); 544 ).generate(sink, attributes::unused, context);
536 545
537 } 546 }
@@ -539,22 +548,12 @@ struct klass
539 // Detailed constructors go only in root classes. 548 // Detailed constructors go only in root classes.
540 return as_generator( 549 return as_generator(
541 /// Actual root costructor that creates class and instantiates 550 /// Actual root costructor that creates class and instantiates
542 scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n" 551 scope_tab << "protected " << inherit_name << "(IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
543 << scope_tab << "{\n" 552 << scope_tab << "{\n"
544 << scope_tab << scope_tab << "inherited = ((object)this).GetType() != managed_type;\n" 553 << scope_tab << scope_tab << "inherited = ((object)this).GetType() != managed_type;\n"
545 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n" 554 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
546 << scope_tab << scope_tab << "if (inherited) {\n" 555 << scope_tab << scope_tab << "if (inherited) {\n"
547 << scope_tab << scope_tab << scope_tab << "if (!Efl.Eo.Globals.klasses.ContainsKey(((object)this).GetType())) {\n" 556 << scope_tab << scope_tab << scope_tab << "actual_klass = Efl.Eo.ClassRegister.GetInheritKlassOrRegister(base_klass, ((object)this).GetType());\n"
548 << scope_tab << scope_tab << scope_tab << scope_tab << "lock (klassAllocLock) {\n"
549 << 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"
550 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (actual_klass == System.IntPtr.Zero) {\n"
551 << 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"
552 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
553 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.klasses[((object)this).GetType()] = actual_klass;\n"
554 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
555 << scope_tab << scope_tab << scope_tab << "}\n"
556 << scope_tab << scope_tab << scope_tab << "else\n"
557 << scope_tab << scope_tab << scope_tab << scope_tab << "actual_klass = Efl.Eo.Globals.klasses[((object)this).GetType()];\n"
558 << scope_tab << scope_tab << "}\n" 557 << scope_tab << scope_tab << "}\n"
559 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n" 558 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
560 << scope_tab << scope_tab << "register_event_proxies();\n" 559 << scope_tab << scope_tab << "register_event_proxies();\n"
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index 6ddb990..744b4f8 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -142,12 +142,22 @@ struct marshall_annotation_visitor_generate
142 } 142 }
143 bool operator()(attributes::klass_name const& klass_name) const 143 bool operator()(attributes::klass_name const& klass_name) const
144 { 144 {
145 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<"; 145 const char *return_prefix = is_return ? "return:" : "";
146 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<"; 146 const char *marshal_prefix = "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(";
147 return as_generator 147
148 ((is_return ? return_prefix : no_return_prefix) 148 std::string name = name_helpers::klass_full_concrete_name(klass_name);
149 << string << ", Efl.Eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" 149
150 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); 150 if (name == "Efl.Class")
151 name = "Efl.Eo.MarshalEflClass";
152 else
153 {
154 auto own = klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag";
155 name = "Efl.Eo.MarshalTest<" + name + ", Efl.Eo." + own + ">";
156 }
157
158 return as_generator(
159 lit("[") << return_prefix << marshal_prefix << name << "))]"
160 ).generate(sink, name, *context);
151 } 161 }
152 bool operator()(attributes::complex_type_def const& c) const 162 bool operator()(attributes::complex_type_def const& c) const
153 { 163 {
@@ -252,12 +262,22 @@ struct marshall_native_annotation_visitor_generate
252 } 262 }
253 bool operator()(attributes::klass_name const& klass_name) const 263 bool operator()(attributes::klass_name const& klass_name) const
254 { 264 {
255 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<"; 265 const char *return_prefix = is_return ? "return:" : "";
256 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<"; 266 const char *marshal_prefix = "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(";
257 return as_generator 267
258 ((is_return ? return_prefix : no_return_prefix) 268 std::string name = name_helpers::klass_full_concrete_name(klass_name);
259 << string << ", Efl.Eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" 269
260 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); 270 if (name == "Efl.Class")
271 name = "Efl.Eo.MarshalEflClass";
272 else
273 {
274 auto own = klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag";
275 name = "Efl.Eo.MarshalTest<" + name + ", Efl.Eo." + own + ">";
276 }
277
278 return as_generator(
279 lit("[") << return_prefix << marshal_prefix << name << "))]"
280 ).generate(sink, name, *context);
261 } 281 }
262 bool operator()(attributes::complex_type_def const& c) const 282 bool operator()(attributes::complex_type_def const& c) const
263 { 283 {
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index 9810250..f34c479 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -309,6 +309,9 @@ struct visitor_generate
309 } 309 }
310 bool operator()(attributes::klass_name klass) const 310 bool operator()(attributes::klass_name klass) const
311 { 311 {
312 // Efl.Class is manually handled in a custom marshall to be represented by a System.Type.
313 if (name_helpers::klass_full_concrete_name(klass) == "Efl.Class")
314 return as_generator(lit("Type")).generate(sink, attributes::unused, *context);
312 if(klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_) 315 if(klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_)
313 return as_generator(string).generate(sink, name_helpers::klass_full_concrete_name(klass), *context); 316 return as_generator(string).generate(sink, name_helpers::klass_full_concrete_name(klass), *context);
314 else 317 else