const Eobj_Class **kls_itr;
} Eobj_Kls_Itr_Node;
-static inline void
+static inline Eina_Bool
_eobj_kls_itr_init(Eobj *obj, Eobj_Op op)
{
- if (obj->kls_itr &&
- EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eobj_Kls_Itr_Node))
+ if (obj->kls_itr)
{
- /* Nothing ATM. */
+ Eobj_Kls_Itr_Node *node =
+ EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eobj_Kls_Itr_Node);
+ if (node->op == op)
+ {
+ return EINA_FALSE;
+ }
}
- else
+
+
{
Eobj_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 const Eobj_Class *
+_eobj_kls_itr_get(Eobj *obj)
+{
+ Eobj_Kls_Itr_Node *node =
+ EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eobj_Kls_Itr_Node);
+
+ return (node) ? *(node->kls_itr) : NULL;
+}
+
+static inline const Eobj_Class *
_eobj_kls_itr_next(Eobj *obj)
{
Eobj_Kls_Itr_Node *node =
}
static Eina_Bool
-_eobj_op_internal(Eobj *obj, const Eobj_Class *obj_klass, Eobj_Op op, va_list *p_list, Eina_Bool recursive)
+_eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
{
- const Eobj_Class *klass = obj_klass;
- eobj_op_func_type func;
-
- if (!obj_klass)
- return EINA_FALSE;
+ const Eobj_Class *klass;
+ Eina_Bool ret = EINA_FALSE;
+ Eina_Bool _itr_init;
+ _itr_init = _eobj_kls_itr_init(obj, op);
+ klass = _eobj_kls_itr_get(obj);
while (klass)
{
- func = dich_func_get(klass, op);
+ eobj_op_func_type func = dich_func_get(klass, op);
if (func)
{
func(obj, op, p_list);
- return EINA_TRUE;
- }
- else
- {
- klass = klass->parent;
+ ret = EINA_TRUE;
+ goto end;
}
- }
- if (!recursive)
- return EINA_FALSE;
+ klass = _eobj_kls_itr_next(obj);
+ }
- if (!klass)
+ /* Try composite objects */
{
- klass = obj_klass;
- /* FIXME: Should probably flatten everything. to be faster. */
- {
- /* Try MIXINS */
- Eobj_Extension_Node *itr;
- EINA_INLIST_FOREACH(klass->extensions, itr)
- {
- if (_eobj_op_internal(obj, itr->klass, op, p_list, recursive))
- {
- return EINA_TRUE;
- }
- }
- }
-
- /* Try composite objects */
+ Eina_List *itr;
+ Eobj *emb_obj;
+ EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
{
- Eina_List *itr;
- Eobj *emb_obj;
- EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
+ if (_eobj_op_internal(emb_obj, op, p_list))
{
- if (_eobj_op_internal(emb_obj, eobj_class_get(emb_obj), op, p_list, recursive))
- {
- return EINA_TRUE;
- }
+ ret = EINA_TRUE;
+ goto end;
}
}
-
- /* If haven't found anything, return FALSE */
- return EINA_FALSE;
}
- return EINA_TRUE;
+end:
+
+ if (_itr_init) _eobj_kls_itr_end(obj, op);
+ return ret;
}
static inline Eina_Bool
-_eobj_ops_internal(Eobj *obj, const Eobj_Class *obj_klass, va_list *p_list)
+_eobj_ops_internal(Eobj *obj, va_list *p_list)
{
Eina_Bool ret = EINA_TRUE;
Eobj_Op op = 0;
op = va_arg(*p_list, Eobj_Op);
while (op)
{
- if (!_eobj_op_internal(obj, obj_klass, op, p_list, EINA_TRUE))
+ if (!_eobj_op_internal(obj, op, p_list))
{
const Eobj_Op_Description *desc = _eobj_op_id_desc_get(op);
const char *_id_name = (desc) ? desc->name : NULL;
const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
ERR("Can't find func for op %x ('%s' of domain '%s') for class '%s'. Aborting.",
op, _id_name, _dom_name,
- obj_klass->desc->name);
+ obj->klass->desc->name);
ret = EINA_FALSE;
break;
}
Eina_Bool ret;
va_list p_list;
va_start(p_list, obj);
- ret = _eobj_ops_internal(obj, eobj_class_get(obj), &p_list);
+ ret = _eobj_ops_internal(obj, &p_list);
va_end(p_list);
return ret;
}
EAPI Eina_Bool
eobj_super_do(Eobj *obj, Eobj_Op op, ...)
{
- const Eobj_Class *obj_klass = _eobj_kls_itr_next(obj);
- if (!obj_klass) return EINA_TRUE;
-
+ const Eobj_Class *obj_klass;
Eina_Bool ret = EINA_TRUE;
va_list p_list;
+
va_start(p_list, op);
- _eobj_kls_itr_init(obj, op);
- if (!_eobj_op_internal(obj, obj_klass, op, &p_list, EINA_FALSE))
+
+ /* Advance the kls itr. */
+ obj_klass = _eobj_kls_itr_next(obj);
+ if (!_eobj_op_internal(obj, op, &p_list))
{
const Eobj_Op_Description *desc = _eobj_op_id_desc_get(op);
const char *_id_name = (desc) ? desc->name : NULL;
const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
ERR("Can't find func for op %x ('%s' of domain '%s') for class '%s'. Aborting.",
op, _id_name, _dom_name,
- obj_klass->desc->name);
+ (obj_klass) ? obj_klass->desc->name : NULL);
ret = EINA_FALSE;
}
- _eobj_kls_itr_end(obj, op);
va_end(p_list);
+
return ret;
}
return obj->klass;
}
-EAPI const Eobj_Class *
-eobj_class_parent_get(const Eobj_Class *klass)
-{
- return klass->parent;
-}
-
EAPI const char *
eobj_class_name_get(const Eobj_Class *klass)
{
klass = calloc(1, sizeof(Eobj_Class));
klass->parent = parent;
- klass->class_id = ++_eobj_classes_last_id;
- {
- /* FIXME: Handle errors. */
- Eobj_Class **tmp;
- tmp = realloc(_eobj_classes, _eobj_classes_last_id * sizeof(*_eobj_classes));
- _eobj_classes = tmp;
- _eobj_classes[klass->class_id - 1] = klass;
- }
/* Handle class extensions */
{
klass->desc = desc;
- /* If we have a class parent, update the current offset. */
+ /* Handle the inheritance */
if (klass->parent)
{
+ /* Verify the inheritance is allowed. */
+ switch (klass->desc->type)
+ {
+ case EOBJ_CLASS_TYPE_REGULAR:
+ case EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT:
+ if ((klass->parent->desc->type != EOBJ_CLASS_TYPE_REGULAR) &&
+ (klass->parent->desc->type != EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT))
+ {
+ /* FIXME: Actually handle it. */
+ ERR("Regular classes ('%s') aren't allowed to inherit from non-regular classes ('%s').", klass->desc->name, klass->parent->desc->name);
+ goto cleanup;
+ }
+ break;
+ case EOBJ_CLASS_TYPE_INTERFACE:
+ case EOBJ_CLASS_TYPE_MIXIN:
+ if ((klass->parent->desc->type != EOBJ_CLASS_TYPE_REGULAR) &&
+ (klass->parent->desc->type != EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT))
+ {
+ /* FIXME: Actually handle it. */
+ ERR("Non-regular classes ('%s') aren't allowed to inherit from regular classes ('%s').", klass->desc->name, klass->parent->desc->name);
+ goto cleanup;
+ }
+ break;
+ }
+
+
+ /* Update the current offset. */
/* FIXME: Make sure this alignment is enough. */
klass->data_offset = klass->parent->data_offset +
klass->parent->desc->private_size +
(klass->parent->desc->private_size % sizeof(void *)));
}
+ klass->class_id = ++_eobj_classes_last_id;
+ {
+ /* FIXME: Handle errors. */
+ Eobj_Class **tmp;
+ tmp = realloc(_eobj_classes, _eobj_classes_last_id * sizeof(*_eobj_classes));
+ _eobj_classes = tmp;
+ _eobj_classes[klass->class_id - 1] = klass;
+ }
+
_eobj_class_base_op_init(klass);
/* FIXME: Shouldn't be called here - should be called from eobj_add. */
va_end(p_list);
return klass;
+
+cleanup:
+ eobj_class_free(klass);
+ return NULL;
}
#undef _CLS_NEW_CHECK
Eobj *obj = eobj_parent_get(emb_obj);
Eina_List *itr;
Eobj *tmp;
+
+ if (!obj)
+ return EINA_FALSE;
+
EINA_LIST_FOREACH(obj->composite_objects, itr, tmp)
{
if (tmp == emb_obj)
cb->delete_me = EINA_TRUE;
_eobj_callbacks_clear(obj);
ret = data;
- goto end;
+ goto found;
}
}
-end:
+ return NULL;
+
+found:
eobj_event_callback_call(obj, EOBJ_SIG_CALLBACK_DEL, desc);
return ret;
}
cb->delete_me = EINA_TRUE;
_eobj_callbacks_clear(obj);
ret = data;
- goto end;
+ goto found;
}
}
-end:
+ return NULL;
+
+found:
eobj_event_callback_call(obj, EOBJ_SIG_CALLBACK_DEL, desc);
return ret;
}