forked from enlightenment/efl
eo: make eo_parent_get/set part of eo_base_class.
This commit is contained in:
parent
b5472db51d
commit
936a8072f2
|
@ -787,39 +787,6 @@ EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line);
|
|||
*/
|
||||
EAPI Eo *eo_add_internal(const char *file, int line, const Eo_Class *klass, Eo *parent, ...);
|
||||
|
||||
/**
|
||||
* @brief Get the parent of an object
|
||||
* @param obj the object to get the parent of.
|
||||
* @return a pointer to the parent object.
|
||||
*
|
||||
* @see eo_parent_set()
|
||||
*/
|
||||
EAPI Eo *eo_parent_get(const Eo *obj);
|
||||
|
||||
/**
|
||||
* @brief Get an iterator on all childrens
|
||||
* @param obj the object to get the childrens from.
|
||||
* @return a pointer to an Eina_Iterator containing all the childrens.
|
||||
*
|
||||
* @see eo_parent_set()
|
||||
*/
|
||||
EAPI Eina_Iterator *eo_children_iterator_new(Eo *obj_id);
|
||||
|
||||
/**
|
||||
* @brief Set the parent of an object
|
||||
* @param obj the object to get the parent of.
|
||||
* @param parent the new parent.
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
|
||||
*
|
||||
* Parents keep references to their children so in order to delete objects
|
||||
* that have parents you need to set parent to NULL or use eo_del() that
|
||||
* does that for you (and also unrefs the object).
|
||||
*
|
||||
* @see eo_del()
|
||||
* @see eo_parent_get()
|
||||
*/
|
||||
EAPI Eina_Bool eo_parent_set(Eo *obj, const Eo *parent);
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the data of an object for a specific class.
|
||||
* @param obj the object to work on.
|
||||
|
@ -1094,6 +1061,9 @@ extern EAPI Eo_Op EO_BASE_BASE_ID;
|
|||
enum {
|
||||
EO_BASE_SUB_ID_CONSTRUCTOR,
|
||||
EO_BASE_SUB_ID_DESTRUCTOR,
|
||||
EO_BASE_SUB_ID_PARENT_SET,
|
||||
EO_BASE_SUB_ID_PARENT_GET,
|
||||
EO_BASE_SUB_ID_CHILDREN_ITERATOR_NEW,
|
||||
EO_BASE_SUB_ID_DATA_SET,
|
||||
EO_BASE_SUB_ID_DATA_GET,
|
||||
EO_BASE_SUB_ID_DATA_DEL,
|
||||
|
@ -1163,6 +1133,36 @@ enum {
|
|||
*/
|
||||
#define eo_base_data_del(key) EO_BASE_ID(EO_BASE_SUB_ID_DATA_DEL), EO_TYPECHECK(const char *, key)
|
||||
|
||||
/**
|
||||
* @brief Set the parent of an object
|
||||
* @param[in] parent the new parent.
|
||||
*
|
||||
* Parents keep references to their children so in order to delete objects
|
||||
* that have parents you need to set parent to NULL or use eo_del() that
|
||||
* does that for you (and also unrefs the object).
|
||||
*
|
||||
* @see eo_del()
|
||||
* @see eo_parent_get()
|
||||
*/
|
||||
#define eo_parent_set(parent) EO_BASE_ID(EO_BASE_SUB_ID_PARENT_SET), EO_TYPECHECK(Eo *, parent)
|
||||
|
||||
/**
|
||||
* @brief Get the parent of an object
|
||||
* @param[out] a pointer to the parent object.
|
||||
*
|
||||
* @see eo_parent_set()
|
||||
*/
|
||||
#define eo_parent_get(parent) EO_BASE_ID(EO_BASE_SUB_ID_PARENT_GET), EO_TYPECHECK(Eo **, parent)
|
||||
|
||||
/**
|
||||
* @brief Get an iterator on all childrens
|
||||
* @param obj the object to get the childrens from.
|
||||
* @return a pointer to an Eina_Iterator containing all the childrens.
|
||||
*
|
||||
* @see eo_parent_set()
|
||||
*/
|
||||
#define eo_children_iterator_new(it) EO_BASE_ID(EO_BASE_SUB_ID_CHILDREN_ITERATOR_NEW), EO_TYPECHECK(Eina_Iterator **, it)
|
||||
|
||||
/**
|
||||
* @def eo_wref_add
|
||||
* @brief Add a new weak reference to obj.
|
||||
|
|
150
src/lib/eo/eo.c
150
src/lib/eo/eo.c
|
@ -1043,133 +1043,17 @@ eo_isa(const Eo *obj_id, const Eo_Class *klass_id)
|
|||
return (func && (func->func == _eo_class_isa_func));
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eo_parent_set(Eo *obj_id, const Eo *parent_id)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
|
||||
if (parent_id)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
|
||||
}
|
||||
|
||||
if (obj->parent == parent_id)
|
||||
return EINA_TRUE;
|
||||
|
||||
_eo_ref(obj);
|
||||
|
||||
if (eo_composite_is(obj_id))
|
||||
{
|
||||
eo_composite_detach(obj_id, obj->parent);
|
||||
}
|
||||
|
||||
if (obj->parent)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(obj->parent, obj_parent, EINA_FALSE);
|
||||
obj_parent->children = eina_list_remove(obj_parent->children, obj_id);
|
||||
eo_xunref(obj_id, obj->parent);
|
||||
}
|
||||
|
||||
obj->parent = (Eo *) parent_id;
|
||||
if (obj->parent)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
|
||||
parent->children = eina_list_append(parent->children, obj_id);
|
||||
eo_xref(obj_id, obj->parent);
|
||||
}
|
||||
|
||||
_eo_unref(obj);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* Children accessor */
|
||||
typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
|
||||
struct _Eo_Children_Iterator
|
||||
{
|
||||
Eina_Iterator iterator;
|
||||
Eina_List *current;
|
||||
_Eo *obj;
|
||||
Eo *obj_id;
|
||||
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_eo_children_iterator_next(Eo_Children_Iterator *it, void **data)
|
||||
{
|
||||
if (!it->current) return EINA_FALSE;
|
||||
|
||||
if (data) *data = eina_list_data_get(it->current);
|
||||
it->current = eina_list_next(it->current);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eo *
|
||||
_eo_children_iterator_container(Eo_Children_Iterator *it)
|
||||
{
|
||||
return it->obj_id;
|
||||
}
|
||||
|
||||
// A little bit hacky, but does the job
|
||||
static void
|
||||
_eo_children_iterator_free(Eo_Children_Iterator *it)
|
||||
_eo_parent_internal_set(_Eo *obj, ...)
|
||||
{
|
||||
_Eo_Class *klass;
|
||||
_Eo *obj;
|
||||
va_list p_list;
|
||||
|
||||
klass = (_Eo_Class*) it->obj->klass;
|
||||
obj = it->obj;
|
||||
|
||||
eina_lock_take(&klass->iterators.trash_lock);
|
||||
if (klass->iterators.trash_count < 8)
|
||||
{
|
||||
klass->iterators.trash_count++;
|
||||
eina_trash_push(&klass->iterators.trash, it);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(it);
|
||||
}
|
||||
eina_lock_release(&klass->iterators.trash_lock);
|
||||
|
||||
_eo_unref(obj);
|
||||
}
|
||||
|
||||
EAPI Eina_Iterator *
|
||||
eo_children_iterator_new(Eo *obj_id)
|
||||
{
|
||||
Eo_Children_Iterator *it;
|
||||
_Eo_Class *klass;
|
||||
|
||||
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
|
||||
|
||||
if (!obj->children) return NULL;
|
||||
|
||||
klass = (_Eo_Class*) obj->klass;
|
||||
|
||||
eina_lock_take(&klass->iterators.trash_lock);
|
||||
it = eina_trash_pop(&klass->iterators.trash);
|
||||
if (it)
|
||||
{
|
||||
klass->iterators.trash_count--;
|
||||
memset(it, 0, sizeof (Eo_Children_Iterator));
|
||||
}
|
||||
else
|
||||
{
|
||||
it = calloc(1, sizeof (Eo_Children_Iterator));
|
||||
}
|
||||
eina_lock_release(&klass->iterators.trash_lock);
|
||||
if (!it) return NULL;
|
||||
|
||||
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
||||
it->current = obj->children;
|
||||
it->obj = _eo_ref(obj);
|
||||
it->obj_id = obj_id;
|
||||
|
||||
it->iterator.next = FUNC_ITERATOR_NEXT(_eo_children_iterator_next);
|
||||
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eo_children_iterator_container);
|
||||
it->iterator.free = FUNC_ITERATOR_FREE(_eo_children_iterator_free);
|
||||
|
||||
return &it->iterator;
|
||||
va_start(p_list, obj);
|
||||
_eo_op_internal("eo.c", 1049, obj, obj->klass,
|
||||
EO_OP_TYPE_REGULAR, EO_BASE_ID(EO_BASE_SUB_ID_PARENT_SET),
|
||||
&p_list);
|
||||
va_end(p_list);
|
||||
}
|
||||
|
||||
EAPI Eo *
|
||||
|
@ -1212,12 +1096,13 @@ eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent
|
|||
#endif
|
||||
Eo_Id obj_id = _eo_id_allocate(obj);
|
||||
obj->obj_id = obj_id;
|
||||
eo_parent_set((Eo *)obj_id, parent_id);
|
||||
|
||||
_eo_condtor_reset(obj);
|
||||
|
||||
_eo_ref(obj);
|
||||
|
||||
_eo_parent_internal_set(obj, parent_id);
|
||||
|
||||
/* Run the relevant do stuff. */
|
||||
{
|
||||
va_list p_list;
|
||||
|
@ -1322,7 +1207,7 @@ eo_unref(const Eo *obj_id)
|
|||
EAPI void
|
||||
eo_del(const Eo *obj)
|
||||
{
|
||||
eo_parent_set((Eo *) obj, NULL);
|
||||
eo_do((Eo *) obj, eo_parent_set(NULL));
|
||||
eo_unref(obj);
|
||||
}
|
||||
|
||||
|
@ -1334,14 +1219,6 @@ eo_ref_get(const Eo *obj_id)
|
|||
return obj->refcount;
|
||||
}
|
||||
|
||||
EAPI Eo *
|
||||
eo_parent_get(const Eo *obj_id)
|
||||
{
|
||||
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
|
||||
|
||||
return obj->parent;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eo_error_set_internal(const Eo *obj_id, const char *file, int line)
|
||||
{
|
||||
|
@ -1624,7 +1501,8 @@ eo_composite_attach(Eo *comp_obj_id, Eo *parent_id)
|
|||
|
||||
comp_obj->composite = EINA_TRUE;
|
||||
parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
|
||||
eo_parent_set(comp_obj_id, parent_id);
|
||||
|
||||
eo_do(comp_obj_id, eo_parent_set(parent_id));
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1635,7 +1513,7 @@ eo_composite_detach(Eo *comp_obj_id, Eo *parent_id)
|
|||
|
||||
comp_obj->composite = EINA_FALSE;
|
||||
parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id);
|
||||
eo_parent_set(comp_obj_id, NULL);
|
||||
eo_do(comp_obj_id, eo_parent_set(NULL));
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
|
|
@ -16,6 +16,9 @@ typedef struct _Eo_Callback_Description Eo_Callback_Description;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
Eina_List *children;
|
||||
Eo *parent;
|
||||
|
||||
Eina_Inlist *generic_data;
|
||||
Eo ***wrefs;
|
||||
|
||||
|
@ -108,6 +111,147 @@ _data_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_parent_set(Eo *obj, void *class_data, va_list *list)
|
||||
{
|
||||
Private_Data *pd = (Private_Data *) class_data;
|
||||
|
||||
EO_PARAMETER_GET(Eo *, parent_id, list);
|
||||
|
||||
if (pd->parent == parent_id)
|
||||
return ;
|
||||
|
||||
if (eo_composite_is(obj))
|
||||
{
|
||||
eo_composite_detach(obj, pd->parent);
|
||||
}
|
||||
|
||||
if (pd->parent)
|
||||
{
|
||||
Private_Data *old_parent_pd;
|
||||
|
||||
old_parent_pd = eo_data_scope_get(pd->parent, EO_BASE_CLASS);
|
||||
old_parent_pd->children = eina_list_remove(old_parent_pd->children,
|
||||
obj);
|
||||
eo_xunref(obj, pd->parent);
|
||||
}
|
||||
|
||||
pd->parent = parent_id;
|
||||
if (pd->parent)
|
||||
{
|
||||
Private_Data *parent_pd = NULL;
|
||||
|
||||
parent_pd = eo_data_scope_get(parent_id, EO_BASE_CLASS);
|
||||
parent_pd->children = eina_list_append(parent_pd->children,
|
||||
obj);
|
||||
eo_xref(obj, pd->parent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_parent_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
|
||||
{
|
||||
Private_Data *pd = (Private_Data *) class_data;
|
||||
|
||||
EO_PARAMETER_GET(Eo **, parent_id, list);
|
||||
|
||||
if (!parent_id) return ;
|
||||
*parent_id = pd->parent;
|
||||
}
|
||||
|
||||
|
||||
/* Children accessor */
|
||||
typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
|
||||
struct _Eo_Children_Iterator
|
||||
{
|
||||
Eina_Iterator iterator;
|
||||
Eina_List *current;
|
||||
_Eo *obj;
|
||||
Eo *obj_id;
|
||||
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_eo_children_iterator_next(Eo_Children_Iterator *it, void **data)
|
||||
{
|
||||
if (!it->current) return EINA_FALSE;
|
||||
|
||||
if (data) *data = eina_list_data_get(it->current);
|
||||
it->current = eina_list_next(it->current);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eo *
|
||||
_eo_children_iterator_container(Eo_Children_Iterator *it)
|
||||
{
|
||||
return it->obj_id;
|
||||
}
|
||||
|
||||
static void
|
||||
_eo_children_iterator_free(Eo_Children_Iterator *it)
|
||||
{
|
||||
_Eo_Class *klass;
|
||||
_Eo *obj;
|
||||
|
||||
klass = (_Eo_Class*) it->obj->klass;
|
||||
obj = it->obj;
|
||||
|
||||
eina_lock_take(&klass->iterators.trash_lock);
|
||||
if (klass->iterators.trash_count < 8)
|
||||
{
|
||||
klass->iterators.trash_count++;
|
||||
eina_trash_push(&klass->iterators.trash, it);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(it);
|
||||
}
|
||||
eina_lock_release(&klass->iterators.trash_lock);
|
||||
|
||||
_eo_unref(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_children_iterator_new(Eo *obj_id, void *class_data, va_list *list)
|
||||
{
|
||||
Private_Data *pd = class_data;
|
||||
_Eo_Class *klass;
|
||||
|
||||
EO_PARAMETER_GET(Eo_Children_Iterator **, it, list);
|
||||
EO_OBJ_POINTER_RETURN(obj_id, obj);
|
||||
|
||||
if (!it) return ;
|
||||
*it = NULL;
|
||||
|
||||
if (!pd->children) return ;
|
||||
|
||||
klass = (_Eo_Class *) obj->klass;
|
||||
|
||||
eina_lock_take(&klass->iterators.trash_lock);
|
||||
*it = eina_trash_pop(&klass->iterators.trash);
|
||||
if (*it)
|
||||
{
|
||||
klass->iterators.trash_count--;
|
||||
memset(*it, 0, sizeof (Eo_Children_Iterator));
|
||||
}
|
||||
else
|
||||
{
|
||||
*it = calloc(1, sizeof (Eo_Children_Iterator));
|
||||
}
|
||||
eina_lock_release(&klass->iterators.trash_lock);
|
||||
if (!*it) return ;
|
||||
|
||||
EINA_MAGIC_SET(&(*it)->iterator, EINA_MAGIC_ITERATOR);
|
||||
(*it)->current = obj->children;
|
||||
(*it)->obj = _eo_ref(obj);
|
||||
(*it)->obj_id = obj_id;
|
||||
|
||||
(*it)->iterator.next = FUNC_ITERATOR_NEXT(_eo_children_iterator_next);
|
||||
(*it)->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eo_children_iterator_container);
|
||||
(*it)->iterator.free = FUNC_ITERATOR_FREE(_eo_children_iterator_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_dbg_info_get(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED,
|
||||
va_list *data EINA_UNUSED)
|
||||
|
@ -746,8 +890,13 @@ _constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
|
|||
static void
|
||||
_destructor(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
|
||||
{
|
||||
Private_Data *pd = class_data;
|
||||
|
||||
DBG("%p - %s.", obj, eo_class_name_get(MY_CLASS));
|
||||
|
||||
while (pd->children)
|
||||
eo_do(eina_list_data_get(pd->children), eo_parent_set(NULL));
|
||||
|
||||
_eo_generic_data_del_all(class_data);
|
||||
_wref_destruct(class_data);
|
||||
_eo_callback_remove_all(class_data);
|
||||
|
@ -763,6 +912,9 @@ _class_constructor(Eo_Class *klass)
|
|||
const Eo_Op_Func_Description func_desc[] = {
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_PARENT_SET), _parent_set),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_PARENT_GET), _parent_get),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CHILDREN_ITERATOR_NEW), _children_iterator_new),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DATA_SET), _data_set),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DATA_GET), _data_get),
|
||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DATA_DEL), _data_del),
|
||||
|
@ -791,6 +943,9 @@ _class_constructor(Eo_Class *klass)
|
|||
static const Eo_Op_Description op_desc[] = {
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_CONSTRUCTOR, "Constructor"),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_DESTRUCTOR, "Destructor"),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_PARENT_SET, "Set parent"),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_PARENT_GET, "Get parent"),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_CHILDREN_ITERATOR_NEW, "Children Iterator"),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_DATA_SET, "Set data for key."),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_DATA_GET, "Get data for key."),
|
||||
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_DATA_DEL, "Del key."),
|
||||
|
|
|
@ -214,11 +214,6 @@ _eo_del_internal(const char *file, int line, _Eo *obj)
|
|||
}
|
||||
}
|
||||
|
||||
while (obj->children)
|
||||
{
|
||||
eo_parent_set(eina_list_data_get(obj->children), NULL); // ZZZ
|
||||
}
|
||||
|
||||
obj->del = EINA_TRUE;
|
||||
obj->refcount--;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue