#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "ecore_internal.h" #include "efl_model_container_private.h" #define MY_CLASS EFL_MODEL_CONTAINER_CLASS void * _value_copy_alloc(void *v, const Eina_Value_Type *type) { if (!v) return v; if (type == EINA_VALUE_TYPE_STRINGSHARE) return (void*) eina_stringshare_ref(v); else if (type == EINA_VALUE_TYPE_STRING) return (void*) strdup(v); else { void *ret = malloc(type->value_size); memcpy(ret, v, type->value_size); return ret; } } void _value_free(void *v, const Eina_Value_Type *type) { if (!v) return; if (type == EINA_VALUE_TYPE_STRINGSHARE) return eina_stringshare_del(v); else free(v); } static void _values_free(Eina_Array *values, const Eina_Value_Type *type) { unsigned int i; void *v; Eina_Array_Iterator it; EINA_ARRAY_ITER_NEXT(values, i, v, it) { _value_free(v, type); } eina_array_free(values); } static void _property_data_free_cb(void *data) { Child_Property_Data *cpd = data; _values_free(cpd->values, cpd->type); free(cpd); } static Efl_Object * _efl_model_container_efl_object_constructor(Eo *obj, Efl_Model_Container_Data *sd) { obj = efl_constructor(efl_super(obj, MY_CLASS)); if (!obj) return NULL; sd->obj = obj; sd->properties = eina_hash_stringshared_new(_property_data_free_cb); return obj; } static void _efl_model_container_efl_object_destructor(Eo *obj, Efl_Model_Container_Data *sd) { Eina_Stringshare *key; Eina_Iterator *it; Efl_Model *child; EINA_LIST_FREE(sd->childrens, child) { if (child) efl_parent_set(child, NULL); } it = eina_hash_iterator_key_new(sd->properties); EINA_ITERATOR_FOREACH(it, key) eina_stringshare_del(key); eina_iterator_free(it); eina_hash_free(sd->properties); efl_destructor(efl_super(obj, MY_CLASS)); } static const Eina_Value_Type * _efl_model_container_child_property_value_type_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property) { Child_Property_Data *cpd; Eina_Stringshare *key; key = eina_stringshare_add(property); cpd = eina_hash_find(sd->properties, key); eina_stringshare_del(key); if (!cpd) return NULL; return cpd->type; } static Eina_Iterator * _efl_model_container_child_property_values_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property) { Child_Property_Data *cpd; Eina_Stringshare *key; key = eina_stringshare_add(property); cpd = eina_hash_find(sd->properties, key); eina_stringshare_del(key); if (!cpd) return NULL; return eina_array_iterator_new(cpd->values); } static Eina_Bool _efl_model_container_child_property_add(Eo *obj, Efl_Model_Container_Data *sd, const char *name, const Eina_Value_Type *type, Eina_Iterator *values) { Eina_Array *arr = NULL; void *data = NULL; Child_Property_Data *cpd = NULL; unsigned int i, in_count, children_count; Eina_Error err = EFL_MODEL_ERROR_INCORRECT_VALUE; name = eina_stringshare_add(name); if (!type || !values) { EINA_LOG_WARN("Invalid input data"); goto on_error; } err = ENOMEM; arr = eina_array_new(4); if (!arr) goto on_error; EINA_ITERATOR_FOREACH(values, data) { void *new_data = _value_copy_alloc(data, type); if ((data && !new_data) || !eina_array_push(arr, new_data)) { if (new_data) _value_free(new_data, type); goto on_error; } } eina_iterator_free(values); err = EFL_MODEL_ERROR_UNKNOWN; cpd = eina_hash_find(sd->properties, name); if (!cpd) { cpd = calloc(1, sizeof(Child_Property_Data)); if (!cpd) goto on_error; cpd->type = type; cpd->values = arr; if (!eina_hash_direct_add(sd->properties, name, cpd)) goto on_error; } else { eina_stringshare_del(name); _values_free(cpd->values, cpd->type); cpd->type = type; cpd->values = arr; } in_count = eina_array_count(arr); children_count = eina_list_count(sd->childrens); for (i = children_count; i < in_count; ++i) { Efl_Model_Children_Event cevt; Efl_Model *child; child = efl_add(EFL_MODEL_CONTAINER_ITEM_CLASS, obj, efl_model_container_item_define(efl_added, sd, i)); sd->childrens = eina_list_append(sd->childrens, child); cevt.index = i; efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt); } if (in_count > children_count) efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, NULL); return EINA_TRUE; on_error: eina_stringshare_del(name); if (cpd) free(cpd); if (arr) _values_free(arr, type); eina_error_set(err); return EINA_FALSE; } static Eina_Array * _efl_model_container_efl_model_properties_get(const Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd) { Eina_Iterator *it; Eina_Array *r; Eina_Stringshare *s; r = eina_array_new(1); it = eina_hash_iterator_key_new(sd->properties); EINA_ITERATOR_FOREACH(it, s) eina_array_push(r, eina_stringshare_ref(s)); eina_iterator_free(it); return r; } static Eina_Future * _efl_model_container_efl_model_property_set(Eo *obj, Efl_Model_Container_Data *pd EINA_UNUSED, const char *property EINA_UNUSED, Eina_Value *value EINA_UNUSED) { return eina_future_rejected(efl_loop_future_scheduler_get(obj), EFL_MODEL_ERROR_NOT_FOUND); } static Eina_Value * _efl_model_container_efl_model_property_get(const Eo *obj EINA_UNUSED, Efl_Model_Container_Data *pd EINA_UNUSED, const char *property EINA_UNUSED) { return eina_value_error_new(EFL_MODEL_ERROR_NOT_FOUND); } static Eina_Future * _efl_model_container_efl_model_children_slice_get(Eo *obj, Efl_Model_Container_Data *sd, unsigned int start, unsigned int count) { Eina_Value v; v = efl_model_list_value_get(sd->childrens, start, count); return eina_future_resolved(efl_loop_future_scheduler_get(obj), v); } static unsigned int _efl_model_container_efl_model_children_count_get(const Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd) { return eina_list_count(sd->childrens); } static Eo * _efl_model_container_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED) { EINA_LOG_WARN("child_add not supported by Efl.Model.Container"); eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED); return NULL; } static void _efl_model_container_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED) { EINA_LOG_WARN("child_del not supported by Efl.Model.Container"); eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED); } #include "efl_model_container.eo.c"