summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-20 18:50:38 -0300
committerLarry Jr <larry.olj@gmail.com>2017-02-01 14:45:50 -0200
commitb7d1a1c688558d340715b76952b2b6b4d423a1a5 (patch)
tree5dafc5fcf06bdd14ad31f92e642e19357e8a7105
parent2b044b9bc20bcb78f89f459fbda72e298196bf9b (diff)
efl: Add composite model for boolean propertiesdevs/felipealmeida/efl_ui_connect
Add Efl.Model.Composite.Boolean, a model for wrapping another Efl.Model and adding boolean properties to its children. Children of the given composite model will have the boolean properties specified in Efl.Model.Composite.Boolean with the specified default value. A call to Efl.Model.Property_set can change the property value for a child.
-rw-r--r--src/Makefile_Ecore.am3
-rw-r--r--src/Makefile_Efl.am1
-rw-r--r--src/lib/ecore/Ecore_Eo.h2
-rw-r--r--src/lib/ecore/efl_model_composite_boolean.c642
-rw-r--r--src/lib/ecore/efl_model_composite_boolean.eo34
-rw-r--r--src/lib/ecore/efl_model_composite_boolean_children.eo13
-rw-r--r--src/tests/efl/efl_suite.c1
-rw-r--r--src/tests/efl/efl_suite.h1
-rw-r--r--src/tests/efl/efl_test_model_composite_boolean.c155
9 files changed, 852 insertions, 0 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index 3cb58b6b43..97b91f0c89 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -29,6 +29,8 @@ ecore_eolian_files = \
29 lib/ecore/efl_model_item.eo \ 29 lib/ecore/efl_model_item.eo \
30 lib/ecore/efl_model_container.eo \ 30 lib/ecore/efl_model_container.eo \
31 lib/ecore/efl_model_container_item.eo \ 31 lib/ecore/efl_model_container_item.eo \
32 lib/ecore/efl_model_composite_boolean.eo \
33 lib/ecore/efl_model_composite_boolean_children.eo \
32 $(ecore_eolian_files_legacy) 34 $(ecore_eolian_files_legacy)
33 35
34ecore_eolian_type_files = \ 36ecore_eolian_type_files = \
@@ -93,6 +95,7 @@ lib/ecore/efl_model_item.c \
93lib/ecore/efl_model_container.c \ 95lib/ecore/efl_model_container.c \
94lib/ecore/efl_model_container_item.c \ 96lib/ecore/efl_model_container_item.c \
95lib/ecore/efl_model_container_private.h \ 97lib/ecore/efl_model_container_private.h \
98lib/ecore/efl_model_composite_boolean.c \
96lib/ecore/ecore_pipe.c \ 99lib/ecore/ecore_pipe.c \
97lib/ecore/ecore_poller.c \ 100lib/ecore/ecore_poller.c \
98lib/ecore/ecore_time.c \ 101lib/ecore/ecore_time.c \
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index faccdf5bac..a8fbf038c7 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -184,6 +184,7 @@ TESTS += tests/efl/efl_suite
184tests_efl_efl_suite_SOURCES = \ 184tests_efl_efl_suite_SOURCES = \
185tests/efl/efl_suite.c \ 185tests/efl/efl_suite.c \
186tests/efl/efl_test_model_container.c \ 186tests/efl/efl_test_model_container.c \
187tests/efl/efl_test_model_composite_boolean.c \
187tests/efl/efl_suite.h 188tests/efl/efl_suite.h
188 189
189tests_efl_efl_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ 190tests_efl_efl_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 1c29de392c..2a250fca29 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -125,6 +125,8 @@ EAPI Efl_Future *efl_future_iterator_race(Eina_Iterator *it);
125#include "efl_model_item.eo.h" 125#include "efl_model_item.eo.h"
126#include "efl_model_container.eo.h" 126#include "efl_model_container.eo.h"
127#include "efl_model_container_item.eo.h" 127#include "efl_model_container_item.eo.h"
128#include "efl_model_composite_boolean.eo.h"
129#include "efl_model_composite_boolean_children.eo.h"
128 130
129/** 131/**
130 * @} 132 * @}
diff --git a/src/lib/ecore/efl_model_composite_boolean.c b/src/lib/ecore/efl_model_composite_boolean.c
new file mode 100644
index 0000000000..7ec344d05c
--- /dev/null
+++ b/src/lib/ecore/efl_model_composite_boolean.c
@@ -0,0 +1,642 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eina.h"
6#include "Efl.h"
7#include <Ecore.h>
8
9#include "efl_model_composite_boolean_children.eo.h"
10
11typedef struct _Efl_Model_Hash_Value
12{
13 unsigned char *buffer;
14 unsigned int bits_count;
15 Eina_Bool default_value : 1;
16} Efl_Model_Hash_Value;
17
18typedef struct _Efl_Model_Composite_Boolean_Data
19{
20 Efl_Model *composite_model;
21 Eina_Array *bool_children_cache;
22 Eina_Array *empty_properties;
23 Eina_Hash *values; // [property_name, Efl_Model_Hash_Value*]
24} Efl_Model_Composite_Boolean_Data;
25
26typedef struct _Efl_Model_Composite_Boolean_Children_Data
27{
28 Efl_Model_Composite_Boolean_Data *parent_pd;
29 Efl_Model *composite_child;
30 Eina_Array *properties_names;
31 unsigned int index;
32} Efl_Model_Composite_Boolean_Children_Data;
33
34typedef struct _Efl_Model_Accessor_Slice
35{
36 Eina_Accessor vtable;
37 Eina_Accessor *real_accessor;
38 Efl_Model *parent;
39 Efl_Model_Composite_Boolean_Data *parent_pd;
40 Efl_Promise *promise;
41 unsigned int index;
42} Efl_Model_Accessor_Slice;
43
44static Eina_Value *
45_value_clone(const Eina_Value *value)
46{
47 Eina_Value *copy = eina_value_new(eina_value_type_get(value));
48 eina_value_copy(value, copy);
49 return copy;
50}
51
52static void
53_future_forward_cb(void *data, Efl_Event const *event)
54{
55 efl_promise_value_set(
56 data, _value_clone(((Efl_Future_Event_Success*)event->info)->value), (Eina_Free_Cb)eina_value_free);
57}
58
59static void
60_future_error_forward_cb(void *data, Efl_Event const *event)
61{
62 Eina_Error err = ((Efl_Future_Event_Failure*)event->info)->error;
63 efl_promise_failed_set(data, err);
64}
65
66static Eina_Bool
67_bit_get(const unsigned char *bitstream, unsigned int idx)
68{
69 return (bitstream[idx / 8] >> (idx % 8)) & 1u;
70}
71
72static void
73_bit_set(unsigned char *bitstream, unsigned int idx, Eina_Bool v)
74{
75 if (v)
76 bitstream[idx / 8] |= 1u << (idx % 8);
77 else
78 bitstream[idx / 8] &= ~(1u << (idx % 8));
79}
80
81/**************** efl_mmodel_composite_boolean_children **************/
82
83static void
84_properties_names_array_free(Eina_Array *properties_names)
85{
86 Eina_Array_Iterator it;
87 void *name;
88 unsigned int i;
89
90 EINA_ARRAY_ITER_NEXT(properties_names, i, name, it)
91 free(name);
92
93 eina_array_free(properties_names);
94}
95
96
97static void
98_efl_model_composite_boolean_children_efl_object_destructor(Eo *obj,
99 Efl_Model_Composite_Boolean_Children_Data *pd)
100{
101 if (pd->properties_names)
102 _properties_names_array_free(pd->properties_names);
103
104 if (pd->composite_child)
105 efl_unref(pd->composite_child);
106
107 efl_destructor(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS));
108}
109
110static Eina_Bool
111_properties_names_push(const Eina_Hash *hash EINA_UNUSED,
112 const void *key, void *data EINA_UNUSED, void *fdata)
113{
114 eina_array_push(fdata, key);
115 return EINA_TRUE;
116}
117
118static const Eina_Array*
119_efl_model_composite_boolean_children_efl_model_properties_get(Eo *obj EINA_UNUSED,
120 Efl_Model_Composite_Boolean_Children_Data *pd)
121{
122 Eina_Array const *composite_properties;
123 unsigned int composite_count, self_count, i;
124
125 if (pd->properties_names)
126 {
127 _properties_names_array_free(pd->properties_names);
128 pd->properties_names = NULL;
129 }
130
131 composite_properties = efl_model_properties_get(pd->composite_child);
132 if (!composite_properties)
133 return pd->properties_names = eina_array_new(1);
134
135 composite_count = eina_array_count_get(composite_properties);
136 self_count = eina_hash_population(pd->parent_pd->values);
137
138 pd->properties_names = eina_array_new(composite_count + self_count);
139 for (i = 0; i != composite_count; ++i)
140 {
141 const char *name = strdup(eina_array_data_get(composite_properties, i));
142 eina_array_push(pd->properties_names, name);
143 }
144
145 eina_hash_foreach(pd->parent_pd->values, _properties_names_push, pd->properties_names);
146
147 return pd->properties_names;
148}
149
150static Efl_Future *
151_efl_model_composite_boolean_children_efl_model_property_get(Eo *obj EINA_UNUSED,
152 Efl_Model_Composite_Boolean_Children_Data *pd, const char *property)
153{
154 Efl_Model_Hash_Value *hv = eina_hash_find(pd->parent_pd->values, property);
155 if (hv)
156 {
157 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
158 Efl_Future *rfuture = efl_promise_future_get(promise);
159
160 Eina_Value *eina_value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
161 if (hv->bits_count <= pd->index)
162 {
163 unsigned char f = hv->default_value;
164 eina_value_set(eina_value, f);
165 }
166 else
167 {
168 eina_value_set(eina_value, _bit_get(hv->buffer, pd->index));
169 }
170 efl_promise_value_set(promise, eina_value, (Eina_Free_Cb)eina_value_free);
171 return rfuture;
172 }
173 else if (pd->composite_child)
174 return efl_model_property_get(pd->composite_child, property);
175 else
176 {
177 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
178 Efl_Future *rfuture = efl_promise_future_get(promise);
179
180 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
181 return rfuture;
182 }
183}
184
185static Efl_Future *
186_efl_model_composite_boolean_children_efl_model_property_set(Eo *obj EINA_UNUSED,
187 Efl_Model_Composite_Boolean_Children_Data *pd, const char *property, const Eina_Value *value)
188{
189 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
190 Efl_Future *rfuture = efl_promise_future_get(promise);
191
192 Efl_Model_Hash_Value *hv = eina_hash_find(pd->parent_pd->values, property);
193 if (hv)
194 {
195 Eina_Bool flag = EINA_FALSE;
196
197 if (eina_value_type_get(value) == EINA_VALUE_TYPE_UCHAR)
198 {
199 efl_promise_failed_set(promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
200 return rfuture;
201 }
202 if (!eina_value_get(value, &flag))
203 {
204 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
205 return rfuture;
206 }
207
208 if (pd->index >= hv->bits_count)
209 {
210 unsigned int bytes = (pd->index / 8) + 1;
211 unsigned int buff_size = (hv->bits_count / 8) + (hv->bits_count % 8 ? 1 : 0);
212 unsigned char *buff = realloc(hv->buffer, bytes);
213 if (!buff)
214 {
215 efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
216 return rfuture;
217 }
218 memset(
219 buff + buff_size,
220 hv->default_value ? -1 : 0,
221 bytes - buff_size);
222
223 hv->buffer = buff;
224 hv->bits_count = bytes * 8;
225 }
226
227 _bit_set(hv->buffer, pd->index, flag);
228
229 efl_promise_value_set(
230 promise, _value_clone(value), (Eina_Free_Cb)eina_value_free);
231 }
232 else if (pd->composite_child)
233 {
234 Efl_Future *f_forward = efl_model_property_set(pd->composite_child, property, value);
235 efl_future_then(f_forward, _future_forward_cb, _future_error_forward_cb, NULL, promise);
236 }
237 else
238 {
239 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
240 }
241
242 return rfuture;
243}
244
245static Efl_Future*
246_efl_model_composite_boolean_children_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
247 Efl_Model_Composite_Boolean_Children_Data *pd, unsigned int start, unsigned int count)
248{
249 return efl_model_children_slice_get(pd->composite_child, start, count);
250}
251
252static Efl_Future*
253_efl_model_composite_boolean_children_efl_model_children_count_get(Eo *obj EINA_UNUSED,
254 Efl_Model_Composite_Boolean_Children_Data *pd)
255{
256 return efl_model_children_count_get(pd->composite_child);
257}
258
259static Efl_Object*
260_efl_model_composite_boolean_children_efl_model_child_add(Eo *obj EINA_UNUSED,
261 Efl_Model_Composite_Boolean_Children_Data *pd)
262{
263 return efl_model_child_add(pd->composite_child);
264}
265
266static void
267_efl_model_composite_boolean_children_efl_model_child_del(Eo *obj EINA_UNUSED,
268 Efl_Model_Composite_Boolean_Children_Data *pd, Efl_Object *child)
269{
270 efl_model_child_del(pd->composite_child, child);
271}
272
273/**************** efl_model_accessor_slice **************/
274
275static void
276_bool_children_cache_array_free(Eina_Array *children_cache)
277{
278 int i, count = eina_array_count_get(children_cache);
279 for (i = 0; i < count; ++i)
280 efl_unref(eina_array_data_get(children_cache, i));
281 eina_array_free(children_cache);
282}
283
284static Eina_Bool
285efl_model_acessor_slice_get_at(Efl_Model_Accessor_Slice *acc, unsigned int idx, void **data)
286{
287 Efl_Model *child_bool;
288 Eina_Array *children_cache = acc->parent_pd->bool_children_cache;
289
290 /* NOTE: Efl.Model.Composite.Boolean must alloc the cache with the correct size
291 and NULL initialized. */
292 if (idx >= eina_array_count(children_cache))
293 {
294 EINA_LOG_WARN("Index bigger than size");
295 return EINA_FALSE;
296 }
297
298 child_bool = eina_array_data_get(children_cache, idx);
299
300 if (!child_bool)
301 {
302 Efl_Model *child = NULL;
303
304 if (!eina_accessor_data_get(acc->real_accessor, idx, (void *)&child))
305 return EINA_FALSE;
306
307 if (child)
308 {
309 Efl_Model_Composite_Boolean_Children_Data *pd;
310 child_bool = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS, NULL);
311 pd = efl_data_scope_get(child_bool, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS);
312
313 pd->parent_pd = acc->parent_pd;
314 pd->composite_child = efl_ref(child);
315 pd->index = acc->index++;
316
317 eina_array_data_set(children_cache, idx, child_bool);
318 }
319 }
320
321 if (data) *data = child_bool;
322 return EINA_TRUE;
323}
324
325static void *
326efl_model_acessor_slice_get_container(Efl_Model_Accessor_Slice *acc)
327{
328 return eina_accessor_container_get(acc->real_accessor);
329}
330
331static void
332efl_model_acessor_slice_free(Efl_Model_Accessor_Slice *acc)
333{
334 if (acc->real_accessor)
335 {
336 eina_accessor_free(acc->real_accessor);
337 acc->real_accessor = NULL;
338 }
339
340 if (acc->parent)
341 {
342 efl_unref(acc->parent);
343 acc->parent = NULL;
344 }
345
346 acc->parent_pd = NULL;
347 acc->promise = NULL;
348
349 free(acc);
350}
351
352static Eina_Bool
353efl_model_acessor_slice_lock(Efl_Model_Accessor_Slice *acc)
354{
355 return eina_accessor_lock(acc->real_accessor);
356}
357
358static Eina_Bool
359efl_model_acessor_slice_unlock(Efl_Model_Accessor_Slice *acc)
360{
361 return eina_accessor_unlock(acc->real_accessor);
362}
363
364static Efl_Model_Accessor_Slice *
365efl_model_acessor_slice_clone(Efl_Model_Accessor_Slice *acc EINA_UNUSED)
366{
367 return NULL;
368}
369
370static void
371efl_model_accessor_slice_setup(Efl_Model_Accessor_Slice *acc,
372 Efl_Model *parent, Efl_Model_Composite_Boolean_Data *parent_pd, Efl_Promise *promise)
373{
374 acc->vtable.version = EINA_ACCESSOR_VERSION;
375 acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(efl_model_acessor_slice_get_at);
376 acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(efl_model_acessor_slice_get_container);
377 acc->vtable.free = FUNC_ACCESSOR_FREE(efl_model_acessor_slice_free);
378
379 acc->vtable.lock = FUNC_ACCESSOR_LOCK(efl_model_acessor_slice_lock);
380 acc->vtable.unlock = FUNC_ACCESSOR_LOCK(efl_model_acessor_slice_unlock);
381
382 acc->vtable.clone = FUNC_ACCESSOR_CLONE(efl_model_acessor_slice_clone);
383
384 EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
385
386 acc->parent = efl_ref(parent);
387 acc->parent_pd = parent_pd;
388 acc->promise = promise;
389}
390
391static void
392_efl_model_composite_boolean_slice_then_cb(void *data, Efl_Event const *event)
393{
394 Efl_Model_Accessor_Slice *slice_acc = data;
395 Eina_Accessor *value_itt = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
396 unsigned int *children_count = NULL;
397 Eina_Accessor *children_accessor = NULL;
398
399 if (!eina_accessor_data_get(value_itt, 0, (void**)&children_count) ||
400 !children_count ||
401 !eina_accessor_data_get(value_itt, 1, (void**)&children_accessor) ||
402 !children_accessor)
403 {
404 EINA_LOG_WARN("missing Efl.Model information");
405 efl_promise_failed_set(slice_acc->promise, EFL_MODEL_ERROR_UNKNOWN);
406 efl_model_acessor_slice_free(slice_acc);
407 return;
408 }
409
410 slice_acc->real_accessor = eina_accessor_clone(children_accessor);
411 if (slice_acc->real_accessor)
412 {
413 Eina_Array *children_cache;
414 unsigned int i;
415
416 if (slice_acc->parent_pd->bool_children_cache)
417 _bool_children_cache_array_free(slice_acc->parent_pd->bool_children_cache);
418
419 children_cache = eina_array_new(*children_count);
420 for (i = 0 ; i < *children_count; ++i)
421 {
422 // NOTE: eina_array_push do not accept NULL
423 eina_array_push(children_cache, (void*)0x01);
424 eina_array_data_set(children_cache, i, NULL);
425 }
426
427 slice_acc->parent_pd->bool_children_cache = children_cache;
428
429 efl_promise_value_set(slice_acc->promise, slice_acc, (Eina_Free_Cb)&eina_accessor_free);
430 }
431 else
432 {
433 efl_promise_failed_set(slice_acc->promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
434 efl_model_acessor_slice_free(slice_acc);
435 }
436}
437
438static void
439_efl_model_composite_boolean_slice_error_cb(void *data, Efl_Event const*event)
440{
441 Efl_Model_Accessor_Slice *slice_acc = data;
442 Eina_Error error = ((Efl_Future_Event_Failure*)event->info)->error;
443 efl_promise_failed_set(slice_acc->promise, error);
444 efl_model_acessor_slice_free(slice_acc);
445}
446
447/**************** efl_mmodel_composite_boolean **************/
448
449static void
450efl_model_hash_value_free(void *p)
451{
452 Efl_Model_Hash_Value *value = p;
453 if (value)
454 {
455 free(value->buffer);
456 free(value);
457 }
458}
459
460static void
461_composite_model_data_reset(Efl_Model_Composite_Boolean_Data *pd)
462{
463 if (pd->bool_children_cache)
464 {
465 _bool_children_cache_array_free(pd->bool_children_cache);
466 pd->bool_children_cache = NULL;
467 }
468
469 if (pd->composite_model)
470 {
471 efl_unref(pd->composite_model);
472 pd->composite_model = NULL;
473 }
474}
475
476static void
477_efl_model_composite_boolean_efl_object_destructor(Eo *obj, Efl_Model_Composite_Boolean_Data *pd)
478{
479 if (pd->empty_properties)
480 {
481 eina_array_free(pd->empty_properties);
482 pd->empty_properties = NULL;
483 }
484
485 if (pd->values)
486 {
487 eina_hash_free(pd->values);
488 pd->values = NULL;
489 }
490
491 _composite_model_data_reset(pd);
492
493 efl_destructor(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS));
494}
495
496static void
497_efl_model_composite_boolean_composite_model_set(Eo *obj EINA_UNUSED,
498 Efl_Model_Composite_Boolean_Data *pd, Efl_Model *model)
499{
500 if (pd->composite_model)
501 {
502 _composite_model_data_reset(pd);
503 }
504
505 pd->composite_model = efl_ref(model);
506}
507
508static Efl_Model *
509_efl_model_composite_boolean_composite_model_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
510{
511 return pd->composite_model;
512}
513
514static void
515_efl_model_composite_boolean_property_add(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd,
516 const char *name, Eina_Bool initial_value)
517{
518 if (!pd->values)
519 pd->values = eina_hash_string_small_new(&efl_model_hash_value_free);
520 Efl_Model_Hash_Value *value = calloc(1, sizeof(Efl_Model_Hash_Value));
521 value->default_value = initial_value;
522 eina_hash_add(pd->values, name, value);
523}
524
525static const Eina_Array *
526_efl_model_composite_boolean_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
527{
528 if (pd->composite_model)
529 return efl_model_properties_get(pd->composite_model);
530 else if (pd->empty_properties)
531 return pd->empty_properties;
532 else
533 return pd->empty_properties = eina_array_new(1);
534}
535
536Efl_Future *
537_efl_model_composite_boolean_efl_model_property_get(Eo *obj EINA_UNUSED,
538 Efl_Model_Composite_Boolean_Data *pd, const char *property)
539{
540 if (pd->composite_model)
541 return efl_model_property_get(pd->composite_model, property);
542
543 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
544 Efl_Future *rfuture = efl_promise_future_get(promise);
545
546 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
547 return rfuture;
548}
549
550Efl_Future *
551_efl_model_composite_boolean_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd,
552 const char *property, const Eina_Value *value)
553{
554
555 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
556 Efl_Future *rfuture = efl_promise_future_get(promise);
557
558 if (pd->composite_model)
559 {
560 Efl_Future *f_forward = efl_model_property_set(pd->composite_model, property, value);
561 efl_future_then(f_forward, _future_forward_cb, _future_error_forward_cb, NULL, promise);
562 }
563 else
564 {
565 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
566 }
567
568 return rfuture;
569}
570
571static Efl_Future *
572_efl_model_composite_boolean_efl_model_children_slice_get(Eo *obj, Efl_Model_Composite_Boolean_Data *pd, unsigned int start, unsigned int count)
573{
574 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
575 Efl_Future *rfuture = efl_promise_future_get(promise);
576
577 if (pd->composite_model)
578 {
579 Efl_Model_Accessor_Slice *accessor;
580 Efl_Future *composite_future;
581 Efl_Future *futures[2] = {NULL,};
582
583 futures[0] = efl_model_children_count_get(pd->composite_model);
584 futures[1] = efl_model_children_slice_get(pd->composite_model, start, count);
585
586 composite_future = efl_future_all(futures[0], futures[1]);
587
588 accessor = calloc(1, sizeof(Efl_Model_Accessor_Slice));
589 efl_model_accessor_slice_setup(accessor, obj, pd, promise);
590
591 efl_future_then(composite_future, &_efl_model_composite_boolean_slice_then_cb,
592 &_efl_model_composite_boolean_slice_error_cb, NULL, accessor);
593 }
594 else
595 {
596 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
597 }
598 return rfuture;
599}
600
601static Efl_Future *
602_efl_model_composite_boolean_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
603{
604 if (pd->composite_model)
605 return efl_model_children_count_get(pd->composite_model);
606 else
607 {
608 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
609 Efl_Future *rfuture = efl_promise_future_get(promise);
610
611 unsigned int *count = malloc(sizeof(unsigned int));
612 *count = 0;
613 efl_promise_value_set(promise, count, free);
614 return rfuture;
615 }
616}
617
618static Efl_Object*
619_efl_model_composite_boolean_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
620{
621 if (pd->composite_model)
622 return efl_model_child_add(pd->composite_model);
623 else
624 {
625 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
626 return NULL;
627 }
628}
629
630static void
631_efl_model_composite_boolean_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd, Efl_Object *child)
632{
633 if (pd->composite_model)
634 return efl_model_child_del(pd->composite_model, child);
635 else
636 {
637 eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
638 }
639}
640
641#include "efl_model_composite_boolean.eo.c"
642#include "efl_model_composite_boolean_children.eo.c"
diff --git a/src/lib/ecore/efl_model_composite_boolean.eo b/src/lib/ecore/efl_model_composite_boolean.eo
new file mode 100644
index 0000000000..4384e20017
--- /dev/null
+++ b/src/lib/ecore/efl_model_composite_boolean.eo
@@ -0,0 +1,34 @@
1class Efl.Model.Composite.Boolean (Efl.Object, Efl.Model)
2{
3 methods {
4 @property composite_model {
5 set {
6 }
7 get {
8 }
9 values {
10 model: Efl.Model;
11 }
12 }
13 property_add {
14 params {
15 @in name: string;
16 @in initial_value: bool;
17 }
18 }
19 }
20 implements {
21 Efl.Object.destructor;
22 Efl.Model.properties { get; }
23 Efl.Model.property_get;
24 Efl.Model.property_set;
25 Efl.Model.children_slice_get;
26 Efl.Model.children_count_get;
27 Efl.Model.child_add;
28 Efl.Model.child_del;
29 }
30 constructors {
31 .composite_model;
32 .property_add @optional;
33 }
34}
diff --git a/src/lib/ecore/efl_model_composite_boolean_children.eo b/src/lib/ecore/efl_model_composite_boolean_children.eo
new file mode 100644
index 0000000000..d2668c745f
--- /dev/null
+++ b/src/lib/ecore/efl_model_composite_boolean_children.eo
@@ -0,0 +1,13 @@
1class Efl.Model.Composite.Boolean.Children (Efl.Object, Efl.Model)
2{
3 implements {
4 Efl.Object.destructor;
5 Efl.Model.properties { get; }
6 Efl.Model.property_get;
7 Efl.Model.property_set;
8 Efl.Model.children_slice_get;
9 Efl.Model.children_count_get;
10 Efl.Model.child_add;
11 Efl.Model.child_del;
12 }
13}
diff --git a/src/tests/efl/efl_suite.c b/src/tests/efl/efl_suite.c
index 653aac2201..82cc6dfb32 100644
--- a/src/tests/efl/efl_suite.c
+++ b/src/tests/efl/efl_suite.c
@@ -27,6 +27,7 @@
27 27
28static const Efl_Test_Case etc[] = { 28static const Efl_Test_Case etc[] = {
29 { "Efl_Model_Container", efl_test_case_model_container }, 29 { "Efl_Model_Container", efl_test_case_model_container },
30 { "Efl_Model_Composite_Boolean", efl_test_case_model_composite_boolean },
30 { NULL, NULL } 31 { NULL, NULL }
31}; 32};
32 33
diff --git a/src/tests/efl/efl_suite.h b/src/tests/efl/efl_suite.h
index d5a7caa9ec..b142037425 100644
--- a/src/tests/efl/efl_suite.h
+++ b/src/tests/efl/efl_suite.h
@@ -22,5 +22,6 @@
22#include <check.h> 22#include <check.h>
23 23
24void efl_test_case_model_container(TCase *tc); 24void efl_test_case_model_container(TCase *tc);
25void efl_test_case_model_composite_boolean(TCase *tc);
25 26
26#endif /* EFL_SUITE_H_ */ 27#endif /* EFL_SUITE_H_ */
diff --git a/src/tests/efl/efl_test_model_composite_boolean.c b/src/tests/efl/efl_test_model_composite_boolean.c
new file mode 100644
index 0000000000..2b94fa7aa0
--- /dev/null
+++ b/src/tests/efl/efl_test_model_composite_boolean.c
@@ -0,0 +1,155 @@
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 <Efl.h>
26#include <Ecore.h>
27
28typedef struct _Test_Data
29{
30 Eina_Bool success_flag;
31 unsigned int child_count;
32} Test_Data;
33
34typedef struct _Test_Child_Data
35{
36 Test_Data *tdata;
37 unsigned int idx;
38} Test_Child_Data;
39
40const int child_number = 3;
41const int base_ints[] = { 41, 42, 43 };
42
43static void
44_future_error_then(void *data EINA_UNUSED, Efl_Event const* event EINA_UNUSED)
45{
46 fprintf(stderr, "Promise failed!\n"); fflush(stderr);
47 ck_abort_msg("Promise failed");
48}
49
50static void
51_property_get_then(void *data, Efl_Event const *event)
52{
53 Test_Child_Data *t = data;
54 Eina_Accessor *value_itt = (Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value;
55 int v_int = 0;
56 Eina_Bool v_bool = EINA_FALSE;
57
58#define _value_get_and_compare(it, i, var, cmp) \
59 do { \
60 Eina_Value *vvv = NULL; \
61 if (!eina_accessor_data_get(it, i, (void **)&vvv) || !vvv || \
62 !eina_value_get(vvv, &var) || var != cmp) \
63 { \
64 fprintf(stderr, "Could not get value!\n"); fflush(stderr); \
65 ck_abort_msg("Could not get value"); \
66 return; \
67 } \
68 } while(0)
69
70 _value_get_and_compare(value_itt, 0, v_int, base_ints[t->idx]);
71 _value_get_and_compare(value_itt, 1, v_bool, EINA_TRUE);
72 _value_get_and_compare(value_itt, 2, v_bool, EINA_FALSE);
73
74 t->tdata->child_count++;
75 if (t->tdata->child_count == 3)
76 t->tdata->success_flag = EINA_TRUE;
77
78#undef _value_get_and_compare
79}
80
81static void
82_children_slice_get_then(void *data, Efl_Event const* event)
83{
84 Eina_Accessor *children = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
85 Efl_Model *child;
86 Test_Child_Data *t;
87 unsigned int i = 0;
88
89 fprintf(stderr, "OPAAAAAAa\n");
90 EINA_ACCESSOR_FOREACH(children, i, child)
91 {
92 Efl_Future *futures[3] = {NULL,};
93 Efl_Future *future_all = NULL;
94
95 futures[0] = efl_model_property_get(child, "test_p_int");
96 futures[1] = efl_model_property_get(child, "test_p_true");
97 futures[2] = efl_model_property_get(child, "test_p_false");
98
99 future_all = efl_future_all(futures[0], futures[1], futures[2]);
100
101 t = calloc(1, sizeof(Test_Child_Data));
102 t->tdata = data;
103 t->idx = i;
104 efl_future_then(future_all, _property_get_then, _future_error_then, NULL, t);
105 }
106}
107
108START_TEST(efl_test_model_composite_boolean)
109{
110 Efl_Model_Item *base_model, *child;
111 int i;
112 Eina_Value v;
113 Efl_Model_Composite_Boolean *model;
114 Test_Data *tdata;
115 Efl_Future *future;
116
117 fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
118 fail_if(!efl_object_init(), "ERROR: Cannot init EO!\n");
119
120 eina_value_setup(&v, EINA_VALUE_TYPE_INT);
121
122 base_model = efl_add(EFL_MODEL_ITEM_CLASS, NULL);
123 ck_assert(!!base_model);
124
125 for (i = 0; i < child_number; ++i)
126 {
127 child = efl_model_child_add(base_model);
128 ck_assert(!!child);
129 ck_assert(eina_value_set(&v, base_ints[i]));
130 efl_model_property_set(child, "test_p_int", &v);
131 }
132
133 model = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CLASS, NULL,
134 efl_model_composite_boolean_composite_model_set(efl_added, base_model),
135 efl_model_composite_boolean_property_add(efl_added, "test_p_true", EINA_TRUE),
136 efl_model_composite_boolean_property_add(efl_added, "test_p_false", EINA_FALSE));
137 ck_assert(!!model);
138
139 tdata = calloc(1, sizeof(Test_Data));
140 future = efl_model_children_slice_get(model, 0, 0);
141 efl_future_then(future, _children_slice_get_then, _future_error_then, NULL, tdata);
142
143 ecore_main_loop_iterate();
144
145 ck_assert(tdata->success_flag);
146
147 ecore_shutdown();
148}
149END_TEST
150
151void
152efl_test_case_model_composite_boolean(TCase *tc)
153{
154 tcase_add_test(tc, efl_test_model_composite_boolean);
155}