summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-12-18 16:43:48 -0200
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-02-28 22:13:35 -0300
commit230cc00eeb2e38421a27b2badb6422c29f767f91 (patch)
tree0e8b5a724eb90b67d9f407a398dcd279608467c5
parent9583f2a7678252233a5e5f3b0f4982a6365bf433 (diff)
efl-mono: Add Model manual implementation to C# and MVVM factories
Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8080
-rw-r--r--src/Makefile_Ecore.am5
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh48
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh14
-rw-r--r--src/bindings/mono/efl_mono/Bind.cs31
-rw-r--r--src/bindings/mono/efl_mono/Factory.cs19
-rw-r--r--src/bindings/mono/efl_mono/GenericModel.cs113
-rw-r--r--src/bindings/mono/efl_mono/UserModel.cs66
-rw-r--r--src/bindings/mono/efl_mono/meson.build6
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs10
-rw-r--r--src/lib/ecore/Ecore_Eo.h3
-rw-r--r--src/lib/ecore/efl_mono_model_internal.c203
-rw-r--r--src/lib/ecore/efl_mono_model_internal.eo19
-rw-r--r--src/lib/ecore/efl_mono_model_internal_child.eo10
-rw-r--r--src/lib/ecore/meson.build3
-rw-r--r--src/tests/efl_mono/Model.cs53
-rw-r--r--src/tests/efl_mono/Parts.cs15
-rw-r--r--src/tests/efl_mono/meson.build1
17 files changed, 612 insertions, 7 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index c7f66ebd02..b1dfefcd0a 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -52,7 +52,9 @@ ecore_eolian_files_public = \
52 lib/ecore/efl_view_model.eo \ 52 lib/ecore/efl_view_model.eo \
53 lib/ecore/efl_core_env.eo \ 53 lib/ecore/efl_core_env.eo \
54 lib/ecore/efl_core_proc_env.eo \ 54 lib/ecore/efl_core_proc_env.eo \
55 lib/ecore/efl_core_command_line.eo 55 lib/ecore/efl_core_command_line.eo \
56 lib/ecore/efl_mono_model_internal.eo \
57 lib/ecore/efl_mono_model_internal_child.eo
56 58
57ecore_test_eolian_files = \ 59ecore_test_eolian_files = \
58 tests/ecore/efl_app_test_cml.eo 60 tests/ecore/efl_app_test_cml.eo
@@ -144,6 +146,7 @@ lib/ecore/efl_composite_model_private.h \
144lib/ecore/efl_model_accessor_view.c \ 146lib/ecore/efl_model_accessor_view.c \
145lib/ecore/efl_model_accessor_view_private.h \ 147lib/ecore/efl_model_accessor_view_private.h \
146lib/ecore/efl_view_model.c \ 148lib/ecore/efl_view_model.c \
149lib/ecore/efl_mono_model_internal.c \
147lib/ecore/efl_linear_interpolator.c \ 150lib/ecore/efl_linear_interpolator.c \
148lib/ecore/efl_accelerate_interpolator.c \ 151lib/ecore/efl_accelerate_interpolator.c \
149lib/ecore/efl_decelerate_interpolator.c \ 152lib/ecore/efl_decelerate_interpolator.c \
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 67dfcc0ce4..32049a2f8b 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -214,6 +214,47 @@ struct native_function_definition_parameterized
214 } 214 }
215} const native_function_definition; 215} const native_function_definition;
216 216
217struct property_extension_method_definition_generator
218{
219 template<typename OutputIterator, typename Context>
220 bool generate(OutputIterator sink, attributes::property_def const& property, Context context) const
221 {
222 if (blacklist::is_property_blacklisted(property, context))
223 return true;
224
225 auto get_params = property.getter.is_engaged() ? property.getter->parameters.size() : 0;
226 auto set_params = property.setter.is_engaged() ? property.setter->parameters.size() : 0;
227
228 std::string managed_name = name_helpers::property_managed_name(property);
229
230 if (get_params > 0 || set_params > 1)
231 return true;
232
233 std::string dir_mod;
234 if (property.setter.is_engaged())
235 dir_mod = direction_modifier(property.setter->parameters[0]);
236
237 if (property.setter.is_engaged())
238 {
239 attributes::type_def prop_type = property.setter->parameters[0].type;
240 if (!as_generator("public static Efl.Bindable<" << type(true) << "> " << managed_name << "(this Efl.Ui.ItemFactory<" << name_helpers::klass_full_concrete_name(cls) << "> fac) {\n"
241 << scope_tab << scope_tab << "return new Efl.Bindable<" << type(true) << ">(\"" << property.name << "\", fac);\n"
242 << scope_tab << "}\n"
243 ).generate(sink, std::make_tuple(prop_type, prop_type), context))
244 return false;
245 }
246
247 return true;
248 }
249
250 grammar::attributes::klass_def const& cls;
251};
252
253property_extension_method_definition_generator property_extension_method_definition (grammar::attributes::klass_def const& cls)
254{
255 return {cls};
256}
257
217struct property_wrapper_definition_generator 258struct property_wrapper_definition_generator
218{ 259{
219 template<typename OutputIterator, typename Context> 260 template<typename OutputIterator, typename Context>
@@ -292,6 +333,8 @@ struct is_eager_generator< ::eolian_mono::function_definition_generator> : std::
292template <> 333template <>
293struct is_eager_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {}; 334struct is_eager_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {};
294template <> 335template <>
336struct is_eager_generator< ::eolian_mono::property_extension_method_definition_generator> : std::true_type {};
337template <>
295struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {}; 338struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
296template <> 339template <>
297struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {}; 340struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {};
@@ -300,6 +343,8 @@ struct is_generator< ::eolian_mono::native_function_definition_generator> : std:
300template <> 343template <>
301struct is_generator< ::eolian_mono::function_definition_parameterized> : std::true_type {}; 344struct is_generator< ::eolian_mono::function_definition_parameterized> : std::true_type {};
302template <> 345template <>
346struct is_generator< ::eolian_mono::property_extension_method_definition_generator> : std::true_type {};
347template <>
303struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {}; 348struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
304 349
305namespace type_traits { 350namespace type_traits {
@@ -313,6 +358,9 @@ template <>
313struct attributes_needed< ::eolian_mono::native_function_definition_generator> : std::integral_constant<int, 1> {}; 358struct attributes_needed< ::eolian_mono::native_function_definition_generator> : std::integral_constant<int, 1> {};
314 359
315template <> 360template <>
361struct attributes_needed< ::eolian_mono::property_extension_method_definition_generator> : std::integral_constant<int, 1> {};
362
363template <>
316struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {}; 364struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {};
317} 365}
318 366
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index fc1bdd57aa..103151e976 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -416,6 +416,12 @@ struct klass
416 if(!name_helpers::close_namespaces(sink, cls.namespaces, context)) 416 if(!name_helpers::close_namespaces(sink, cls.namespaces, context))
417 return false; 417 return false;
418 418
419 if(!as_generator
420 ("public static class " << (string % "_") << name_helpers::klass_inherit_name(cls)
421 << "_ExtensionMethods {\n"
422 << *((scope_tab << property_extension_method_definition(cls)) << "\n")
423 << "}\n")
424 .generate(sink, std::make_tuple(cls.namespaces, cls.properties), context));
419 return true; 425 return true;
420 } 426 }
421 427
@@ -511,7 +517,7 @@ struct klass
511 // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters. 517 // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
512 << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n" 518 << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n"
513 << scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") :\n" 519 << scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") :\n"
514 << scope_tab << scope_tab << (root ? "this" : "base") << "(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n" 520 << scope_tab << scope_tab << (root ? "this" : "base") << "(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, false)\n"
515 << scope_tab << "{\n" 521 << scope_tab << "{\n"
516 << *(scope_tab << scope_tab << constructor_invocation << "\n" ) 522 << *(scope_tab << scope_tab << constructor_invocation << "\n" )
517 << scope_tab << scope_tab << "FinishInstantiation();\n" 523 << scope_tab << scope_tab << "FinishInstantiation();\n"
@@ -530,7 +536,7 @@ struct klass
530 { 536 {
531 return as_generator( 537 return as_generator(
532 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" 538 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"
533 << 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" 539 << scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent, bool force_no_inherit) : base(klass_name, base_klass, managed_type, parent, force_no_inherit) {}\n"
534 ).generate(sink, attributes::unused, context); 540 ).generate(sink, attributes::unused, context);
535 541
536 } 542 }
@@ -538,9 +544,9 @@ struct klass
538 // Detailed constructors go only in root classes. 544 // Detailed constructors go only in root classes.
539 return as_generator( 545 return as_generator(
540 /// Actual root costructor that creates class and instantiates 546 /// Actual root costructor that creates class and instantiates
541 scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n" 547 scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent, bool force_no_inherit)\n"
542 << scope_tab << "{\n" 548 << scope_tab << "{\n"
543 << scope_tab << scope_tab << "inherited = ((object)this).GetType() != managed_type;\n" 549 << scope_tab << scope_tab << "inherited = force_no_inherit ? false : ((object)this).GetType() != managed_type;\n"
544 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n" 550 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
545 << scope_tab << scope_tab << "if (inherited) {\n" 551 << scope_tab << scope_tab << "if (inherited) {\n"
546 << scope_tab << scope_tab << scope_tab << "if (!Efl.Eo.Globals.klasses.ContainsKey(((object)this).GetType())) {\n" 552 << scope_tab << scope_tab << scope_tab << "if (!Efl.Eo.Globals.klasses.ContainsKey(((object)this).GetType())) {\n"
diff --git a/src/bindings/mono/efl_mono/Bind.cs b/src/bindings/mono/efl_mono/Bind.cs
new file mode 100644
index 0000000000..1f8fbf20d7
--- /dev/null
+++ b/src/bindings/mono/efl_mono/Bind.cs
@@ -0,0 +1,31 @@
1using System;
2using System.Runtime.InteropServices;
3using System.Collections.Generic;
4using System.Linq;
5using System.ComponentModel;
6
7namespace Efl {
8
9public class Bindable<T>
10{
11 public Bindable(string name, Efl.Ui.PropertyBind binder)
12 {
13 this.name = name;
14 this.binder = binder;
15 }
16
17 public void Bind(string model_property)
18 {
19 binder.PropertyBind(name, model_property);
20 }
21
22 public void Set(T value)
23 {
24 // set somehow
25 }
26
27 string name;
28 Efl.Ui.PropertyBind binder;
29}
30
31}
diff --git a/src/bindings/mono/efl_mono/Factory.cs b/src/bindings/mono/efl_mono/Factory.cs
new file mode 100644
index 0000000000..48b988f399
--- /dev/null
+++ b/src/bindings/mono/efl_mono/Factory.cs
@@ -0,0 +1,19 @@
1using System;
2using System.Runtime.InteropServices;
3using System.Collections.Generic;
4using System.Linq;
5using System.ComponentModel;
6
7namespace Efl { namespace Ui {
8
9public class ItemFactory<T> : Efl.Ui.CachingFactory, IDisposable
10{
11 public ItemFactory(Efl.Object parent = null)
12 : base (parent, Efl.Eo.Globals.get_efl_klass_from_klass<T>())
13 {
14 }
15
16
17}
18
19} }
diff --git a/src/bindings/mono/efl_mono/GenericModel.cs b/src/bindings/mono/efl_mono/GenericModel.cs
new file mode 100644
index 0000000000..214755cefb
--- /dev/null
+++ b/src/bindings/mono/efl_mono/GenericModel.cs
@@ -0,0 +1,113 @@
1using System;
2using System.Runtime.InteropServices;
3using System.Collections.Generic;
4using System.Linq;
5using System.ComponentModel;
6
7namespace Efl {
8
9public class GenericModel<T> : Efl.Object, Efl.Model, IDisposable
10{
11 private Efl.Model model;
12
13 public GenericModel (Efl.Model model, Efl.Object parent = null) : base(parent)
14 {
15 this.model = model;
16 FinishInstantiation();
17 }
18
19 ~GenericModel()
20 {
21 Dispose(false);
22 }
23
24 public Eina.Iterator< System.String> Properties {
25 get { return GetProperties(); }
26 }
27 public uint ChildrenCount {
28 get { return GetChildrenCount(); }
29 }
30
31 public Eina.Iterator<System.String> GetProperties()
32 {
33 return model.GetProperties();
34 }
35 public Eina.Value GetProperty( System.String property)
36 {
37 return model.GetProperty(property);
38 }
39 public Eina.Future SetProperty( System.String property, Eina.Value value)
40 {
41 return model.SetProperty(property, value);
42 }
43 public uint GetChildrenCount()
44 {
45 return model.GetChildrenCount();
46 }
47 public Eina.Future GetPropertyReady( System.String property)
48 {
49 return model.GetPropertyReady(property);
50 }
51 public Eina.Future GetChildrenSlice( uint start, uint count)
52 {
53 return model.GetChildrenSlice(start, count);
54 }
55 public Efl.Object AddChild()
56 {
57 return model.AddChild();
58 }
59 public void DelChild( Efl.Object child)
60 {
61 model.DelChild(child);
62 }
63 public System.Threading.Tasks.Task<Eina.Value> SetPropertyAsync( System.String property, Eina.Value value, System.Threading.CancellationToken token=default(System.Threading.CancellationToken))
64 {
65 return model.SetPropertyAsync(property, value, token);
66 }
67 public System.Threading.Tasks.Task<Eina.Value> GetPropertyReadyAsync( System.String property, System.Threading.CancellationToken token=default(System.Threading.CancellationToken))
68 {
69 return model.GetPropertyReadyAsync(property, token);
70 }
71 public System.Threading.Tasks.Task<Eina.Value> GetChildrenSliceAsync( uint start, uint count, System.Threading.CancellationToken token=default(System.Threading.CancellationToken))
72 {
73 return model.GetChildrenSliceAsync(start, count, token);
74 }
75 public event EventHandler<Efl.ModelPropertiesChangedEvt_Args> PropertiesChangedEvt
76 {
77 add {
78 model.PropertiesChangedEvt += value;
79 }
80 remove {
81 model.PropertiesChangedEvt -= value;
82 }
83 }
84 public event EventHandler<Efl.ModelChildAddedEvt_Args> ChildAddedEvt
85 {
86 add {
87 model.ChildAddedEvt += value;
88 }
89 remove {
90 model.ChildAddedEvt -= value;
91 }
92 }
93 public event EventHandler<Efl.ModelChildRemovedEvt_Args> ChildRemovedEvt
94 {
95 add {
96 model.ChildRemovedEvt += value;
97 }
98 remove {
99 model.ChildRemovedEvt -= value;
100 }
101 }
102 public event EventHandler ChildrenCountChangedEvt
103 {
104 add {
105 model.ChildrenCountChangedEvt += value;
106 }
107 remove {
108 model.ChildrenCountChangedEvt -= value;
109 }
110 }
111}
112
113}
diff --git a/src/bindings/mono/efl_mono/UserModel.cs b/src/bindings/mono/efl_mono/UserModel.cs
new file mode 100644
index 0000000000..4555607470
--- /dev/null
+++ b/src/bindings/mono/efl_mono/UserModel.cs
@@ -0,0 +1,66 @@
1using System;
2using System.Runtime.InteropServices;
3using System.Collections.Generic;
4using System.Linq;
5using System.ComponentModel;
6
7namespace Efl {
8
9public class UserModel<T> : Efl.MonoModelInternal, IDisposable
10{
11 ///<summary>Pointer to the native class description.</summary>
12 public override System.IntPtr NativeClass {
13 get {
14 if (((object)this).GetType() == typeof (UserModel<T>))
15 return Efl.MonoModelInternalNativeInherit.GetEflClassStatic();
16 else
17 return Efl.Eo.Globals.klasses[((object)this).GetType()];
18 }
19 }
20 public UserModel (Efl.Object parent = null) : base("MonoModelInternal", Efl.MonoModelInternal.efl_mono_model_internal_class_get(), typeof(MonoModelInternal), parent, true)
21 {
22 inherited = false;
23 var properties = typeof(T).GetProperties();
24 foreach(var prop in properties)
25 {
26 AddProperty(prop.Name, System.IntPtr.Zero);
27 }
28
29 FinishInstantiation();
30 }
31
32 ~UserModel()
33 {
34 Dispose(false);
35 }
36 public void Add (T o)
37 {
38 Efl.Object obj = this.AddChild();
39 if (obj == null)
40 Console.WriteLine("Object from AddChild is null");
41 //Debug.Assert(obj != null);
42 Efl.Model child = Efl.ModelConcrete.static_cast(obj);
43 //Debug.Assert(child != null);
44
45 var properties = typeof(T).GetProperties();
46 foreach(var prop in properties)
47 {
48 Eina.Value v;
49 if (prop.PropertyType == typeof(int))
50 {
51 v = new Eina.Value(Eina.ValueType.Int32);
52 v.Set((int)prop.GetValue(o));
53 }
54 else if (prop.PropertyType == typeof(string))
55 {
56 v = new Eina.Value(Eina.ValueType.String);
57 v.Set((string)prop.GetValue(o));
58 }
59 else
60 throw new Exception("Type unknown " + prop.PropertyType.Name);
61 child.SetProperty(prop.Name, v);
62 }
63 }
64}
65
66}
diff --git a/src/bindings/mono/efl_mono/meson.build b/src/bindings/mono/efl_mono/meson.build
index acfeb4bc3f..d8b1a8e4b8 100644
--- a/src/bindings/mono/efl_mono/meson.build
+++ b/src/bindings/mono/efl_mono/meson.build
@@ -1,6 +1,10 @@
1mono_files += files( 1mono_files += files(
2 'efl_all.cs', 2 'efl_all.cs',
3 'efl_csharp_application.cs' 3 'efl_csharp_application.cs',
4 'UserModel.cs',
5 'GenericModel.cs',
6 'Factory.cs',
7 'Bind.cs'
4 ) 8 )
5 9
6bash = find_program('bash') 10bash = find_program('bash')
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index 2dfc3d4523..7243fad592 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -241,6 +241,12 @@ public class Globals {
241 Eina.Log.Debug("Registered class successfully"); 241 Eina.Log.Debug("Registered class successfully");
242 return klass; 242 return klass;
243 } 243 }
244 public static Efl.Class get_efl_klass_from_klass<T>()
245 {
246 var native = get_native_class (typeof(T));
247 return new Efl.Class (native.GetEflClass());
248 }
249
244 public static List<IntPtr> get_efl_interfaces(System.Type type) 250 public static List<IntPtr> get_efl_interfaces(System.Type type)
245 { 251 {
246 System.Type base_type = type.BaseType; 252 System.Type base_type = type.BaseType;
@@ -408,12 +414,14 @@ public class Globals {
408 public static void data_set(Efl.Eo.IWrapper obj) 414 public static void data_set(Efl.Eo.IWrapper obj)
409 { 415 {
410 Eina.Log.Debug($"Calling data_scope_get with obj {obj.NativeHandle.ToInt64():x} and klass {obj.NativeClass.ToInt64():x}"); 416 Eina.Log.Debug($"Calling data_scope_get with obj {obj.NativeHandle.ToInt64():x} and klass {obj.NativeClass.ToInt64():x}");
417 Console.WriteLine($"Calling data_scope_get with obj {obj.NativeHandle.ToInt64():x} and klass {obj.NativeClass.ToInt64():x}");
411 IntPtr pd = Efl.Eo.Globals.efl_data_scope_get(obj.NativeHandle, obj.NativeClass); 418 IntPtr pd = Efl.Eo.Globals.efl_data_scope_get(obj.NativeHandle, obj.NativeClass);
419 if (pd != null)
412 { 420 {
413 GCHandle gch = GCHandle.Alloc(obj); 421 GCHandle gch = GCHandle.Alloc(obj);
414 EolianPD epd; 422 EolianPD epd;
415 epd.pointer = GCHandle.ToIntPtr(gch); 423 epd.pointer = GCHandle.ToIntPtr(gch);
416 Marshal.StructureToPtr(epd, pd, false); 424 Marshal.StructureToPtr<EolianPD>(epd, pd, false);
417 } 425 }
418 } 426 }
419 public static Efl.Eo.IWrapper data_get(IntPtr pd) 427 public static Efl.Eo.IWrapper data_get(IntPtr pd)
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 3615219c38..cd74e77bca 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -126,4 +126,7 @@ EAPI Eo *efl_main_loop_get(void);
126 * @} 126 * @}
127 */ 127 */
128 128
129#include "efl_mono_model_internal.eo.h"
130#include "efl_mono_model_internal_child.eo.h"
131
129#endif 132#endif
diff --git a/src/lib/ecore/efl_mono_model_internal.c b/src/lib/ecore/efl_mono_model_internal.c
new file mode 100644
index 0000000000..bdd6ce6045
--- /dev/null
+++ b/src/lib/ecore/efl_mono_model_internal.c
@@ -0,0 +1,203 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Efl.h"
6#include "Ecore.h"
7#include <Eo.h>
8
9#include "efl_mono_model_internal.eo.h"
10#include "efl_mono_model_internal_child.eo.h"
11
12#include "assert.h"
13
14typedef struct _Efl_Mono_Model_Internal_Data Efl_Mono_Model_Internal_Data;
15
16typedef struct _Properties_Info Properties_Info;
17struct _Properties_Info
18{
19 const char* name;
20 Eina_Value_Type* type;
21};
22
23typedef struct _Efl_Mono_Model_Internal_Data
24{
25 Eina_Array *properties_info;
26 Eina_Array *properties_names;
27 Eina_Array *items;
28} _Efl_Mono_Model_Internal_Data;
29
30
31#define MY_CLASS EFL_MONO_MODEL_INTERNAL_CLASS
32
33typedef struct _Efl_Mono_Model_Internal_Child_Data
34{
35 Efl_Mono_Model_Internal_Data* model_pd;
36 size_t index;
37 Eina_Array *values;
38 //Eina_Array *items;
39} Efl_Mono_Model_Internal_Child_Data;
40
41static int _find_property_index (const char* name, Eina_Array* properties_info)
42{
43 int i, size = eina_array_count_get(properties_info);
44 fprintf(stdout, "count %d\n", size); fflush(stdout);
45 for (i = 0; i != size; ++i)
46 {
47 if (!strcmp(properties_info->data[i], name))
48 {
49 return i;
50 }
51 }
52 return -1;
53}
54
55static Eo *
56_efl_mono_model_internal_efl_object_constructor(Eo *obj, Efl_Mono_Model_Internal_Data *pd)
57{
58 fprintf (stdout, "_efl_mono_model_internal_efl_object_constructor\n"); fflush(stdout);
59 obj = efl_constructor(efl_super(obj, MY_CLASS));
60
61 pd->properties_info = eina_array_new(5);
62 pd->items = eina_array_new(5);
63
64 if (!obj) return NULL;
65
66 return obj;
67}
68
69static void
70_efl_mono_model_internal_efl_object_destructor(Eo *obj, Efl_Mono_Model_Internal_Data *pd EINA_UNUSED)
71{
72 efl_destructor(efl_super(obj, MY_CLASS));
73}
74
75static void
76_efl_mono_model_internal_add_property(Eo *obj EINA_UNUSED, Efl_Mono_Model_Internal_Data *pd, const char *name, void *type)
77{
78 fprintf(stdout, "add property name : %s\n", name); fflush(stdout);
79
80 Properties_Info* info = malloc(sizeof(Properties_Info));
81 info->name = eina_stringshare_add(name);
82 info->type = type;
83 eina_array_push (pd->properties_info, info);
84}
85
86
87static Eina_Iterator *
88_efl_mono_model_internal_efl_model_properties_get(const Eo *obj EINA_UNUSED, Efl_Mono_Model_Internal_Data *pd EINA_UNUSED)
89{
90 return eina_array_iterator_new (NULL);
91}
92
93static Efl_Object*
94_efl_mono_model_internal_efl_model_child_add(Eo *obj, Efl_Mono_Model_Internal_Data *pd)
95{
96 fprintf (stdout, "child_add\n"); fflush(stdout);
97 Efl_Mono_Model_Internal_Child* child = efl_add (EFL_MONO_MODEL_INTERNAL_CHILD_CLASS, obj);
98 fprintf (stdout, "child_add %p\n", child); fflush(stdout);
99 assert (child != NULL);
100 Efl_Mono_Model_Internal_Child_Data* pcd = efl_data_xref (child, EFL_MONO_MODEL_INTERNAL_CHILD_CLASS, obj);
101 pcd->model_pd = pd;
102 pcd->index = eina_array_count_get(pd->items);
103 eina_array_push (pd->items, pcd);
104
105 return child;
106}
107
108static unsigned int
109_efl_mono_model_internal_efl_model_children_count_get(const Eo *obj EINA_UNUSED, Efl_Mono_Model_Internal_Data *pd)
110{
111 return eina_array_count_get(pd->items);
112}
113
114static Eina_Future *
115_efl_mono_model_internal_child_efl_model_property_set(Eo *obj, Efl_Mono_Model_Internal_Child_Data *pd, const char *property, Eina_Value *value)
116{
117 fprintf (stdout, "property_set\n"); fflush(stdout);
118 int i = _find_property_index (property, pd->model_pd->properties_info);
119 int j;
120 Eina_Value* old_value;
121
122 fprintf (stdout, "property_set\n"); fflush(stdout);
123
124 if (i >= 0)
125 //if (0)
126 {
127 for (j = i - eina_array_count_get (pd->values); j; --j)
128 eina_array_push (pd->values, NULL);
129
130 old_value = eina_array_data_get (pd->values, i);
131 if (old_value)
132 eina_value_free (old_value);
133 eina_array_data_set (pd->values, i, value);
134
135 /* promise = eian_promise_new (efl_loop_future_scheduler_get(obj), NULL, NULL); */
136 /* future = eina_future_new (promise); */
137
138
139 Eina_Future* f = efl_loop_future_resolved(obj, *value);
140 fprintf(stdout, "com resolved %p\n", f); fflush(stdout);
141 assert(!!f);
142 return f;
143 }
144 else
145 {
146 // not found property
147 //return efl_loop_future_rejected(obj, EAGAIN);
148
149 Eina_Promise* promise = eina_promise_new (efl_loop_future_scheduler_get(obj), NULL, NULL);
150 Eina_Future* future = eina_future_new (promise);
151 return future;
152 }
153}
154
155static Eina_Value *
156_efl_mono_model_internal_child_efl_model_property_get(const Eo *obj EINA_UNUSED, Efl_Mono_Model_Internal_Child_Data *pd EINA_UNUSED, const char *property EINA_UNUSED)
157{
158 return eina_value_error_new(EAGAIN);
159}
160
161static Eina_Future *
162_efl_mono_model_internal_efl_model_children_slice_get(Eo *obj, Efl_Mono_Model_Internal_Data *pd, unsigned int start, unsigned int count EINA_UNUSED)
163{
164 unsigned int i;
165 Eina_Value array = EINA_VALUE_EMPTY;
166
167 eina_value_array_setup(&array, EINA_VALUE_TYPE_OBJECT, count % 8);
168
169 for (i = start; i != start + count; ++i)
170 eina_value_array_append (&array, eina_array_data_get(pd->items, i));
171
172 return efl_loop_future_resolved(obj, array);
173}
174
175static Eo *
176_efl_mono_model_internal_child_efl_object_constructor(Eo *obj, Efl_Mono_Model_Internal_Child_Data *pd EINA_UNUSED)
177{
178 obj = efl_constructor(efl_super(obj, EFL_MONO_MODEL_INTERNAL_CHILD_CLASS));
179
180 return obj;
181}
182
183static void
184_efl_mono_model_internal_child_efl_object_destructor(Eo *obj, Efl_Mono_Model_Internal_Child_Data *pd EINA_UNUSED)
185{
186 efl_destructor(efl_super(obj, EFL_MONO_MODEL_INTERNAL_CHILD_CLASS));
187}
188
189static Efl_Object*
190_efl_mono_model_internal_child_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Mono_Model_Internal_Child_Data *pd EINA_UNUSED)
191{
192 abort();
193 return NULL;
194}
195
196static Eina_Iterator *
197_efl_mono_model_internal_child_efl_model_properties_get(const Eo *obj EINA_UNUSED, Efl_Mono_Model_Internal_Child_Data *pd)
198{
199 return eina_array_iterator_new (pd->model_pd->properties_names);
200}
201
202#include "efl_mono_model_internal.eo.c"
203#include "efl_mono_model_internal_child.eo.c"
diff --git a/src/lib/ecore/efl_mono_model_internal.eo b/src/lib/ecore/efl_mono_model_internal.eo
new file mode 100644
index 0000000000..341f066480
--- /dev/null
+++ b/src/lib/ecore/efl_mono_model_internal.eo
@@ -0,0 +1,19 @@
1class Efl.Mono_Model_Internal extends Efl.Object implements Efl.Model
2{
3 methods {
4 add_property {
5 params {
6 @in name: string;
7 @in type: void_ptr;
8 }
9 }
10 }
11 implements {
12 Efl.Object.constructor;
13 Efl.Object.destructor;
14 Efl.Model.properties { get; }
15 Efl.Model.child_add;
16 Efl.Model.children_count { get; }
17 Efl.Model.children_slice_get;
18 }
19}
diff --git a/src/lib/ecore/efl_mono_model_internal_child.eo b/src/lib/ecore/efl_mono_model_internal_child.eo
new file mode 100644
index 0000000000..5802e69e4f
--- /dev/null
+++ b/src/lib/ecore/efl_mono_model_internal_child.eo
@@ -0,0 +1,10 @@
1class Efl.Mono_Model_Internal_Child extends Efl.Object implements Efl.Model
2{
3 implements {
4 Efl.Object.constructor;
5 Efl.Object.destructor;
6 Efl.Model.properties { get; }
7 Efl.Model.property { get; set; }
8 Efl.Model.child_add;
9 }
10}
diff --git a/src/lib/ecore/meson.build b/src/lib/ecore/meson.build
index 2e44804481..eb65ce6cd0 100644
--- a/src/lib/ecore/meson.build
+++ b/src/lib/ecore/meson.build
@@ -78,6 +78,8 @@ pub_eo_files = [
78 'efl_core_env.eo', 78 'efl_core_env.eo',
79 'efl_core_proc_env.eo', 79 'efl_core_proc_env.eo',
80 'efl_core_command_line.eo', 80 'efl_core_command_line.eo',
81 'efl_mono_model_internal.eo',
82 'efl_mono_model_internal_child.eo'
81] 83]
82 84
83foreach eo_file : pub_eo_files 85foreach eo_file : pub_eo_files
@@ -159,6 +161,7 @@ ecore_src = [
159 'efl_model_accessor_view.c', 161 'efl_model_accessor_view.c',
160 'efl_model_accessor_view_private.h', 162 'efl_model_accessor_view_private.h',
161 'efl_view_model.c', 163 'efl_view_model.c',
164 'efl_mono_model_internal.c',
162 'efl_linear_interpolator.c', 165 'efl_linear_interpolator.c',
163 'efl_accelerate_interpolator.c', 166 'efl_accelerate_interpolator.c',
164 'efl_decelerate_interpolator.c', 167 'efl_decelerate_interpolator.c',
diff --git a/src/tests/efl_mono/Model.cs b/src/tests/efl_mono/Model.cs
new file mode 100644
index 0000000000..5a5f0536a4
--- /dev/null
+++ b/src/tests/efl_mono/Model.cs
@@ -0,0 +1,53 @@
1#define CODE_ANALYSIS
2
3using System;
4using System.Diagnostics.CodeAnalysis;
5
6namespace TestSuite {
7
8[SuppressMessage("Gendarme.Rules.Portability", "DoNotHardcodePathsRule")]
9public static class TestModel {
10
11 public class VeggieViewModel
12 {
13 public string Name { get; set; }
14 public string Type { get; set; }
15 public string Image { get; set; }
16 }
17
18 public static void reflection_test ()
19 {
20 Efl.UserModel<VeggieViewModel> veggies = new Efl.UserModel<VeggieViewModel>();
21 veggies.Add (new VeggieViewModel{ Name="Tomato", Type="Fruit", Image="tomato.png"});
22 veggies.Add (new VeggieViewModel{ Name="Romaine Lettuce", Type="Vegetable", Image="lettuce.png"});
23 veggies.Add (new VeggieViewModel{ Name="Zucchini", Type="Vegetable", Image="zucchini.png"});
24
25
26
27 Console.WriteLine ("end of test");
28 }
29
30 public static void easy_model_extraction ()
31 {
32 Efl.UserModel<VeggieViewModel> veggies = new Efl.UserModel<VeggieViewModel>();
33 veggies.Add (new VeggieViewModel{ Name="Tomato", Type="Fruit", Image="tomato.png"});
34 veggies.Add (new VeggieViewModel{ Name="Romaine Lettuce", Type="Vegetable", Image="lettuce.png"});
35 veggies.Add (new VeggieViewModel{ Name="Zucchini", Type="Vegetable", Image="zucchini.png"});
36
37 var model = new Efl.GenericModel<VeggieViewModel>(veggies);
38 Console.WriteLine ("size model {0}", model.GetChildrenCount());
39
40
41
42 Console.WriteLine ("end of test");
43 }
44
45 public static void factory_test ()
46 {
47 var factory = new Efl.Ui.ItemFactory<Efl.Object>();
48 //factory.Foo();
49 factory.Name().Bind("name");
50 }
51}
52
53}
diff --git a/src/tests/efl_mono/Parts.cs b/src/tests/efl_mono/Parts.cs
index 5afed1fdd6..10d8c50075 100644
--- a/src/tests/efl_mono/Parts.cs
+++ b/src/tests/efl_mono/Parts.cs
@@ -17,6 +17,21 @@ public static class TestParts
17 do_part_test(t); 17 do_part_test(t);
18 } 18 }
19 19
20 public static void dynamic_parts()
21 {
22 var t = new DynamicChild();
23 var s = t["a"];
24 }
25
26 private class DynamicChild : Dummy.TestObject
27 {
28 public string this[string key]
29 {
30 get { return ""; }
31 //set { dictionary[key] = value == null ? null : value.Trim(); }
32 }
33 }
34
20 private class Child : Dummy.TestObject 35 private class Child : Dummy.TestObject
21 { 36 {
22 public Child() : base(null) {} 37 public Child() : base(null) {}
diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build
index 350f1ee021..cc03b09988 100644
--- a/src/tests/efl_mono/meson.build
+++ b/src/tests/efl_mono/meson.build
@@ -59,6 +59,7 @@ efl_mono_src = [
59 'Events.cs', 59 'Events.cs',
60 'FunctionPointers.cs', 60 'FunctionPointers.cs',
61 'FunctionPointerMarshalling.cs', 61 'FunctionPointerMarshalling.cs',
62 'Model.cs',
62 'Parts.cs', 63 'Parts.cs',
63 'Promises.cs', 64 'Promises.cs',
64 'Strbuf.cs', 65 'Strbuf.cs',