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.
This commit is contained in:
Jérémy Zurcher 2014-03-05 23:57:39 +01:00
parent b763db3666
commit ef09ef7489
4 changed files with 71 additions and 32 deletions

View File

@ -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.

View File

@ -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

View File

@ -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));
}
}

View File

@ -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));