summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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}