From ef09ef748924c22074e70b97ebc7726fca1513ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Wed, 5 Mar 2014 23:57:39 +0100 Subject: [PATCH] eo: replace composite_objects Eina_List with an array of Eo_Object* as we don't support multiple composites of the same class, and know at class elaboration how many composites we should have, we can create the composites array and pack it at the end of the object. --- src/lib/eo/Eo.h | 6 +- src/lib/eo/eo.c | 81 +++++++++++++------ src/lib/eo/eo_private.h | 13 +-- .../composite_objects_main.c | 3 +- 4 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 47cb0a059e..ef43decad6 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -940,7 +940,8 @@ EAPI Eina_Bool eo_destructed_is(const Eo *obj); * @param parent the "parent" object. * @return EINA_TRUE if successfull. EINA_FALSE otherwise. * - * The class of comp_obj must be part of the extensions of the class of the parent. + * The class of comp_obj must be of the type EO_CLASS_TYPE_REGULAR + * and be part of the extensions of the class of the parent. * It is not possible to attach more then 1 composite of the same class. * This functions also sets the parent of comp_obj to parent. * @@ -953,13 +954,14 @@ EAPI Eina_Bool eo_composite_attach(Eo *comp_obj, Eo *parent); * @brief Detach a composite object from another object. * @param comp_obj the object attached to parent. * @param parent the "parent" object. + * @return EINA_TRUE if successfull. EINA_FALSE otherwise. * * This functions also sets the parent of comp_obj to @c NULL. * * @see eo_composite_attach() * @see eo_composite_is() */ -EAPI void eo_composite_detach(Eo *comp_obj, Eo *parent); +EAPI Eina_Bool eo_composite_detach(Eo *comp_obj, Eo *parent); /** * @brief Check if an object is a composite object. diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index bce20dd4a1..26a91d233d 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -311,18 +311,19 @@ _eo_op_internal(const char *file, int line, Eo_Base *eo_ptr, const _Eo_Class *cu /* Try composite objects */ if (op_type == EO_OP_TYPE_REGULAR) { - Eina_List *itr; - Eo *emb_obj_id; - EINA_LIST_FOREACH(((_Eo_Object *) eo_ptr)->composite_objects, itr, emb_obj_id) - { - /* FIXME: Clean this up a bit. */ - EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE); - if (_eo_op_internal(file, line, (Eo_Base *) emb_obj, emb_obj->klass, op_type, op, p_list)) - { - return EINA_TRUE; - } - } + const _Eo_Object **comp_itr = ((_Eo_Object *) eo_ptr)->composites; + if (!comp_itr) return EINA_FALSE; + + for (unsigned int i = 0; i < ((_Eo_Object *) eo_ptr)->klass->composites_count; i++, comp_itr++) + if (*comp_itr) + { + if (_eo_op_internal(file, line, (Eo_Base *) (*comp_itr), (*comp_itr)->klass, op_type, op, p_list)) + { + return EINA_TRUE; + } + } } + return EINA_FALSE; } @@ -921,6 +922,8 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...) EINA_LIST_FREE(extn_list, extn) { *(extn_itr++) = extn; + if (extn->desc->type == EO_CLASS_TYPE_REGULAR) + klass->composites_count += 1; DBG("Added '%s' extension", extn->desc->name); } @@ -963,6 +966,8 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...) } klass->obj_size = _eo_sz + extn_data_off; + if (klass->composites_count > 0) + klass->obj_size += (klass->composites_count * sizeof(_Eo_Object *)); if (getenv("EO_DEBUG")) { fprintf(stderr, "Eo class '%s' will take %u bytes per object.\n", @@ -1089,6 +1094,11 @@ eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent obj->refcount++; obj->klass = klass; + if (klass->composites_count == 0) + obj->composites = NULL; + else + obj->composites = (const _Eo_Object **) + ((char *) obj + klass->obj_size - (klass->composites_count * sizeof(_Eo_Object *))); #ifndef HAVE_EO_ID EINA_MAGIC_SET((Eo_Base *) obj, EO_EINA_MAGIC); @@ -1497,39 +1507,62 @@ eo_shutdown(void) EAPI Eina_Bool eo_composite_attach(Eo *comp_obj_id, Eo *parent_id) { + const _Eo_Object **comp_itr; + const _Eo_Object **comp_dst; + EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE); + if (!parent->composites) return EINA_FALSE; + if (comp_obj->klass->desc->type != EO_CLASS_TYPE_REGULAR) return EINA_FALSE; if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass))) return EINA_FALSE; + comp_dst = NULL; + comp_itr = parent->composites; + for (unsigned int i = 0; i < parent->klass->composites_count; i++, comp_itr++) { - Eina_List *itr; - Eo *emb_obj_id; - EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id) + if (*comp_itr) { - EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE); - if(emb_obj->klass == comp_obj->klass) + if ((*comp_itr)->klass == comp_obj->klass) return EINA_FALSE; } + else if (!comp_dst) + comp_dst = comp_itr; } - comp_obj->composite = EINA_TRUE; - parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id); + if (!comp_dst) + return EINA_FALSE; + comp_obj->composite = EINA_TRUE; + *comp_dst = comp_obj; eo_do(comp_obj_id, eo_parent_set(parent_id)); return EINA_TRUE; } -EAPI void +EAPI Eina_Bool eo_composite_detach(Eo *comp_obj_id, Eo *parent_id) { - EO_OBJ_POINTER_RETURN(comp_obj_id, comp_obj); - EO_OBJ_POINTER_RETURN(parent_id, parent); + const _Eo_Object **comp_itr; - comp_obj->composite = EINA_FALSE; - parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id); - eo_do(comp_obj_id, eo_parent_set(NULL)); + EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); + EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE); + + if (!parent->composites) return EINA_FALSE; + + comp_itr = parent->composites; + for (unsigned int i = 0; i < parent->klass->composites_count; i++, comp_itr++) + { + if (*comp_itr == comp_obj) + { + comp_obj->composite = EINA_FALSE; + *comp_itr = NULL; + eo_do(comp_obj_id, eo_parent_set(NULL)); + return EINA_TRUE; + } + } + + return EINA_FALSE; } EAPI Eina_Bool diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h index 2fd13a9dad..a985556b70 100644 --- a/src/lib/eo/eo_private.h +++ b/src/lib/eo/eo_private.h @@ -94,7 +94,7 @@ struct _Eo_Object Eina_Inlist *data_xrefs; #endif - Eina_List *composite_objects; + const _Eo_Object **composites; int refcount; int datarefcount; @@ -105,6 +105,8 @@ struct _Eo_Object Eina_Bool composite:1; Eina_Bool del:1; Eina_Bool manual_free:1; + /* data [parents, self, mixins]*/ + /* [composite*] */ }; typedef struct _Dich_Chain1 Dich_Chain1; @@ -158,6 +160,7 @@ struct _Eo_Class unsigned int chain_size; unsigned int base_id; unsigned int data_offset; /* < Offset of the data within object data. */ + unsigned int composites_count; Eina_Bool constructed : 1; /* [extensions*] + NULL */ @@ -229,11 +232,11 @@ _eo_del_internal(const char *file, int line, _Eo_Object *obj) /*FIXME: add eo_class_unref(klass) ? - just to clear the caches. */ { - Eina_List *itr, *itr_n; - Eo *emb_obj; - EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj) + const _Eo_Object **comp_itr = obj->composites; + for (unsigned int i = 0; i < obj->klass->composites_count; i++, comp_itr++) { - eo_composite_detach(emb_obj, _eo_id_get(obj)); + if (*comp_itr) + eo_composite_detach(_eo_id_get(*comp_itr), _eo_id_get(obj)); } } diff --git a/src/tests/eo/composite_objects/composite_objects_main.c b/src/tests/eo/composite_objects/composite_objects_main.c index 1d5b8c0474..ba96eb4a22 100644 --- a/src/tests/eo/composite_objects/composite_objects_main.c +++ b/src/tests/eo/composite_objects/composite_objects_main.c @@ -54,7 +54,8 @@ main(int argc, char *argv[]) fail_if(cb_called); fail_if(!eo_composite_is(simple)); - eo_composite_detach(simple, obj); + fail_if(!eo_composite_detach(simple, obj)); + fail_if(eo_composite_detach(simple, obj)); fail_if(eo_composite_is(simple)); fail_if(!eo_composite_attach(simple, obj)); fail_if(!eo_composite_is(simple));