forked from enlightenment/efl
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:
parent
b763db3666
commit
ef09ef7489
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
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)
|
||||
{
|
||||
/* 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))
|
||||
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;
|
||||
|
||||
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;
|
||||
parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id);
|
||||
*comp_itr = NULL;
|
||||
eo_do(comp_obj_id, eo_parent_set(NULL));
|
||||
return EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue