forked from enlightenment/efl
Eo: Overhauled the mro-walking mechanism.
A lot faster now. SVN revision: 70793
This commit is contained in:
parent
8c5644d5f8
commit
dba7e09641
|
@ -22,6 +22,12 @@ static void eo_constructor_error_unset(Eo *obj);
|
||||||
|
|
||||||
typedef struct _Eo_Callback_Description Eo_Callback_Description;
|
typedef struct _Eo_Callback_Description Eo_Callback_Description;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Eo_Op op;
|
||||||
|
const Eo_Class **kls_itr;
|
||||||
|
} Eo_Kls_Itr;
|
||||||
|
|
||||||
#define EO_EINA_MAGIC 0xa186bc32 /* Nothing magical about this number. */
|
#define EO_EINA_MAGIC 0xa186bc32 /* Nothing magical about this number. */
|
||||||
#define EO_EINA_MAGIC_STR "Eo"
|
#define EO_EINA_MAGIC_STR "Eo"
|
||||||
#define EO_CLASS_EINA_MAGIC 0xa186bb32 /* Nothing magical about this number. */
|
#define EO_CLASS_EINA_MAGIC 0xa186bb32 /* Nothing magical about this number. */
|
||||||
|
@ -59,7 +65,7 @@ struct _Eo {
|
||||||
Eina_Inlist *callbacks;
|
Eina_Inlist *callbacks;
|
||||||
int walking_list;
|
int walking_list;
|
||||||
|
|
||||||
Eina_Inlist *kls_itr;
|
Eo_Kls_Itr mro_itr;
|
||||||
|
|
||||||
Eina_Bool delete:1;
|
Eina_Bool delete:1;
|
||||||
Eina_Bool construct_error:1;
|
Eina_Bool construct_error:1;
|
||||||
|
@ -250,80 +256,53 @@ _eo_op_id_name_get(Eo_Op op)
|
||||||
return (desc) ? desc->name : NULL;
|
return (desc) ? desc->name : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
static inline void
|
||||||
|
_eo_kls_itr_init(Eo *obj, Eo_Op op, Eo_Kls_Itr *prev_state)
|
||||||
{
|
{
|
||||||
EINA_INLIST;
|
prev_state->op = obj->mro_itr.op;
|
||||||
Eo_Op op;
|
prev_state->kls_itr = obj->mro_itr.kls_itr;
|
||||||
const Eo_Class **kls_itr;
|
|
||||||
} Eo_Kls_Itr_Node;
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
/* If we are in a constructor/destructor or we changed an op - init. */
|
||||||
_eo_kls_itr_init(Eo *obj, Eo_Op op)
|
if ((op == EO_NOOP) || (obj->mro_itr.op != op))
|
||||||
{
|
|
||||||
if (obj->kls_itr)
|
|
||||||
{
|
{
|
||||||
Eo_Kls_Itr_Node *node =
|
obj->mro_itr.op = op;
|
||||||
EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eo_Kls_Itr_Node);
|
obj->mro_itr.kls_itr = obj->klass->mro;
|
||||||
if (node->op == op)
|
|
||||||
{
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
Eo_Kls_Itr_Node *node = calloc(1, sizeof(*node));
|
|
||||||
node->op = op;
|
|
||||||
node->kls_itr = obj->klass->mro;
|
|
||||||
obj->kls_itr = eina_inlist_prepend(obj->kls_itr,
|
|
||||||
EINA_INLIST_GET(node));
|
|
||||||
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_eo_kls_itr_end(Eo *obj, Eo_Op op)
|
_eo_kls_itr_end(Eo *obj, Eo_Kls_Itr *prev_state)
|
||||||
{
|
{
|
||||||
Eo_Kls_Itr_Node *node =
|
if (obj->mro_itr.op != prev_state->op)
|
||||||
EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eo_Kls_Itr_Node);
|
{
|
||||||
|
obj->mro_itr.op = prev_state->op;
|
||||||
if (node->op != op)
|
obj->mro_itr.kls_itr = prev_state->kls_itr;
|
||||||
return;
|
}
|
||||||
|
|
||||||
obj->kls_itr = eina_inlist_remove(obj->kls_itr, obj->kls_itr);
|
|
||||||
free(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const Eo_Class *
|
static inline const Eo_Class *
|
||||||
_eo_kls_itr_get(Eo *obj)
|
_eo_kls_itr_get(Eo *obj)
|
||||||
{
|
{
|
||||||
Eo_Kls_Itr_Node *node =
|
return (obj->mro_itr.kls_itr) ? *(obj->mro_itr.kls_itr) : NULL;
|
||||||
EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eo_Kls_Itr_Node);
|
|
||||||
|
|
||||||
return (node) ? *(node->kls_itr) : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const Eo_Class *
|
static inline const Eo_Class *
|
||||||
_eo_kls_itr_next(Eo *obj, Eo_Op op)
|
_eo_kls_itr_next(Eo *obj, Eo_Op op)
|
||||||
{
|
{
|
||||||
Eo_Kls_Itr_Node *node =
|
if (obj->mro_itr.op != op)
|
||||||
EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eo_Kls_Itr_Node);
|
|
||||||
|
|
||||||
if (!node || (node->op != op))
|
|
||||||
{
|
{
|
||||||
Eo_Op node_op = (node) ? node->op : EO_NOOP;
|
Eo_Op node_op = obj->mro_itr.op;
|
||||||
ERR("Called with op %d ('%s') while expecting: %d ('%s'). This probaly means you called eo_*_super functions from a wrong place.",
|
ERR("Called with op %d ('%s') while expecting: %d ('%s'). This probaly means you called eo_*_super functions from a wrong place.",
|
||||||
op, _eo_op_id_name_get(op),
|
op, _eo_op_id_name_get(op),
|
||||||
node_op, _eo_op_id_name_get(node_op));
|
node_op, _eo_op_id_name_get(node_op));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Eo_Class **kls_itr = node->kls_itr;
|
const Eo_Class **kls_itr = obj->mro_itr.kls_itr;
|
||||||
if (*kls_itr)
|
if (*kls_itr)
|
||||||
{
|
{
|
||||||
kls_itr++;
|
kls_itr++;
|
||||||
node->kls_itr = kls_itr;
|
obj->mro_itr.kls_itr = kls_itr;
|
||||||
return *kls_itr;
|
return *kls_itr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -335,9 +314,7 @@ _eo_kls_itr_next(Eo *obj, Eo_Op op)
|
||||||
static inline Eina_Bool
|
static inline Eina_Bool
|
||||||
_eo_kls_itr_reached_end(const Eo *obj)
|
_eo_kls_itr_reached_end(const Eo *obj)
|
||||||
{
|
{
|
||||||
Eo_Kls_Itr_Node *node =
|
const Eo_Class **kls_itr = obj->mro_itr.kls_itr;
|
||||||
EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eo_Kls_Itr_Node);
|
|
||||||
const Eo_Class **kls_itr = node->kls_itr;
|
|
||||||
return !(*kls_itr && *(kls_itr + 1));
|
return !(*kls_itr && *(kls_itr + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +323,6 @@ _eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
|
||||||
{
|
{
|
||||||
const Eo_Class *klass;
|
const Eo_Class *klass;
|
||||||
Eina_Bool ret = EINA_FALSE;
|
Eina_Bool ret = EINA_FALSE;
|
||||||
Eina_Bool _itr_init;
|
|
||||||
|
|
||||||
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
|
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
|
||||||
|
|
||||||
|
@ -357,7 +333,8 @@ _eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_itr_init = _eo_kls_itr_init(obj, op);
|
Eo_Kls_Itr prev_state;
|
||||||
|
_eo_kls_itr_init(obj, op, &prev_state);
|
||||||
klass = _eo_kls_itr_get(obj);
|
klass = _eo_kls_itr_get(obj);
|
||||||
while (klass)
|
while (klass)
|
||||||
{
|
{
|
||||||
|
@ -388,8 +365,7 @@ _eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
_eo_kls_itr_end(obj, &prev_state);
|
||||||
if (_itr_init) _eo_kls_itr_end(obj, op);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,7 +899,9 @@ eo_add(const Eo_Class *klass, Eo *parent)
|
||||||
|
|
||||||
obj->refcount++;
|
obj->refcount++;
|
||||||
|
|
||||||
_eo_kls_itr_init(obj, EO_NOOP);
|
Eo_Kls_Itr prev_state;
|
||||||
|
|
||||||
|
_eo_kls_itr_init(obj, EO_NOOP, &prev_state);
|
||||||
eo_constructor_error_unset(obj);
|
eo_constructor_error_unset(obj);
|
||||||
|
|
||||||
EINA_MAGIC_SET(obj, EO_EINA_MAGIC);
|
EINA_MAGIC_SET(obj, EO_EINA_MAGIC);
|
||||||
|
@ -941,12 +919,13 @@ eo_add(const Eo_Class *klass, Eo *parent)
|
||||||
ERR("Type '%s' - Not all of the object constructors have been executed.", klass->desc->name);
|
ERR("Type '%s' - Not all of the object constructors have been executed.", klass->desc->name);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
_eo_kls_itr_end(obj, EO_NOOP);
|
_eo_kls_itr_end(obj, &prev_state);
|
||||||
eo_unref(obj);
|
eo_unref(obj);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
_eo_kls_itr_end(obj, &prev_state);
|
||||||
/* Unref twice, once for the ref above, and once for the basic object ref. */
|
/* Unref twice, once for the ref above, and once for the basic object ref. */
|
||||||
eo_unref(obj);
|
eo_unref(obj);
|
||||||
eo_unref(obj);
|
eo_unref(obj);
|
||||||
|
@ -1036,7 +1015,9 @@ _eo_del_internal(Eo *obj)
|
||||||
obj->refcount--;
|
obj->refcount--;
|
||||||
|
|
||||||
const Eo_Class *klass = eo_class_get(obj);
|
const Eo_Class *klass = eo_class_get(obj);
|
||||||
_eo_kls_itr_init(obj, EO_NOOP);
|
Eo_Kls_Itr prev_state;
|
||||||
|
|
||||||
|
_eo_kls_itr_init(obj, EO_NOOP, &prev_state);
|
||||||
eo_constructor_error_unset(obj);
|
eo_constructor_error_unset(obj);
|
||||||
_eo_destructor(obj, klass);
|
_eo_destructor(obj, klass);
|
||||||
if (eo_constructor_error_get(obj))
|
if (eo_constructor_error_get(obj))
|
||||||
|
@ -1048,18 +1029,9 @@ _eo_del_internal(Eo *obj)
|
||||||
{
|
{
|
||||||
ERR("Type '%s' - Not all of the object destructors have been executed.", klass->desc->name);
|
ERR("Type '%s' - Not all of the object destructors have been executed.", klass->desc->name);
|
||||||
}
|
}
|
||||||
_eo_kls_itr_end(obj, EO_NOOP);
|
_eo_kls_itr_end(obj, &prev_state);
|
||||||
/*FIXME: add eo_class_unref(klass) ? - just to clear the caches. */
|
/*FIXME: add eo_class_unref(klass) ? - just to clear the caches. */
|
||||||
|
|
||||||
/* If for some reason it's not empty, clear it. */
|
|
||||||
while (obj->kls_itr)
|
|
||||||
{
|
|
||||||
WRN("Kls_Itr is not empty, possibly a bug, please report. - An error will be reported for each kls_itr in the stack.");
|
|
||||||
Eina_Inlist *nitr = obj->kls_itr->next;
|
|
||||||
free(EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eo_Kls_Itr_Node));
|
|
||||||
obj->kls_itr = nitr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Eina_List *itr, *itr_n;
|
Eina_List *itr, *itr_n;
|
||||||
Eo *emb_obj;
|
Eo *emb_obj;
|
||||||
EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj)
|
EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj)
|
||||||
|
|
Loading…
Reference in New Issue