forked from enlightenment/efl
Eo composite: change composite objects to not be tied to parent
This commit breaks behaviour! Re-parenting no longer detaches composite objects, so watch out. Now you can have an object be a composite object of an object although it's not its child. This allows widgets to do things like having an object as the child of a child object while still making it a composite object to the main object. With this change, composite objects don't keep a reference to the child, but instead composite "bonds" are implicitly removed when either the parent or the child are destructed.
This commit is contained in:
parent
9d5caf00b6
commit
537b138a23
|
@ -19,6 +19,7 @@ typedef struct
|
|||
{
|
||||
const char *id;
|
||||
const char *comment;
|
||||
Eo *composite_parent;
|
||||
Eina_Inlist *generic_data;
|
||||
Eo ***wrefs;
|
||||
} Eo_Base_Extension;
|
||||
|
@ -82,7 +83,7 @@ _eo_base_extension_noneed(Eo_Base_Data *pd)
|
|||
{
|
||||
Eo_Base_Extension *ext = pd->ext;
|
||||
if ((!ext) || (ext->id) || (ext->comment) || (ext->generic_data) ||
|
||||
(ext->wrefs)) return;
|
||||
(ext->wrefs) || (ext->composite_parent)) return;
|
||||
_eo_base_extension_free(pd->ext);
|
||||
pd->ext = NULL;
|
||||
}
|
||||
|
@ -478,11 +479,6 @@ _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id)
|
|||
if (pd->parent == parent_id)
|
||||
return;
|
||||
|
||||
if (eo_composite_part_is(obj) && pd->parent)
|
||||
{
|
||||
eo_composite_detach(pd->parent, obj);
|
||||
}
|
||||
|
||||
if (pd->parent)
|
||||
{
|
||||
Eo_Base_Data *old_parent_pd;
|
||||
|
@ -1236,23 +1232,34 @@ _eo_base_composite_attach(Eo *parent_id, Eo_Base_Data *pd EINA_UNUSED, Eo *comp_
|
|||
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
||||
EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
|
||||
|
||||
if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass))) return EINA_FALSE;
|
||||
if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass)))
|
||||
{
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
Eo_Base_Data *comp_pd = eo_data_scope_get(comp_obj_id, EO_BASE_CLASS);
|
||||
/* Don't composite if we already have a composite object of this type */
|
||||
{
|
||||
Eina_List *itr;
|
||||
Eo *emb_obj_id;
|
||||
EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE);
|
||||
if(emb_obj->klass == comp_obj->klass)
|
||||
if (emb_obj->klass == comp_obj->klass)
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
comp_obj->composite = EINA_TRUE;
|
||||
parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
|
||||
if (eo_composite_part_is(comp_obj_id))
|
||||
{
|
||||
eo_composite_detach(comp_pd->ext->composite_parent, comp_obj_id);
|
||||
}
|
||||
|
||||
eo_parent_set(comp_obj_id, parent_id);
|
||||
/* Set the parent comp on the child. */
|
||||
_eo_base_extension_need(comp_pd);
|
||||
comp_pd->ext->composite_parent = parent_id;
|
||||
|
||||
parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -1263,22 +1270,25 @@ _eo_base_composite_detach(Eo *parent_id, Eo_Base_Data *pd EINA_UNUSED, Eo *comp_
|
|||
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
||||
EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
|
||||
|
||||
if (!comp_obj->composite)
|
||||
if (!eo_composite_part_is(comp_obj_id))
|
||||
return EINA_FALSE;
|
||||
|
||||
comp_obj->composite = EINA_FALSE;
|
||||
parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id);
|
||||
eo_parent_set(comp_obj_id, NULL);
|
||||
/* Clear the comp parent on the child. */
|
||||
{
|
||||
Eo_Base_Data *comp_pd = eo_data_scope_get(comp_obj_id, EO_BASE_CLASS);
|
||||
comp_pd->ext->composite_parent = NULL;
|
||||
|
||||
_eo_base_extension_noneed(comp_pd);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_eo_base_composite_part_is(Eo *comp_obj_id, Eo_Base_Data *pd EINA_UNUSED)
|
||||
_eo_base_composite_part_is(Eo *comp_obj_id EINA_UNUSED, Eo_Base_Data *pd)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
||||
|
||||
return comp_obj->composite;
|
||||
return pd->ext && pd->ext->composite_parent;
|
||||
}
|
||||
|
||||
/* Eo_Dbg */
|
||||
|
@ -1408,6 +1418,22 @@ _eo_base_destructor(Eo *obj, Eo_Base_Data *pd)
|
|||
eo_parent_set(child, NULL);
|
||||
}
|
||||
|
||||
/* If we are a composite object, detach children */
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN(obj, obj_data);
|
||||
Eina_List *itr;
|
||||
Eo *emb_obj_id;
|
||||
EINA_LIST_FOREACH(obj_data->composite_objects, itr, emb_obj_id)
|
||||
{
|
||||
eo_composite_detach(obj, emb_obj_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (pd->ext && pd->ext->composite_parent)
|
||||
{
|
||||
eo_composite_detach(pd->ext->composite_parent, obj);
|
||||
}
|
||||
|
||||
if (pd->parent)
|
||||
{
|
||||
ERR("Object '%p' still has a parent at the time of destruction.", obj);
|
||||
|
|
|
@ -103,7 +103,6 @@ struct _Eo_Object
|
|||
Eina_Bool condtor_done:1;
|
||||
Eina_Bool finalized:1;
|
||||
|
||||
Eina_Bool composite:1;
|
||||
Eina_Bool del_triggered:1;
|
||||
Eina_Bool destructed:1;
|
||||
Eina_Bool manual_free:1;
|
||||
|
|
|
@ -299,12 +299,24 @@ START_TEST(eo_composite_tests)
|
|||
fail_if(!obj);
|
||||
Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
|
||||
fail_if(!obj2);
|
||||
Eo *obj3 = eo_add(SIMPLE_CLASS, NULL);
|
||||
fail_if(!obj3);
|
||||
|
||||
eo_composite_attach(obj, obj2);
|
||||
eo_parent_set(obj2, NULL);
|
||||
fail_if(eo_composite_part_is(obj2));
|
||||
fail_if(!eo_composite_part_is(obj2));
|
||||
|
||||
/* Check swapping attachments works. */
|
||||
eo_composite_attach(obj3, obj2);
|
||||
fail_if(!eo_composite_part_is(obj2));
|
||||
|
||||
/* Check that a deletion of a child detaches from the parent. */
|
||||
eo_del(obj2);
|
||||
fail_if(!eo_composite_attach(obj3, obj));
|
||||
|
||||
/* Check that a deletion of the parent detaches the child. */
|
||||
eo_del(obj3);
|
||||
fail_if(eo_composite_part_is(obj));
|
||||
|
||||
eo_unref(obj2);
|
||||
eo_unref(obj);
|
||||
|
||||
eo_shutdown();
|
||||
|
|
Loading…
Reference in New Issue