* @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.
*
* @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.
/* 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;
}
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);
}
}
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",
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);
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;
+ *comp_itr = NULL;
+ eo_do(comp_obj_id, eo_parent_set(NULL));
+ return EINA_TRUE;
+ }
+ }
- 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));
+ return EINA_FALSE;
}
EAPI Eina_Bool
Eina_Inlist *data_xrefs;
#endif
- Eina_List *composite_objects;
+ const _Eo_Object **composites;
int refcount;
int datarefcount;
Eina_Bool composite:1;
Eina_Bool del:1;
Eina_Bool manual_free:1;
+ /* data [parents, self, mixins]*/
+ /* [composite*] */
};
typedef struct _Dich_Chain1 Dich_Chain1;
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 */
/*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));
}
}