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 = \
lib/ecore/efl_model_item.eo \
lib/ecore/efl_model_container.eo \
lib/ecore/efl_model_container_item.eo \
+ lib/ecore/efl_model_composite_boolean.eo \
+ lib/ecore/efl_model_composite_boolean_children.eo \
$(ecore_eolian_files_legacy)
ecore_eolian_type_files = \
@@ -93,6 +95,7 @@ lib/ecore/efl_model_item.c \
lib/ecore/efl_model_container.c \
lib/ecore/efl_model_container_item.c \
lib/ecore/efl_model_container_private.h \
+lib/ecore/efl_model_composite_boolean.c \
lib/ecore/ecore_pipe.c \
lib/ecore/ecore_poller.c \
lib/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
tests_efl_efl_suite_SOURCES = \
tests/efl/efl_suite.c \
tests/efl/efl_test_model_container.c \
+tests/efl/efl_test_model_composite_boolean.c \
tests/efl/efl_suite.h
tests_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);
#include "efl_model_item.eo.h"
#include "efl_model_container.eo.h"
#include "efl_model_container_item.eo.h"
+#include "efl_model_composite_boolean.eo.h"
+#include "efl_model_composite_boolean_children.eo.h"
/**
* @}
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 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Eina.h"
+#include "Efl.h"
+#include <Ecore.h>
+
+#include "efl_model_composite_boolean_children.eo.h"
+
+typedef struct _Efl_Model_Hash_Value
+{
+ unsigned char *buffer;
+ unsigned int bits_count;
+ Eina_Bool default_value : 1;
+} Efl_Model_Hash_Value;
+
+typedef struct _Efl_Model_Composite_Boolean_Data
+{
+ Efl_Model *composite_model;
+ Eina_Array *bool_children_cache;
+ Eina_Array *empty_properties;
+ Eina_Hash *values; // [property_name, Efl_Model_Hash_Value*]
+} Efl_Model_Composite_Boolean_Data;
+
+typedef struct _Efl_Model_Composite_Boolean_Children_Data
+{
+ Efl_Model_Composite_Boolean_Data *parent_pd;
+ Efl_Model *composite_child;
+ Eina_Array *properties_names;
+ unsigned int index;
+} Efl_Model_Composite_Boolean_Children_Data;
+
+typedef struct _Efl_Model_Accessor_Slice
+{
+ Eina_Accessor vtable;
+ Eina_Accessor *real_accessor;
+ Efl_Model *parent;
+ Efl_Model_Composite_Boolean_Data *parent_pd;
+ Efl_Promise *promise;
+ unsigned int index;
+} Efl_Model_Accessor_Slice;
+
+static Eina_Value *
+_value_clone(const Eina_Value *value)
+{
+ Eina_Value *copy = eina_value_new(eina_value_type_get(value));
+ eina_value_copy(value, copy);
+ return copy;
+}
+
+static void
+_future_forward_cb(void *data, Efl_Event const *event)
+{
+ efl_promise_value_set(
+ data, _value_clone(((Efl_Future_Event_Success*)event->info)->value), (Eina_Free_Cb)eina_value_free);
+}
+
+static void
+_future_error_forward_cb(void *data, Efl_Event const *event)
+{
+ Eina_Error err = ((Efl_Future_Event_Failure*)event->info)->error;
+ efl_promise_failed_set(data, err);
+}
+
+static Eina_Bool
+_bit_get(const unsigned char *bitstream, unsigned int idx)
+{
+ return (bitstream[idx / 8] >> (idx % 8)) & 1u;
+}
+
+static void
+_bit_set(unsigned char *bitstream, unsigned int idx, Eina_Bool v)
+{
+ if (v)
+ bitstream[idx / 8] |= 1u << (idx % 8);
+ else
+ bitstream[idx / 8] &= ~(1u << (idx % 8));
+}
+
+/**************** efl_mmodel_composite_boolean_children **************/
+
+static void
+_properties_names_array_free(Eina_Array *properties_names)
+{
+ Eina_Array_Iterator it;
+ void *name;
+ unsigned int i;
+
+ EINA_ARRAY_ITER_NEXT(properties_names, i, name, it)
+ free(name);
+
+ eina_array_free(properties_names);
+}
+
+
+static void
+_efl_model_composite_boolean_children_efl_object_destructor(Eo *obj,
+ Efl_Model_Composite_Boolean_Children_Data *pd)
+{
+ if (pd->properties_names)
+ _properties_names_array_free(pd->properties_names);
+
+ if (pd->composite_child)
+ efl_unref(pd->composite_child);
+
+ efl_destructor(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS));
+}
+
+static Eina_Bool
+_properties_names_push(const Eina_Hash *hash EINA_UNUSED,
+ const void *key, void *data EINA_UNUSED, void *fdata)
+{
+ eina_array_push(fdata, key);
+ return EINA_TRUE;
+}
+
+static const Eina_Array*
+_efl_model_composite_boolean_children_efl_model_properties_get(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd)
+{
+ Eina_Array const *composite_properties;
+ unsigned int composite_count, self_count, i;
+
+ if (pd->properties_names)
+ {
+ _properties_names_array_free(pd->properties_names);
+ pd->properties_names = NULL;
+ }
+
+ composite_properties = efl_model_properties_get(pd->composite_child);
+ if (!composite_properties)
+ return pd->properties_names = eina_array_new(1);
+
+ composite_count = eina_array_count_get(composite_properties);
+ self_count = eina_hash_population(pd->parent_pd->values);
+
+ pd->properties_names = eina_array_new(composite_count + self_count);
+ for (i = 0; i != composite_count; ++i)
+ {
+ const char *name = strdup(eina_array_data_get(composite_properties, i));
+ eina_array_push(pd->properties_names, name);
+ }
+
+ eina_hash_foreach(pd->parent_pd->values, _properties_names_push, pd->properties_names);
+
+ return pd->properties_names;
+}
+
+static Efl_Future *
+_efl_model_composite_boolean_children_efl_model_property_get(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd, const char *property)
+{
+ Efl_Model_Hash_Value *hv = eina_hash_find(pd->parent_pd->values, property);
+ if (hv)
+ {
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ Eina_Value *eina_value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ if (hv->bits_count <= pd->index)
+ {
+ unsigned char f = hv->default_value;
+ eina_value_set(eina_value, f);
+ }
+ else
+ {
+ eina_value_set(eina_value, _bit_get(hv->buffer, pd->index));
+ }
+ efl_promise_value_set(promise, eina_value, (Eina_Free_Cb)eina_value_free);
+ return rfuture;
+ }
+ else if (pd->composite_child)
+ return efl_model_property_get(pd->composite_child, property);
+ else
+ {
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
+ return rfuture;
+ }
+}
+
+static Efl_Future *
+_efl_model_composite_boolean_children_efl_model_property_set(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd, const char *property, const Eina_Value *value)
+{
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ Efl_Model_Hash_Value *hv = eina_hash_find(pd->parent_pd->values, property);
+ if (hv)
+ {
+ Eina_Bool flag = EINA_FALSE;
+
+ if (eina_value_type_get(value) == EINA_VALUE_TYPE_UCHAR)
+ {
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
+ return rfuture;
+ }
+ if (!eina_value_get(value, &flag))
+ {
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
+ return rfuture;
+ }
+
+ if (pd->index >= hv->bits_count)
+ {
+ unsigned int bytes = (pd->index / 8) + 1;
+ unsigned int buff_size = (hv->bits_count / 8) + (hv->bits_count % 8 ? 1 : 0);
+ unsigned char *buff = realloc(hv->buffer, bytes);
+ if (!buff)
+ {
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_UNKNOWN);
+ return rfuture;
+ }
+ memset(
+ buff + buff_size,
+ hv->default_value ? -1 : 0,
+ bytes - buff_size);
+
+ hv->buffer = buff;
+ hv->bits_count = bytes * 8;
+ }
+
+ _bit_set(hv->buffer, pd->index, flag);
+
+ efl_promise_value_set(
+ promise, _value_clone(value), (Eina_Free_Cb)eina_value_free);
+ }
+ else if (pd->composite_child)
+ {
+ Efl_Future *f_forward = efl_model_property_set(pd->composite_child, property, value);
+ efl_future_then(f_forward, _future_forward_cb, _future_error_forward_cb, NULL, promise);
+ }
+ else
+ {
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
+ }
+
+ return rfuture;
+}
+
+static Efl_Future*
+_efl_model_composite_boolean_children_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd, unsigned int start, unsigned int count)
+{
+ return efl_model_children_slice_get(pd->composite_child, start, count);
+}
+
+static Efl_Future*
+_efl_model_composite_boolean_children_efl_model_children_count_get(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd)
+{
+ return efl_model_children_count_get(pd->composite_child);
+}
+
+static Efl_Object*
+_efl_model_composite_boolean_children_efl_model_child_add(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd)
+{
+ return efl_model_child_add(pd->composite_child);
+}
+
+static void
+_efl_model_composite_boolean_children_efl_model_child_del(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Children_Data *pd, Efl_Object *child)
+{
+ efl_model_child_del(pd->composite_child, child);
+}
+
+/**************** efl_model_accessor_slice **************/
+
+static void
+_bool_children_cache_array_free(Eina_Array *children_cache)
+{
+ int i, count = eina_array_count_get(children_cache);
+ for (i = 0; i < count; ++i)
+ efl_unref(eina_array_data_get(children_cache, i));
+ eina_array_free(children_cache);
+}
+
+static Eina_Bool
+efl_model_acessor_slice_get_at(Efl_Model_Accessor_Slice *acc, unsigned int idx, void **data)
+{
+ Efl_Model *child_bool;
+ Eina_Array *children_cache = acc->parent_pd->bool_children_cache;
+
+ /* NOTE: Efl.Model.Composite.Boolean must alloc the cache with the correct size
+ and NULL initialized. */
+ if (idx >= eina_array_count(children_cache))
+ {
+ EINA_LOG_WARN("Index bigger than size");
+ return EINA_FALSE;
+ }
+
+ child_bool = eina_array_data_get(children_cache, idx);
+
+ if (!child_bool)
+ {
+ Efl_Model *child = NULL;
+
+ if (!eina_accessor_data_get(acc->real_accessor, idx, (void *)&child))
+ return EINA_FALSE;
+
+ if (child)
+ {
+ Efl_Model_Composite_Boolean_Children_Data *pd;
+ child_bool = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS, NULL);
+ pd = efl_data_scope_get(child_bool, EFL_MODEL_COMPOSITE_BOOLEAN_CHILDREN_CLASS);
+
+ pd->parent_pd = acc->parent_pd;
+ pd->composite_child = efl_ref(child);
+ pd->index = acc->index++;
+
+ eina_array_data_set(children_cache, idx, child_bool);
+ }
+ }
+
+ if (data) *data = child_bool;
+ return EINA_TRUE;
+}
+
+static void *
+efl_model_acessor_slice_get_container(Efl_Model_Accessor_Slice *acc)
+{
+ return eina_accessor_container_get(acc->real_accessor);
+}
+
+static void
+efl_model_acessor_slice_free(Efl_Model_Accessor_Slice *acc)
+{
+ if (acc->real_accessor)
+ {
+ eina_accessor_free(acc->real_accessor);
+ acc->real_accessor = NULL;
+ }
+
+ if (acc->parent)
+ {
+ efl_unref(acc->parent);
+ acc->parent = NULL;
+ }
+
+ acc->parent_pd = NULL;
+ acc->promise = NULL;
+
+ free(acc);
+}
+
+static Eina_Bool
+efl_model_acessor_slice_lock(Efl_Model_Accessor_Slice *acc)
+{
+ return eina_accessor_lock(acc->real_accessor);
+}
+
+static Eina_Bool
+efl_model_acessor_slice_unlock(Efl_Model_Accessor_Slice *acc)
+{
+ return eina_accessor_unlock(acc->real_accessor);
+}
+
+static Efl_Model_Accessor_Slice *
+efl_model_acessor_slice_clone(Efl_Model_Accessor_Slice *acc EINA_UNUSED)
+{
+ return NULL;
+}
+
+static void
+efl_model_accessor_slice_setup(Efl_Model_Accessor_Slice *acc,
+ Efl_Model *parent, Efl_Model_Composite_Boolean_Data *parent_pd, Efl_Promise *promise)
+{
+ acc->vtable.version = EINA_ACCESSOR_VERSION;
+ acc->vtable.get_at = FUNC_ACCESSOR_GET_AT(efl_model_acessor_slice_get_at);
+ acc->vtable.get_container = FUNC_ACCESSOR_GET_CONTAINER(efl_model_acessor_slice_get_container);
+ acc->vtable.free = FUNC_ACCESSOR_FREE(efl_model_acessor_slice_free);
+
+ acc->vtable.lock = FUNC_ACCESSOR_LOCK(efl_model_acessor_slice_lock);
+ acc->vtable.unlock = FUNC_ACCESSOR_LOCK(efl_model_acessor_slice_unlock);
+
+ acc->vtable.clone = FUNC_ACCESSOR_CLONE(efl_model_acessor_slice_clone);
+
+ EINA_MAGIC_SET(&acc->vtable, EINA_MAGIC_ACCESSOR);
+
+ acc->parent = efl_ref(parent);
+ acc->parent_pd = parent_pd;
+ acc->promise = promise;
+}
+
+static void
+_efl_model_composite_boolean_slice_then_cb(void *data, Efl_Event const *event)
+{
+ Efl_Model_Accessor_Slice *slice_acc = data;
+ Eina_Accessor *value_itt = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
+ unsigned int *children_count = NULL;
+ Eina_Accessor *children_accessor = NULL;
+
+ if (!eina_accessor_data_get(value_itt, 0, (void**)&children_count) ||
+ !children_count ||
+ !eina_accessor_data_get(value_itt, 1, (void**)&children_accessor) ||
+ !children_accessor)
+ {
+ EINA_LOG_WARN("missing Efl.Model information");
+ efl_promise_failed_set(slice_acc->promise, EFL_MODEL_ERROR_UNKNOWN);
+ efl_model_acessor_slice_free(slice_acc);
+ return;
+ }
+
+ slice_acc->real_accessor = eina_accessor_clone(children_accessor);
+ if (slice_acc->real_accessor)
+ {
+ Eina_Array *children_cache;
+ unsigned int i;
+
+ if (slice_acc->parent_pd->bool_children_cache)
+ _bool_children_cache_array_free(slice_acc->parent_pd->bool_children_cache);
+
+ children_cache = eina_array_new(*children_count);
+ for (i = 0 ; i < *children_count; ++i)
+ {
+ // NOTE: eina_array_push do not accept NULL
+ eina_array_push(children_cache, (void*)0x01);
+ eina_array_data_set(children_cache, i, NULL);
+ }
+
+ slice_acc->parent_pd->bool_children_cache = children_cache;
+
+ efl_promise_value_set(slice_acc->promise, slice_acc, (Eina_Free_Cb)&eina_accessor_free);
+ }
+ else
+ {
+ efl_promise_failed_set(slice_acc->promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
+ efl_model_acessor_slice_free(slice_acc);
+ }
+}
+
+static void
+_efl_model_composite_boolean_slice_error_cb(void *data, Efl_Event const*event)
+{
+ Efl_Model_Accessor_Slice *slice_acc = data;
+ Eina_Error error = ((Efl_Future_Event_Failure*)event->info)->error;
+ efl_promise_failed_set(slice_acc->promise, error);
+ efl_model_acessor_slice_free(slice_acc);
+}
+
+/**************** efl_mmodel_composite_boolean **************/
+
+static void
+efl_model_hash_value_free(void *p)
+{
+ Efl_Model_Hash_Value *value = p;
+ if (value)
+ {
+ free(value->buffer);
+ free(value);
+ }
+}
+
+static void
+_composite_model_data_reset(Efl_Model_Composite_Boolean_Data *pd)
+{
+ if (pd->bool_children_cache)
+ {
+ _bool_children_cache_array_free(pd->bool_children_cache);
+ pd->bool_children_cache = NULL;
+ }
+
+ if (pd->composite_model)
+ {
+ efl_unref(pd->composite_model);
+ pd->composite_model = NULL;
+ }
+}
+
+static void
+_efl_model_composite_boolean_efl_object_destructor(Eo *obj, Efl_Model_Composite_Boolean_Data *pd)
+{
+ if (pd->empty_properties)
+ {
+ eina_array_free(pd->empty_properties);
+ pd->empty_properties = NULL;
+ }
+
+ if (pd->values)
+ {
+ eina_hash_free(pd->values);
+ pd->values = NULL;
+ }
+
+ _composite_model_data_reset(pd);
+
+ efl_destructor(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS));
+}
+
+static void
+_efl_model_composite_boolean_composite_model_set(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Data *pd, Efl_Model *model)
+{
+ if (pd->composite_model)
+ {
+ _composite_model_data_reset(pd);
+ }
+
+ pd->composite_model = efl_ref(model);
+}
+
+static Efl_Model *
+_efl_model_composite_boolean_composite_model_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
+{
+ return pd->composite_model;
+}
+
+static void
+_efl_model_composite_boolean_property_add(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd,
+ const char *name, Eina_Bool initial_value)
+{
+ if (!pd->values)
+ pd->values = eina_hash_string_small_new(&efl_model_hash_value_free);
+ Efl_Model_Hash_Value *value = calloc(1, sizeof(Efl_Model_Hash_Value));
+ value->default_value = initial_value;
+ eina_hash_add(pd->values, name, value);
+}
+
+static const Eina_Array *
+_efl_model_composite_boolean_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
+{
+ if (pd->composite_model)
+ return efl_model_properties_get(pd->composite_model);
+ else if (pd->empty_properties)
+ return pd->empty_properties;
+ else
+ return pd->empty_properties = eina_array_new(1);
+}
+
+Efl_Future *
+_efl_model_composite_boolean_efl_model_property_get(Eo *obj EINA_UNUSED,
+ Efl_Model_Composite_Boolean_Data *pd, const char *property)
+{
+ if (pd->composite_model)
+ return efl_model_property_get(pd->composite_model, property);
+
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
+ return rfuture;
+}
+
+Efl_Future *
+_efl_model_composite_boolean_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd,
+ const char *property, const Eina_Value *value)
+{
+
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ if (pd->composite_model)
+ {
+ Efl_Future *f_forward = efl_model_property_set(pd->composite_model, property, value);
+ efl_future_then(f_forward, _future_forward_cb, _future_error_forward_cb, NULL, promise);
+ }
+ else
+ {
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
+ }
+
+ return rfuture;
+}
+
+static Efl_Future *
+_efl_model_composite_boolean_efl_model_children_slice_get(Eo *obj, Efl_Model_Composite_Boolean_Data *pd, unsigned int start, unsigned int count)
+{
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ if (pd->composite_model)
+ {
+ Efl_Model_Accessor_Slice *accessor;
+ Efl_Future *composite_future;
+ Efl_Future *futures[2] = {NULL,};
+
+ futures[0] = efl_model_children_count_get(pd->composite_model);
+ futures[1] = efl_model_children_slice_get(pd->composite_model, start, count);
+
+ composite_future = efl_future_all(futures[0], futures[1]);
+
+ accessor = calloc(1, sizeof(Efl_Model_Accessor_Slice));
+ efl_model_accessor_slice_setup(accessor, obj, pd, promise);
+
+ efl_future_then(composite_future, &_efl_model_composite_boolean_slice_then_cb,
+ &_efl_model_composite_boolean_slice_error_cb, NULL, accessor);
+ }
+ else
+ {
+ efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
+ }
+ return rfuture;
+}
+
+static Efl_Future *
+_efl_model_composite_boolean_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
+{
+ if (pd->composite_model)
+ return efl_model_children_count_get(pd->composite_model);
+ else
+ {
+ Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ Efl_Future *rfuture = efl_promise_future_get(promise);
+
+ unsigned int *count = malloc(sizeof(unsigned int));
+ *count = 0;
+ efl_promise_value_set(promise, count, free);
+ return rfuture;
+ }
+}
+
+static Efl_Object*
+_efl_model_composite_boolean_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd)
+{
+ if (pd->composite_model)
+ return efl_model_child_add(pd->composite_model);
+ else
+ {
+ eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
+ return NULL;
+ }
+}
+
+static void
+_efl_model_composite_boolean_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Composite_Boolean_Data *pd, Efl_Object *child)
+{
+ if (pd->composite_model)
+ return efl_model_child_del(pd->composite_model, child);
+ else
+ {
+ eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
+ }
+}
+
+#include "efl_model_composite_boolean.eo.c"
+#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 @@
+class Efl.Model.Composite.Boolean (Efl.Object, Efl.Model)
+{
+ methods {
+ @property composite_model {
+ set {
+ }
+ get {
+ }
+ values {
+ model: Efl.Model;
+ }
+ }
+ property_add {
+ params {
+ @in name: string;
+ @in initial_value: bool;
+ }
+ }
+ }
+ implements {
+ Efl.Object.destructor;
+ Efl.Model.properties { get; }
+ Efl.Model.property_get;
+ Efl.Model.property_set;
+ Efl.Model.children_slice_get;
+ Efl.Model.children_count_get;
+ Efl.Model.child_add;
+ Efl.Model.child_del;
+ }
+ constructors {
+ .composite_model;
+ .property_add @optional;
+ }
+}
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 @@
+class Efl.Model.Composite.Boolean.Children (Efl.Object, Efl.Model)
+{
+ implements {
+ Efl.Object.destructor;
+ Efl.Model.properties { get; }
+ Efl.Model.property_get;
+ Efl.Model.property_set;
+ Efl.Model.children_slice_get;
+ Efl.Model.children_count_get;
+ Efl.Model.child_add;
+ Efl.Model.child_del;
+ }
+}
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 @@
static const Efl_Test_Case etc[] = {
{ "Efl_Model_Container", efl_test_case_model_container },
+ { "Efl_Model_Composite_Boolean", efl_test_case_model_composite_boolean },
{ NULL, NULL }
};
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 @@
#include <check.h>
void efl_test_case_model_container(TCase *tc);
+void efl_test_case_model_composite_boolean(TCase *tc);
#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 @@
+/* EFL - EFL library
+ * Copyright (C) 2013 Cedric Bail
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "efl_suite.h"
+
+#include <Efl.h>
+#include <Ecore.h>
+
+typedef struct _Test_Data
+{
+ Eina_Bool success_flag;
+ unsigned int child_count;
+} Test_Data;
+
+typedef struct _Test_Child_Data
+{
+ Test_Data *tdata;
+ unsigned int idx;
+} Test_Child_Data;
+
+const int child_number = 3;
+const int base_ints[] = { 41, 42, 43 };
+
+static void
+_future_error_then(void *data EINA_UNUSED, Efl_Event const* event EINA_UNUSED)
+{
+ fprintf(stderr, "Promise failed!\n"); fflush(stderr);
+ ck_abort_msg("Promise failed");
+}
+
+static void
+_property_get_then(void *data, Efl_Event const *event)
+{
+ Test_Child_Data *t = data;
+ Eina_Accessor *value_itt = (Eina_Accessor*)((Efl_Future_Event_Success*)event->info)->value;
+ int v_int = 0;
+ Eina_Bool v_bool = EINA_FALSE;
+
+#define _value_get_and_compare(it, i, var, cmp) \
+ do { \
+ Eina_Value *vvv = NULL; \
+ if (!eina_accessor_data_get(it, i, (void **)&vvv) || !vvv || \
+ !eina_value_get(vvv, &var) || var != cmp) \
+ { \
+ fprintf(stderr, "Could not get value!\n"); fflush(stderr); \
+ ck_abort_msg("Could not get value"); \
+ return; \
+ } \
+ } while(0)
+
+ _value_get_and_compare(value_itt, 0, v_int, base_ints[t->idx]);
+ _value_get_and_compare(value_itt, 1, v_bool, EINA_TRUE);
+ _value_get_and_compare(value_itt, 2, v_bool, EINA_FALSE);
+
+ t->tdata->child_count++;
+ if (t->tdata->child_count == 3)
+ t->tdata->success_flag = EINA_TRUE;
+
+#undef _value_get_and_compare
+}
+
+static void
+_children_slice_get_then(void *data, Efl_Event const* event)
+{
+ Eina_Accessor *children = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
+ Efl_Model *child;
+ Test_Child_Data *t;
+ unsigned int i = 0;
+
+ fprintf(stderr, "OPAAAAAAa\n");
+ EINA_ACCESSOR_FOREACH(children, i, child)
+ {
+ Efl_Future *futures[3] = {NULL,};
+ Efl_Future *future_all = NULL;
+
+ futures[0] = efl_model_property_get(child, "test_p_int");
+ futures[1] = efl_model_property_get(child, "test_p_true");
+ futures[2] = efl_model_property_get(child, "test_p_false");
+
+ future_all = efl_future_all(futures[0], futures[1], futures[2]);
+
+ t = calloc(1, sizeof(Test_Child_Data));
+ t->tdata = data;
+ t->idx = i;
+ efl_future_then(future_all, _property_get_then, _future_error_then, NULL, t);
+ }
+}
+
+START_TEST(efl_test_model_composite_boolean)
+{
+ Efl_Model_Item *base_model, *child;
+ int i;
+ Eina_Value v;
+ Efl_Model_Composite_Boolean *model;
+ Test_Data *tdata;
+ Efl_Future *future;
+
+ fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
+ fail_if(!efl_object_init(), "ERROR: Cannot init EO!\n");
+
+ eina_value_setup(&v, EINA_VALUE_TYPE_INT);
+
+ base_model = efl_add(EFL_MODEL_ITEM_CLASS, NULL);
+ ck_assert(!!base_model);
+
+ for (i = 0; i < child_number; ++i)
+ {
+ child = efl_model_child_add(base_model);
+ ck_assert(!!child);
+ ck_assert(eina_value_set(&v, base_ints[i]));
+ efl_model_property_set(child, "test_p_int", &v);
+ }
+
+ model = efl_add(EFL_MODEL_COMPOSITE_BOOLEAN_CLASS, NULL,
+ efl_model_composite_boolean_composite_model_set(efl_added, base_model),
+ efl_model_composite_boolean_property_add(efl_added, "test_p_true", EINA_TRUE),
+ efl_model_composite_boolean_property_add(efl_added, "test_p_false", EINA_FALSE));
+ ck_assert(!!model);
+
+ tdata = calloc(1, sizeof(Test_Data));
+ future = efl_model_children_slice_get(model, 0, 0);
+ efl_future_then(future, _children_slice_get_then, _future_error_then, NULL, tdata);
+
+ ecore_main_loop_iterate();
+
+ ck_assert(tdata->success_flag);
+
+ ecore_shutdown();
+}
+END_TEST
+
+void
+efl_test_case_model_composite_boolean(TCase *tc)
+{
+ tcase_add_test(tc, efl_test_model_composite_boolean);
+}