summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2016-06-21 19:10:51 -0300
committerVitor Sousa <vitorsousasilva@gmail.com>2016-07-05 19:39:25 -0300
commit83e498d1ab666408882c02940123d7cb5ae6e0d3 (patch)
treeacc85a68efb2afbbd7fa1a4f2361179b03822885
parenta856b2d8ce1db558c3cf50b42703327f7df4db77 (diff)
efl: Add Efl.Model.Container and Efl.Model.Item
Add the classes Efl.Model.Container and Efl.Model.Item to efl/interfaces These classes are used to create Efl.Model objects with predefined property values. This is useful to create tests or in any situation where we want an Efl.Model with explicit defined property values.
-rw-r--r--src/Makefile_Efl.am30
-rw-r--r--src/lib/efl/Efl_Model_Common.h4
-rw-r--r--src/lib/efl/Makefile.am6
-rw-r--r--src/lib/efl/interfaces/efl_model_common.c6
-rw-r--r--src/lib/efl/interfaces/efl_model_container.c291
-rw-r--r--src/lib/efl/interfaces/efl_model_container.eo68
-rw-r--r--src/lib/efl/interfaces/efl_model_container_item.c187
-rw-r--r--src/lib/efl/interfaces/efl_model_container_item.eo39
-rw-r--r--src/lib/efl/interfaces/efl_model_item.c197
-rw-r--r--src/lib/efl/interfaces/efl_model_item.eo26
-rw-r--r--src/lib/efl/interfaces/efl_model_private.h32
-rw-r--r--src/lib/eo/eina_types.eot1
-rw-r--r--src/tests/efl/efl_suite.c51
-rw-r--r--src/tests/efl/efl_suite.h26
-rw-r--r--src/tests/efl/efl_test_model_container.c160
15 files changed, 1124 insertions, 0 deletions
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index 40909316f4..66eb7acd34 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -27,6 +27,9 @@ efl_eolian_files = \
27 lib/efl/interfaces/efl_gfx_filter.eo \ 27 lib/efl/interfaces/efl_gfx_filter.eo \
28 lib/efl/interfaces/efl_gfx_size_hint.eo \ 28 lib/efl/interfaces/efl_gfx_size_hint.eo \
29 lib/efl/interfaces/efl_model.eo \ 29 lib/efl/interfaces/efl_model.eo \
30 lib/efl/interfaces/efl_model_item.eo \
31 lib/efl/interfaces/efl_model_container.eo \
32 lib/efl/interfaces/efl_model_container_item.eo \
30 lib/efl/interfaces/efl_animator.eo \ 33 lib/efl/interfaces/efl_animator.eo \
31 lib/efl/interfaces/efl_orientation.eo \ 34 lib/efl/interfaces/efl_orientation.eo \
32 lib/efl/interfaces/efl_flipable.eo \ 35 lib/efl/interfaces/efl_flipable.eo \
@@ -76,6 +79,7 @@ EXTRA_DIST2 += \
76 lib/efl/Makefile.am \ 79 lib/efl/Makefile.am \
77 lib/efl/Makefile.in \ 80 lib/efl/Makefile.in \
78 lib/efl/interfaces/efl_common_internal.h \ 81 lib/efl/interfaces/efl_common_internal.h \
82 lib/efl/interfaces/efl_model_private.h \
79 $(efl_eolian_files) \ 83 $(efl_eolian_files) \
80 $(efl_eolian_type_files) 84 $(efl_eolian_type_files)
81 85
@@ -87,6 +91,9 @@ lib_LTLIBRARIES += lib/efl/libefl.la
87lib_efl_libefl_la_SOURCES = \ 91lib_efl_libefl_la_SOURCES = \
88lib/efl/interfaces/efl_interfaces_main.c \ 92lib/efl/interfaces/efl_interfaces_main.c \
89lib/efl/interfaces/efl_model_common.c \ 93lib/efl/interfaces/efl_model_common.c \
94lib/efl/interfaces/efl_model_item.c \
95lib/efl/interfaces/efl_model_container.c \
96lib/efl/interfaces/efl_model_container_item.c \
90lib/efl/interfaces/efl_gfx_shape.c \ 97lib/efl/interfaces/efl_gfx_shape.c \
91lib/efl/interfaces/efl_vpath_file.c \ 98lib/efl/interfaces/efl_vpath_file.c \
92lib/efl/interfaces/efl_vpath_manager.c \ 99lib/efl/interfaces/efl_vpath_manager.c \
@@ -158,3 +165,26 @@ bin_efl_efl_debug_CPPFLAGS = -I$(top_builddir)/src/bin/efl @EINA_CFLAGS@ @ECORE_
158bin_efl_efl_debug_LDADD = @EFL_LIBS@ @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@ 165bin_efl_efl_debug_LDADD = @EFL_LIBS@ @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@
159bin_efl_efl_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@ 166bin_efl_efl_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@
160 167
168
169if EFL_ENABLE_TESTS
170
171check_PROGRAMS += tests/efl/efl_suite
172TESTS += tests/efl/efl_suite
173
174tests_efl_efl_suite_SOURCES = \
175tests/efl/efl_suite.c \
176tests/efl/efl_test_model_container.c \
177tests/efl/efl_suite.h
178
179tests_efl_efl_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
180-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl\" \
181-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl\" \
182@CHECK_CFLAGS@ \
183@ECORE_CFLAGS@ \
184@EFL_CFLAGS@
185
186tests_efl_efl_suite_LDADD = @CHECK_LIBS@ @USE_EFL_LIBS@ @USE_ECORE_LIBS@
187tests_efl_efl_suite_DEPENDENCIES = @USE_EFL_INTERNAL_LIBS@
188
189endif
190
diff --git a/src/lib/efl/Efl_Model_Common.h b/src/lib/efl/Efl_Model_Common.h
index 68de92a0a1..e3a43c3599 100644
--- a/src/lib/efl/Efl_Model_Common.h
+++ b/src/lib/efl/Efl_Model_Common.h
@@ -10,6 +10,7 @@ EAPI extern Eina_Error EFL_MODEL_ERROR_READ_ONLY;
10EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED; 10EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED;
11EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE; 11EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE;
12EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED; 12EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED;
13EAPI extern Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT;
13 14
14/** 15/**
15 * @struct _Efl_Model_Children_Event 16 * @struct _Efl_Model_Children_Event
@@ -38,6 +39,9 @@ struct _Efl_Model_Children_Event
38typedef struct _Efl_Model_Children_Event Efl_Model_Children_Event; 39typedef struct _Efl_Model_Children_Event Efl_Model_Children_Event;
39 40
40#include "interfaces/efl_model.eo.h" 41#include "interfaces/efl_model.eo.h"
42#include "interfaces/efl_model_container.eo.h"
43#include "interfaces/efl_model_container_item.eo.h"
44#include "interfaces/efl_model_item.eo.h"
41 45
42EAPI int efl_model_init(void); 46EAPI int efl_model_init(void);
43 47
diff --git a/src/lib/efl/Makefile.am b/src/lib/efl/Makefile.am
index 3cae7dd8d3..8933ad8a06 100644
--- a/src/lib/efl/Makefile.am
+++ b/src/lib/efl/Makefile.am
@@ -27,6 +27,9 @@ interfaces/efl_gfx_gradient_radial.eo \
27interfaces/efl_gfx_filter.eo \ 27interfaces/efl_gfx_filter.eo \
28interfaces/efl_gfx_size_hint.eo \ 28interfaces/efl_gfx_size_hint.eo \
29interfaces/efl_model.eo \ 29interfaces/efl_model.eo \
30interfaces/efl_model_item.eo \
31interfaces/efl_model_container.eo \
32interfaces/efl_model_container_item.eo \
30interfaces/efl_animator.eo \ 33interfaces/efl_animator.eo \
31interfaces/efl_orientation.eo \ 34interfaces/efl_orientation.eo \
32interfaces/efl_flipable.eo \ 35interfaces/efl_flipable.eo \
@@ -64,6 +67,9 @@ lib_LTLIBRARIES = libefl.la
64libefl_la_SOURCES = \ 67libefl_la_SOURCES = \
65interfaces/efl_interfaces_main.c \ 68interfaces/efl_interfaces_main.c \
66interfaces/efl_model_common.c \ 69interfaces/efl_model_common.c \
70interfaces/efl_model_item.c \
71interfaces/efl_model_container.c \
72interfaces/efl_model_container_item.c \
67interfaces/efl_gfx_shape.c \ 73interfaces/efl_gfx_shape.c \
68interfaces/efl_vpath_file.c \ 74interfaces/efl_vpath_file.c \
69interfaces/efl_vpath_manager.c \ 75interfaces/efl_vpath_manager.c \
diff --git a/src/lib/efl/interfaces/efl_model_common.c b/src/lib/efl/interfaces/efl_model_common.c
index d25d1ff7a5..6aee4bae5a 100644
--- a/src/lib/efl/interfaces/efl_model_common.c
+++ b/src/lib/efl/interfaces/efl_model_common.c
@@ -12,6 +12,7 @@ EAPI Eina_Error EFL_MODEL_ERROR_READ_ONLY = 0;
12EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0; 12EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0;
13EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0; 13EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0;
14EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0; 14EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0;
15EAPI Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT = 0;
15 16
16static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error"; 17static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error";
17static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported"; 18static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
@@ -20,6 +21,8 @@ static const char EFL_MODEL_ERROR_READ_ONLY_STR[] = "Value read only";
20static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed"; 21static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed";
21static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied"; 22static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied";
22static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value"; 23static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value";
24static const char EFL_MODEL_ERROR_INVALID_OBJECT_STR[] = "Object is invalid";
25
23 26
24EAPI int 27EAPI int
25efl_model_init() 28efl_model_init()
@@ -45,6 +48,9 @@ efl_model_init()
45 EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register( 48 EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register(
46 EFL_MODEL_ERROR_PERMISSION_DENIED_STR); 49 EFL_MODEL_ERROR_PERMISSION_DENIED_STR);
47 50
51 EFL_MODEL_ERROR_INVALID_OBJECT = eina_error_msg_static_register(
52 EFL_MODEL_ERROR_INVALID_OBJECT_STR);
53
48 return EINA_TRUE; 54 return EINA_TRUE;
49} 55}
50 56
diff --git a/src/lib/efl/interfaces/efl_model_container.c b/src/lib/efl/interfaces/efl_model_container.c
new file mode 100644
index 0000000000..121722c2b0
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_container.c
@@ -0,0 +1,291 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Efl.h>
6
7#include "interfaces/efl_model_private.h"
8
9#define MY_CLASS EFL_MODEL_CONTAINER_CLASS
10
11void *
12_value_copy_alloc(void *v, const Eina_Value_Type *type)
13{
14 if (!v)
15 return v;
16
17 if (type == EINA_VALUE_TYPE_STRINGSHARE)
18 return (void*) eina_stringshare_ref(v);
19 else if (type == EINA_VALUE_TYPE_STRING)
20 return (void*) strdup(v);
21 else
22 {
23 void *ret = malloc(type->value_size);
24 memcpy(ret, v, type->value_size);
25 return ret;
26 }
27}
28
29void
30_value_free(void *v, const Eina_Value_Type *type)
31{
32 if (!v)
33 return;
34
35 if (type == EINA_VALUE_TYPE_STRINGSHARE)
36 return eina_stringshare_del(v);
37 else
38 free(v);
39}
40
41static void
42_values_free(Eina_Array *values, const Eina_Value_Type *type)
43{
44 unsigned int i;
45 void *v;
46 Eina_Array_Iterator it;
47 EINA_ARRAY_ITER_NEXT(values, i, v, it)
48 {
49 _value_free(v, type);
50 }
51 eina_array_free(values);
52}
53
54static Eina_Bool
55_stringshared_keys_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata EINA_UNUSED)
56{
57 eina_stringshare_del(key);
58 return EINA_TRUE;
59}
60
61static void
62_property_data_free_cb(void *data)
63{
64 Child_Property_Data *cpd = data;
65 _values_free(cpd->property_values, cpd->property_type);
66 free(cpd);
67}
68
69EOLIAN static Eo *
70_efl_model_container_eo_base_constructor(Eo *obj, Efl_Model_Container_Data *sd)
71{
72 obj = eo_constructor(eo_super(obj, MY_CLASS));
73 if (!obj)
74 return NULL;
75
76 sd->obj = obj;
77 sd->property_data = eina_hash_stringshared_new(_property_data_free_cb);
78 sd->defined_properties = eina_array_new(8);
79
80 return obj;
81}
82
83EOLIAN static void
84_efl_model_container_eo_base_destructor(Eo *obj, Efl_Model_Container_Data *sd)
85{
86 Efl_Model *child;
87
88 EINA_LIST_FREE(sd->children, child)
89 {
90 if (child)
91 {
92 efl_model_container_item_invalidate(child);
93 eo_parent_set(child, NULL);
94 }
95 }
96
97 eina_array_free(sd->defined_properties);
98
99 eina_hash_foreach(sd->property_data, _stringshared_keys_free, NULL);
100 eina_hash_free(sd->property_data);
101
102 eo_destructor(eo_super(obj, MY_CLASS));
103}
104
105EOLIAN static const Eina_Value_Type *
106_efl_model_container_child_property_value_type_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property)
107{
108 Eina_Stringshare *sshared = eina_stringshare_add(property);
109 Child_Property_Data *cpd = eina_hash_find(sd->property_data, sshared);
110 eina_stringshare_del(sshared);
111 if (!cpd)
112 return NULL;
113
114 return cpd->property_type;
115}
116
117EOLIAN static Eina_Iterator *
118_efl_model_container_child_property_values_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property)
119{
120 Eina_Stringshare *sshared = eina_stringshare_add(property);
121 Child_Property_Data *cpd = eina_hash_find(sd->property_data, sshared);
122 eina_stringshare_del(sshared);
123 if (!cpd)
124 return NULL;
125
126 return eina_array_iterator_new(cpd->property_values);
127}
128
129EOLIAN static Eina_Bool
130_efl_model_container_child_property_add(Eo *obj, Efl_Model_Container_Data *sd, const char *name, const Eina_Value_Type *type, Eina_Iterator *values)
131{
132 Eina_Array *arr = NULL;
133 void *data = NULL;
134 Eina_Stringshare *prop_name = NULL;
135 Child_Property_Data *cpd = NULL;
136 unsigned int i, in_count, children_count;
137
138 if (!type || !values)
139 {
140 EINA_LOG_WARN("Invalid input data");
141 eina_error_set(EFL_MODEL_ERROR_INCORRECT_VALUE);
142 return EINA_FALSE;
143 }
144
145 arr = eina_array_new(32);
146 if (!arr)
147 {
148 eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
149 return EINA_FALSE;
150 }
151
152 EINA_ITERATOR_FOREACH(values, data)
153 {
154 void *new_data = _value_copy_alloc(data, type);
155 if ((data && !new_data) || !eina_array_push(arr, new_data))
156 {
157 if (new_data)
158 _value_free(new_data, type);
159 goto error;
160 }
161 }
162 eina_iterator_free(values);
163
164 prop_name = eina_stringshare_add(name);
165 cpd = eina_hash_find(sd->property_data, prop_name);
166 if (!cpd)
167 {
168 cpd = calloc(1, sizeof(Child_Property_Data));
169 if (!cpd)
170 goto error;
171
172 cpd->property_type = type;
173 cpd->property_values = arr;
174
175 if (!eina_array_push(sd->defined_properties, prop_name))
176 goto error;
177
178 if (!eina_hash_direct_add(sd->property_data, prop_name, cpd))
179 {
180 eina_array_pop(sd->defined_properties);
181 goto error;
182 }
183 }
184 else
185 {
186 eina_stringshare_del(prop_name);
187 _values_free(cpd->property_values, cpd->property_type);
188
189 cpd->property_type = type;
190 cpd->property_values = arr;
191 }
192
193 in_count = eina_array_count(arr);
194 children_count = eina_list_count(sd->children);
195
196 for (i = children_count; i < in_count; ++i)
197 {
198 Efl_Model_Children_Event cevt;
199 Efl_Model *child;
200
201 child = eo_add(EFL_MODEL_CONTAINER_ITEM_CLASS, obj,
202 efl_model_container_item_define(eo_self, sd, i));
203 sd->children = eina_list_append(sd->children, child);
204
205 cevt.child = child;
206 cevt.index = i;
207 eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
208 }
209
210 if (in_count > children_count)
211 eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &in_count);
212
213 return EINA_TRUE;
214
215error:
216 if (prop_name)
217 eina_stringshare_del(prop_name);
218 if (cpd)
219 free(cpd);
220 if (arr)
221 _values_free(arr, type);
222 eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
223 return EINA_FALSE;
224}
225
226EOLIAN static const Eina_Array *
227_efl_model_container_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED)
228{
229 return sd->defined_properties;
230}
231
232
233EOLIAN static void
234_efl_model_container_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, const char *property EINA_UNUSED, const Eina_Value *value EINA_UNUSED, Eina_Promise_Owner *promise_owner)
235{
236 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
237}
238
239EOLIAN static Eina_Promise *
240_efl_model_container_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, const char *property EINA_UNUSED)
241{
242 Eina_Promise_Owner *promise_owner = eina_promise_add();
243 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
244
245 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
246
247 return rpromise;
248}
249
250EOLIAN static Eina_Promise *
251_efl_model_container_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, unsigned int start, unsigned int count)
252{
253 Eina_Promise_Owner *promise_owner = eina_promise_add();
254 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
255
256 Eina_Accessor* accessor = efl_model_list_slice(sd->children, start, count);
257 eina_promise_owner_value_set(promise_owner, accessor, (Eina_Promise_Free_Cb)&eina_accessor_free);
258
259 return rpromise;
260}
261
262EOLIAN static Eina_Promise *
263_efl_model_container_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd)
264{
265 Eina_Promise_Owner *promise_owner = eina_promise_add();
266 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
267
268 unsigned int *count = calloc(1, sizeof(unsigned int));
269 *count = eina_list_count(sd->children);
270 eina_promise_owner_value_set(promise_owner, count, &free);
271
272 return rpromise;
273}
274
275EOLIAN static Eo *
276_efl_model_container_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED)
277{
278 EINA_LOG_WARN("child_add not supported by Efl.Model.Container");
279 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
280
281 return NULL;
282}
283
284EOLIAN static void
285_efl_model_container_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED)
286{
287 EINA_LOG_WARN("child_del not supported by Efl.Model.Container");
288 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
289}
290
291#include "interfaces/efl_model_container.eo.c"
diff --git a/src/lib/efl/interfaces/efl_model_container.eo b/src/lib/efl/interfaces/efl_model_container.eo
new file mode 100644
index 0000000000..665106431e
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_container.eo
@@ -0,0 +1,68 @@
1import eina_types;
2
3class Efl.Model.Container (Eo.Base, Efl.Model)
4{
5 [[
6 Class used to create data models from Eina containers.
7
8 Each container supplied represent a series of property values, each item
9 being the property value for a child object (@Efl.Model.Container.Item).
10
11 The data in the given containers are copied and stored internally.
12
13 Several containers can be supplied, and the number of allocated children is
14 based on the container with the biggest size.
15 As illustrated above:
16
17 |‾‾‾‾‾||‾‾‾‾‾||‾‾‾‾‾||‾‾‾‾‾| <br/>
18 cont1, property: "code" -> ["A"] ["B"] ["C"] ["D"] <br/>
19 cont2, property: "day" -> [ 8 ] [ 24] [ 14] <br/>
20 |_____||_____||_____||_____| <br/>
21 | | | | <br/>
22 child1 child2 child3 child4 <br/>
23 ]]
24 methods {
25 child_property_value_type_get {
26 [[Get the type of the given property.]]
27 params {
28 name: string; [[Property name]]
29 }
30 return: const(Eina.Value.Type)*; [[Property type]]
31 }
32 child_property_values_get {
33 [[Get the values for the given property.]]
34 params {
35 name: string; [[Property name]]
36 }
37 return: free(own(iterator<void_ptr>), eina_iterator_free) @warn_unused;
38 [[The currently wrapped values]]
39 }
40 child_property_add {
41 [[Add the given property to child objects and supply the values.
42
43 Each item will represent the value of the given property in the
44 respective child within the data model.
45
46 New children objects are allocated as necessary.
47
48 Value type is required for compatibility with the @Efl.Model API.]]
49 params {
50 name: string; [[Property name]]
51 type: const(Eina.Value.Type)*; [[Property type]]
52 values: own(iterator<const(void_ptr)>); [[Values to be added]]
53 }
54 return: bool; [[$true on success, $false otherwise]]
55 }
56 }
57 implements {
58 Eo.Base.constructor;
59 Eo.Base.destructor;
60 Efl.Model.properties.get;
61 Efl.Model.property_set;
62 Efl.Model.property_get;
63 Efl.Model.child_add;
64 Efl.Model.child_del;
65 Efl.Model.children_slice_get;
66 Efl.Model.children_count_get;
67 }
68}
diff --git a/src/lib/efl/interfaces/efl_model_container_item.c b/src/lib/efl/interfaces/efl_model_container_item.c
new file mode 100644
index 0000000000..6d4e97d028
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_container_item.c
@@ -0,0 +1,187 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Efl.h>
6
7#include "interfaces/efl_model_private.h"
8
9#define MY_CLASS EFL_MODEL_CONTAINER_ITEM_CLASS
10
11static void
12_item_value_free_cb(void *data)
13{
14 eina_value_free(data);
15}
16
17EOLIAN static void
18_efl_model_container_item_define(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, void *parent_data, unsigned int index)
19{
20 sd->parent_data = parent_data;
21 sd->index = index;
22}
23
24EOLIAN static void
25_efl_model_container_item_invalidate(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd)
26{
27 sd->parent_data = NULL;
28 sd->index = 0;
29}
30
31EOLIAN static const Eina_Array *
32_efl_model_container_item_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd)
33{
34 if (!sd->parent_data)
35 return NULL;
36
37 return sd->parent_data->defined_properties;
38}
39
40EOLIAN static void
41_efl_model_container_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, const char *property, const Eina_Value *value, Eina_Promise_Owner *promise_owner)
42{
43 Eina_Stringshare *prop_name;
44 Child_Property_Data *cpd;
45 void *data, *new_data;
46
47 if (!sd->parent_data)
48 {
49 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_INVALID_OBJECT);
50 return;
51 }
52
53 prop_name = eina_stringshare_add(property);
54 cpd = eina_hash_find(sd->parent_data->property_data, prop_name);
55 eina_stringshare_del(prop_name);
56 if (!cpd || !cpd->property_values ||
57 sd->index >= eina_array_count_get(cpd->property_values))
58 {
59 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
60 return;
61 }
62
63 if (cpd->property_type != eina_value_type_get(value))
64 {
65 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_INCORRECT_VALUE);
66 return;
67 }
68
69 data = calloc(1, cpd->property_type->value_size);
70 if (!data || !eina_value_pget(value, data))
71 {
72 if (data)
73 free(data);
74 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
75 return;
76 }
77
78 new_data = _value_copy_alloc(data, cpd->property_type);
79 free(data);
80
81 _value_free(eina_array_data_get(cpd->property_values, sd->index), cpd->property_type);
82 eina_array_data_set(cpd->property_values, sd->index, new_data);
83
84 {
85 Eina_Value *v = eina_value_new(cpd->property_type);
86 if (v && eina_value_copy(value, v))
87 eina_promise_owner_value_set(promise_owner, v, _item_value_free_cb);
88 else
89 {
90 if (v)
91 eina_value_free(v);
92 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
93 }
94 }
95}
96
97EOLIAN static Eina_Promise *
98_efl_model_container_item_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, const char *property)
99{
100 Eina_Stringshare *prop_name;
101 Child_Property_Data *cpd;
102 Eina_Value *value;
103 Eina_Promise_Owner *promise_owner = eina_promise_add();
104 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
105
106 if (!sd->parent_data)
107 {
108 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_INVALID_OBJECT);
109 return rpromise;
110 }
111
112 prop_name = eina_stringshare_add(property);
113 cpd = eina_hash_find(sd->parent_data->property_data, prop_name);
114 eina_stringshare_del(prop_name);
115 if (!cpd || !cpd->property_values ||
116 sd->index >= eina_array_count_get(cpd->property_values))
117 {
118 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
119 return rpromise;
120 }
121
122 value = eina_value_new(cpd->property_type);
123 if (!value)
124 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
125 else
126 {
127 Eina_Bool r = EINA_FALSE;
128 void *data = eina_array_data_get(cpd->property_values, sd->index);
129
130 if (cpd->property_type == EINA_VALUE_TYPE_STRINGSHARE ||
131 cpd->property_type == EINA_VALUE_TYPE_STRING)
132 r = eina_value_set(value, data);
133 else
134 r = eina_value_pset(value, data);
135
136 if (r)
137 eina_promise_owner_value_set(promise_owner, value, _item_value_free_cb);
138 else
139 {
140 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
141 eina_value_free(value);
142 }
143 }
144 return rpromise;
145}
146
147EOLIAN static Eina_Promise *
148_efl_model_container_item_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED, unsigned int start EINA_UNUSED, unsigned int count EINA_UNUSED)
149{
150 Eina_Promise_Owner *promise_owner = eina_promise_add();
151 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
152
153 eina_promise_owner_value_set(promise_owner, NULL, NULL);
154
155 return rpromise;
156}
157
158EOLIAN static Eina_Promise *
159_efl_model_container_item_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED)
160{
161 Eina_Promise_Owner *promise_owner = eina_promise_add();
162 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
163
164 unsigned int *count = calloc(1, sizeof(unsigned int));
165 *count = 0;
166 eina_promise_owner_value_set(promise_owner, count, &free);
167
168 return rpromise;
169}
170
171EOLIAN static Eo *
172_efl_model_container_item_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED)
173{
174 EINA_LOG_WARN("child_add not supported by Efl.Model.Container.Item");
175 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
176
177 return NULL;
178}
179
180EOLIAN static void
181_efl_model_container_item_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED)
182{
183 EINA_LOG_WARN("child_del not supported by Efl.Model.Container.Item");
184 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
185}
186
187#include "interfaces/efl_model_container_item.eo.c"
diff --git a/src/lib/efl/interfaces/efl_model_container_item.eo b/src/lib/efl/interfaces/efl_model_container_item.eo
new file mode 100644
index 0000000000..6a6703e919
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_container_item.eo
@@ -0,0 +1,39 @@
1import eina_types;
2
3class Efl.Model.Container.Item (Eo.Base, Efl.Model)
4{
5 [[
6 Used as a child of @Efl.Model.Container.
7
8 Provides the @Efl.Model API for elements of @Efl.Model.Container.
9 Should not be used in another context, so do not manually create objects
10 of this class.
11 ]]
12 methods {
13 define {
14 [[Define @Efl.Model.Container.Item internal data.]]
15 params {
16 parent_data: void_ptr; [[Pointer to the private data of the
17 @Efl.Model.Container parent object.]]
18 index: uint; [[Index of this item within the @Efl.Model.Container
19 children.]]
20 }
21 }
22 invalidate {
23 [[Invalidate the object preventing it from using the given parent
24 data.]]
25 }
26 }
27 implements {
28 Efl.Model.properties.get;
29 Efl.Model.property_set;
30 Efl.Model.property_get;
31 Efl.Model.child_add;
32 Efl.Model.child_del;
33 Efl.Model.children_slice_get;
34 Efl.Model.children_count_get;
35 }
36 constructors {
37 .define;
38 }
39}
diff --git a/src/lib/efl/interfaces/efl_model_item.c b/src/lib/efl/interfaces/efl_model_item.c
new file mode 100644
index 0000000000..6191d3b025
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_item.c
@@ -0,0 +1,197 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Efl.h>
6
7#define MY_CLASS EFL_MODEL_ITEM_CLASS
8
9typedef struct _Efl_Model_Item_Data Efl_Model_Item_Data;
10struct _Efl_Model_Item_Data
11{
12 Eina_Hash *properties;
13 Eina_Array *defined_properties;
14 Eina_List *children;
15};
16
17static void
18_item_value_free_cb(void *data)
19{
20 eina_value_free(data);
21}
22
23static Eina_Bool
24_stringshared_keys_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata EINA_UNUSED)
25{
26 eina_stringshare_del(key);
27 return EINA_TRUE;
28}
29
30EOLIAN static Eo *
31_efl_model_item_eo_base_constructor(Eo *obj, Efl_Model_Item_Data *sd)
32{
33 obj = eo_constructor(eo_super(obj, MY_CLASS));
34 if (!obj)
35 return NULL;
36
37 sd->properties = eina_hash_stringshared_new(_item_value_free_cb);
38 sd->defined_properties = eina_array_new(8);
39
40 return obj;
41}
42
43EOLIAN static void
44_efl_model_item_eo_base_destructor(Eo *obj, Efl_Model_Item_Data *sd)
45{
46 Efl_Model *child;
47
48 EINA_LIST_FREE(sd->children, child)
49 {
50 if (child)
51 eo_parent_set(child, NULL);
52 }
53
54 eina_hash_foreach(sd->properties, _stringshared_keys_free, NULL);
55 eina_hash_free(sd->properties);
56
57 eina_array_free(sd->defined_properties);
58
59 eo_destructor(eo_super(obj, MY_CLASS));
60}
61
62EOLIAN static const Eina_Array *
63_efl_model_item_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd)
64{
65 return sd->defined_properties;
66}
67
68
69EOLIAN static void
70_efl_model_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, const char *property, const Eina_Value *value, Eina_Promise_Owner *promise_owner)
71{
72 Eina_Stringshare *sshared = eina_stringshare_add(property);
73 Eina_Value *p_v = eina_hash_find(sd->properties, sshared);
74 if (p_v)
75 {
76 eina_stringshare_del(sshared);
77 if (!eina_value_copy(value, p_v))
78 goto err1;
79 }
80 else
81 {
82 if (!eina_array_push(sd->defined_properties, sshared))
83 goto err2;
84
85 p_v = eina_value_new(eina_value_type_get(value));
86 if (!p_v)
87 goto err3;
88
89 if (!eina_value_copy(value, p_v) ||
90 !eina_hash_direct_add(sd->properties, sshared, p_v))
91 goto err4;
92 }
93
94 eina_promise_owner_value_set(promise_owner, p_v, NULL);
95 return;
96
97err4:
98 eina_value_free(p_v);
99err3:
100 eina_array_pop(sd->defined_properties);
101err2:
102 eina_stringshare_del(sshared);
103err1:
104 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
105}
106
107EOLIAN static Eina_Promise *
108_efl_model_item_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, const char *property)
109{
110 Eina_Promise_Owner *promise_owner = eina_promise_add();
111 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
112
113 Eina_Stringshare *sshare = eina_stringshare_add(property);
114 Eina_Value *p_v = eina_hash_find(sd->properties, sshare);
115 eina_stringshare_del(sshare);
116 if (p_v)
117 eina_promise_owner_value_set(promise_owner, p_v, NULL);
118 else
119 eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
120
121 return rpromise;
122}
123
124EOLIAN static Eina_Promise *
125_efl_model_item_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, unsigned int start, unsigned int count)
126{
127 Eina_Promise_Owner *promise_owner = eina_promise_add();
128 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
129
130 Eina_Accessor* accessor = efl_model_list_slice(sd->children, start, count);
131 eina_promise_owner_value_set(promise_owner, accessor, (Eina_Promise_Free_Cb)&eina_accessor_free);
132
133 return rpromise;
134}
135
136EOLIAN static Eina_Promise *
137_efl_model_item_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd)
138{
139 Eina_Promise_Owner *promise_owner = eina_promise_add();
140 Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
141
142 unsigned int *count = calloc(1, sizeof(unsigned int));
143 *count = eina_list_count(sd->children);
144 eina_promise_owner_value_set(promise_owner, count, &free);
145
146 return rpromise;
147}
148
149EOLIAN static Eo *
150_efl_model_item_efl_model_child_add(Eo *obj, Efl_Model_Item_Data *sd)
151{
152 Efl_Model_Children_Event cevt;
153 Efl_Model *child = eo_add(EFL_MODEL_ITEM_CLASS, obj);
154 if (!child)
155 {
156 EINA_LOG_ERR("Could not allocate Efl.Model.Item");
157 eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
158 return NULL;
159 }
160 sd->children = eina_list_append(sd->children, child);
161 cevt.child = child;
162 cevt.index = eina_list_count(sd->children);
163 eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
164 eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &cevt.index);
165 return child;
166}
167
168EOLIAN static void
169_efl_model_item_efl_model_child_del(Eo *obj, Efl_Model_Item_Data *sd, Eo *child)
170{
171 Eina_List *l;
172 Efl_Model *data;
173 unsigned int i = 0;
174 EINA_LIST_FOREACH(sd->children, l, data)
175 {
176 if (data == child)
177 {
178 Efl_Model_Children_Event cevt;
179 sd->children = eina_list_remove_list(sd->children, l);
180
181 cevt.child = eo_ref(child);
182 cevt.index = i;
183
184 eo_parent_set(child, NULL);
185
186 eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_REMOVED, &cevt);
187 eo_unref(child);
188
189 i = eina_list_count(sd->children);
190 eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &i);
191 break;
192 }
193 ++i;
194 }
195}
196
197#include "interfaces/efl_model_item.eo.c"
diff --git a/src/lib/efl/interfaces/efl_model_item.eo b/src/lib/efl/interfaces/efl_model_item.eo
new file mode 100644
index 0000000000..8fca4b67c8
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_item.eo
@@ -0,0 +1,26 @@
1import eina_types;
2
3class Efl.Model.Item (Eo.Base, Efl.Model)
4{
5 [[
6 Generic model that allows any property to be manually set.
7 Also children of the same type can be added and deleted.
8
9 Intended to be used in scenarios where the user needs a manually defined
10 data model, like in tests.
11
12 It does not model anything in particular and does not affect anything else
13 in the system.
14 ]]
15 implements {
16 Eo.Base.constructor;
17 Eo.Base.destructor;
18 Efl.Model.properties.get;
19 Efl.Model.property_set;
20 Efl.Model.property_get;
21 Efl.Model.child_add;
22 Efl.Model.child_del;
23 Efl.Model.children_slice_get;
24 Efl.Model.children_count_get;
25 }
26}
diff --git a/src/lib/efl/interfaces/efl_model_private.h b/src/lib/efl/interfaces/efl_model_private.h
new file mode 100644
index 0000000000..0a0aad1be6
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_model_private.h
@@ -0,0 +1,32 @@
1#ifndef EFL_MODEL_PRIVATE_H__
2# define EFL_MODEL_PRIVATE_H__
3
4typedef struct _Child_Property_Data Child_Property_Data;
5struct _Child_Property_Data
6{
7 const Eina_Value_Type *property_type;
8 Eina_Array *property_values;
9};
10
11typedef struct _Efl_Model_Container_Data Efl_Model_Container_Data;
12struct _Efl_Model_Container_Data
13{
14 Eo *obj;
15 Eina_Hash *property_data;
16 Eina_Array *defined_properties;
17 Eina_List *children;
18};
19
20
21typedef struct _Efl_Model_Container_Item_Data Efl_Model_Container_Item_Data;
22struct _Efl_Model_Container_Item_Data
23{
24 Efl_Model_Container_Data *parent_data;
25 unsigned int index;
26};
27
28void *_value_copy_alloc(void *v, const Eina_Value_Type *type);
29
30void _value_free(void *v, const Eina_Value_Type *type);
31
32#endif
diff --git a/src/lib/eo/eina_types.eot b/src/lib/eo/eina_types.eot
index d043da3000..92fc383787 100644
--- a/src/lib/eo/eina_types.eot
+++ b/src/lib/eo/eina_types.eot
@@ -40,3 +40,4 @@ enum @extern Eina.Xattr.Flags {
40 created [[This will only succeed if the extended attribute wasn't previously set]] 40 created [[This will only succeed if the extended attribute wasn't previously set]]
41} 41}
42 42
43struct @extern Eina.Value.Type;
diff --git a/src/tests/efl/efl_suite.c b/src/tests/efl/efl_suite.c
new file mode 100644
index 0000000000..653aac2201
--- /dev/null
+++ b/src/tests/efl/efl_suite.c
@@ -0,0 +1,51 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <Eina.h>
24
25#include "efl_suite.h"
26#include "../efl_check.h"
27
28static const Efl_Test_Case etc[] = {
29 { "Efl_Model_Container", efl_test_case_model_container },
30 { NULL, NULL }
31};
32
33int
34main(int argc, char **argv)
35{
36 int failed_count;
37
38 if (!_efl_test_option_disp(argc, argv, etc))
39 return 0;
40
41 putenv("EFL_RUN_IN_TREE=1");
42
43 eina_init();
44
45 failed_count = _efl_suite_build_and_run(argc - 1, (const char **)argv + 1,
46 "Efl", etc);
47
48 eina_shutdown();
49
50 return (failed_count == 0) ? 0 : 255;
51}
diff --git a/src/tests/efl/efl_suite.h b/src/tests/efl/efl_suite.h
new file mode 100644
index 0000000000..d5a7caa9ec
--- /dev/null
+++ b/src/tests/efl/efl_suite.h
@@ -0,0 +1,26 @@
1/* EFL - EFL library
2 * Copyright (C) 2008 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef EFL_SUITE_H_
20#define EFL_SUITE_H_
21
22#include <check.h>
23
24void efl_test_case_model_container(TCase *tc);
25
26#endif /* EFL_SUITE_H_ */
diff --git a/src/tests/efl/efl_test_model_container.c b/src/tests/efl/efl_test_model_container.c
new file mode 100644
index 0000000000..1d4c0d2161
--- /dev/null
+++ b/src/tests/efl/efl_test_model_container.c
@@ -0,0 +1,160 @@
1/* EFL - EFL library
2 * Copyright (C) 2013 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include "efl_suite.h"
24
25#include <Ecore.h>
26#include <Efl.h>
27
28typedef struct _Test_Container_Data {
29 int item_count;
30 Eina_Bool pass_flag;
31 Eina_Bool fail_flag;
32} Test_Container_Data;
33
34typedef struct _Test_Container_Item_Data {
35 Test_Container_Data* test_data;
36 unsigned int index;
37} Test_Container_Item_Data;
38
39const int base_int[7] = {10, 11, 12, 13, 14, 0, 16};
40const char * const base_str[7] = {"A", "B", "C", "D", "E", "", "GH"};
41
42static void
43_container_property_get_then(void *data, void *values)
44{
45 Eina_Iterator *value_itt = values;
46 Test_Container_Item_Data *test_item_data = data;
47 Eina_Value *value_int = NULL;
48 Eina_Value *value_str = NULL;
49 int cmp_int = 0;
50 const char *cmp_str = NULL;
51
52 test_item_data->test_data->item_count++;
53
54 if (!eina_iterator_next(value_itt, (void**)&value_int) ||
55 !eina_iterator_next(value_itt, (void**)&value_str))
56 {
57 test_item_data->test_data->fail_flag = EINA_TRUE;
58 return;
59 }
60
61 eina_value_get(value_int, &cmp_int);
62 eina_value_get(value_str, &cmp_str);
63
64 if (cmp_int != base_int[test_item_data->index] ||
65 strcmp(cmp_str, base_str[test_item_data->index]) != 0)
66 {
67 test_item_data->test_data->fail_flag = EINA_TRUE;
68 }
69
70 if (test_item_data->test_data->item_count == 7)
71 {
72 test_item_data->test_data->pass_flag = EINA_TRUE;
73 }
74}
75
76static void
77_children_slice_promise_then(void *data, void *value)
78{
79 Eina_Accessor *children_accessor = value;
80 unsigned int i = 0;
81 Efl_Model *child;
82
83 if (children_accessor)
84 {
85 EINA_ACCESSOR_FOREACH(children_accessor, i, child)
86 {
87 Eina_Promise *promises[3] = {NULL,};
88 Eina_Promise *promise_all = NULL;
89 Test_Container_Item_Data *test_item_data = calloc(1, sizeof(Test_Container_Item_Data));
90
91 test_item_data->test_data = data;
92 test_item_data->index = i;
93
94 promises[0] = efl_model_property_get(child, "test_p_int");
95 promises[1] = efl_model_property_get(child, "test_p_str");
96
97 promise_all = eina_promise_all(eina_carray_iterator_new((void**)promises));
98 eina_promise_then(promise_all, _container_property_get_then, NULL, test_item_data);
99 }
100 }
101}
102
103
104START_TEST(efl_test_model_container_values)
105{
106 Efl_Model_Container* model;
107 Eina_Promise *promise;
108 Test_Container_Data test_data;
109 int **cmp_int;
110 const char **cmp_str;
111 int i;
112
113 eo_init();
114
115 cmp_int = calloc(8, sizeof(int*));
116 cmp_str = calloc(8, sizeof(const char*));
117 for (i = 0; i < 7; ++i)
118 {
119 cmp_int[i] = calloc(1, sizeof(int));
120 *(cmp_int[i]) = base_int[i];
121 cmp_str[i] = strdup(base_str[i]);
122 }
123
124 model = eo_add(EFL_MODEL_CONTAINER_CLASS, NULL);
125
126 efl_model_container_child_property_add(model, "test_p_int", EINA_VALUE_TYPE_INT,
127 eina_carray_iterator_new((void**)cmp_int));
128 efl_model_container_child_property_add(model, "test_p_str", EINA_VALUE_TYPE_STRING,
129 eina_carray_iterator_new((void**)cmp_str));
130
131 for (i = 0; i < 7; ++i)
132 {
133 free(cmp_int[i]);
134 free(cmp_str[i]);
135 }
136 free(cmp_int);
137 free(cmp_str);
138
139 promise = efl_model_children_slice_get(model, 0, 0);
140
141 test_data.item_count = 0;
142 test_data.pass_flag = EINA_FALSE;
143 test_data.fail_flag = EINA_FALSE;
144
145 eina_promise_then(promise, _children_slice_promise_then, NULL, &test_data);
146
147 ecore_main_loop_iterate();
148
149 ck_assert(!!test_data.pass_flag);
150 ck_assert(!test_data.fail_flag);
151
152 eo_shutdown();
153}
154END_TEST
155
156void
157efl_test_case_model_container(TCase *tc)
158{
159 tcase_add_test(tc, efl_test_model_container_values);
160}