diff options
author | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2019-02-06 17:50:28 -0200 |
---|---|---|
committer | Vitor Sousa <vitorsousa@expertisesolutions.com.br> | 2019-03-01 23:04:08 -0300 |
commit | dd89eb2fd1755c2816d97f28822639e03ed38608 (patch) | |
tree | 9931650c7db8f267e88b87103fe1c9cc85e0d594 /src/bin/eolian_mono | |
parent | 6d61ca915195a5ff4c5dc24c271d37fa22d64314 (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/eolian_mono')
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/klass.hh | 29 | ||||
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/marshall_annotation.hh | 44 | ||||
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/type_impl.hh | 3 |
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 |