EAPI void
eo2_class_funcs_set(Eo_Class *klass_id);
-// opaque type used to pass object pointer to EAPI calls
-typedef struct _Eo_Internal _Eo;
-
// to fetch internal function and object data at once
typedef struct _Eo2_Op_Call_Data
{
- void *func;
- void *data;
+ Eo *obj_id;
+ void *func;
+ void *data;
} Eo2_Op_Call_Data;
-// EAPI function declaration first argument
-#define eo2_a _Eo *obj, Eo *objid
-// EAPI function call first argument
-#define eo2_o _obj_, _objid_
-
// to pass the internal function call to EO2_FUNC_BODY (as Func parameter)
-#define EO2_FUNC_CALL(...) _func_(objid, call.data, __VA_ARGS__)
+#define EO2_FUNC_CALL(...) _func_(call.obj_id, call.data, __VA_ARGS__)
// cache OP id, get real fct and object data then do the call
#define _EO2_FUNC_COMMON(Name, Ret, Func, DefRet) \
static Eo_Op op = EO_NOOP; \
- if ( op == EO_NOOP ) op = eo2_get_op_id(obj, (void*)Name); \
+ if ( op == EO_NOOP ) op = eo2_get_op_id((void*)Name); \
Eo2_Op_Call_Data call; \
- if (!eo2_call_resolve(obj, op, &call)) return DefRet; \
+ if (!eo2_call_resolve(op, &call)) return DefRet; \
__##Name##_func _func_ = (__##Name##_func) call.func; \
return Func; \
-/* XXX: Essential, because we need to adjust objid for comp objects. */
// to define an EAPI function
#define EO2_FUNC_BODY(Name, Ret, DefRet) \
Ret \
- Name(_Eo *obj, Eo *objid) \
+ Name() \
{ \
typedef Ret (*__##Name##_func)(Eo *, void *obj_data); \
- _EO2_FUNC_COMMON(Name, Ret, _func_(objid, call.data), DefRet) \
+ _EO2_FUNC_COMMON(Name, Ret, _func_(call.obj_id, call.data), DefRet)\
}
#define EO2_VOID_FUNC_BODY(Name) EO2_FUNC_BODY(Name, void, )
#define EO2_FUNC_BODYV(Name, Ret, Func, DefRet, ...) \
Ret \
- Name(_Eo *obj, Eo *objid, __VA_ARGS__) \
+ Name(__VA_ARGS__) \
{ \
typedef Ret (*__##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
_EO2_FUNC_COMMON(Name, Ret, Func, DefRet) \
#define EO2_OP_SENTINEL { NULL, NULL, 0, EO_OP_TYPE_INVALID, NULL}
// returns the OP id corresponding to the given api_func
-EAPI Eo_Op eo2_get_op_id(_Eo *obj, void *api_func);
+EAPI Eo_Op eo2_get_op_id(void *api_func);
// gets the real function pointer and the object data
-#define eo2_call_resolve(obj_id, op, call) eo2_call_resolve_internal(obj_id, NULL, op, call)
-EAPI Eina_Bool eo2_call_resolve_internal(_Eo *obj, const Eo_Class *klass, Eo_Op op, Eo2_Op_Call_Data *call);
-
-// start of eo2_do barrier, gets the object pointer and ref it
-EAPI _Eo * eo2_do_start(Eo *obj_id);
+#define eo2_call_resolve(op, call) eo2_call_resolve_internal(NULL, op, call)
+EAPI Eina_Bool eo2_call_resolve_internal(const Eo_Class *klass, Eo_Op op, Eo2_Op_Call_Data *call);
-// end of the eo2_do barrier, unref the obj
-EAPI void eo2_do_end(_Eo *obj);
+// start of eo2_do barrier, gets the object pointer and ref it, put it on the stask
+EAPI Eina_Bool eo2_do_start(Eo *obj_id);
-// optional helper
-#define eo2_call(api_func) api_func(eo2_o)
-#define eo2_callv(api_func, ...) api_func(eo2_o, __VA_ARGS__)
+// end of the eo2_do barrier, unref the obj, move the stack pointer
+EAPI void eo2_do_end();
// eo object method calls batch,
// DO NOT use return statement in it, use break if necessary
do \
{ \
Eo *_objid_ = objid; \
- _Eo *_obj_ = eo2_do_start(_objid_); \
- if (!_obj_) break; \
+ if (!eo2_do_start(_objid_)) break; \
do { __VA_ARGS__ ; } while (0); \
- eo2_do_end(_obj_); \
- _obj_ = NULL; \
+ eo2_do_end(); \
} while (0)
// FIXME
/************************************ EO2 ************************************/
-EAPI _Eo *
+// FIXME: per thread stack, grow/shrink
+#define EO2_INVALID_DATA (void *) -1
+#define EO2_CALL_STACK_SIZE 5
+typedef struct _Eo2_Stack_Frame
+{
+ Eo *obj_id;
+ _Eo *obj;
+ void *obj_data;
+
+} Eo2_Stack_Frame;
+
+typedef struct _Eo2_Call_Stack {
+ Eo2_Stack_Frame stack[EO2_CALL_STACK_SIZE];
+ Eo2_Stack_Frame *frame_ptr;
+} Eo2_Call_Stack;
+
+static Eo2_Call_Stack eo2_call_stack = {
+ {
+ { NULL, NULL, EO2_INVALID_DATA },
+ { NULL, NULL, EO2_INVALID_DATA },
+ { NULL, NULL, EO2_INVALID_DATA },
+ { NULL, NULL, EO2_INVALID_DATA },
+ { NULL, NULL, EO2_INVALID_DATA },
+ },
+ NULL };
+
+EAPI Eina_Bool
eo2_do_start(Eo *obj_id)
{
- EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
+ EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
_eo_ref(obj);
- return obj;
+
+ if (eo2_call_stack.frame_ptr == NULL)
+ eo2_call_stack.frame_ptr = &eo2_call_stack.stack[0];
+ else
+ eo2_call_stack.frame_ptr++;
+
+ if (eo2_call_stack.frame_ptr->obj_id != NULL)
+ ERR("eo2 call stack is not clear, you must have used a return statement in a eo2_do macro");
+
+ if ((eo2_call_stack.frame_ptr - eo2_call_stack.stack) >= EO2_CALL_STACK_SIZE)
+ ERR("eo2 call stack overflow !!!");
+
+ eo2_call_stack.frame_ptr->obj = obj;
+ eo2_call_stack.frame_ptr->obj_id = obj_id;
+ eo2_call_stack.frame_ptr->obj_data = EO2_INVALID_DATA;
+
+ return EINA_TRUE;
}
EAPI void
-eo2_do_end(_Eo *obj)
+eo2_do_end()
{
- _eo_unref(obj);
+ _eo_unref(eo2_call_stack.frame_ptr->obj);
+
+ eo2_call_stack.frame_ptr->obj = NULL;
+ eo2_call_stack.frame_ptr->obj_id = NULL;
+ eo2_call_stack.frame_ptr->obj_data = EO2_INVALID_DATA;
+
+ if (eo2_call_stack.frame_ptr == &eo2_call_stack.stack[0])
+ eo2_call_stack.frame_ptr = NULL;
+ else
+ eo2_call_stack.frame_ptr--;
}
EAPI Eina_Bool
-eo2_call_resolve_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op, Eo2_Op_Call_Data *call)
+eo2_call_resolve_internal(const Eo_Class *klass_id, Eo_Op op, Eo2_Op_Call_Data *call)
{
const _Eo_Class *klass;
const op_type_funcs *func;
+ const _Eo * obj = eo2_call_stack.frame_ptr->obj;
if (klass_id)
klass = _eo_class_pointer_get(klass_id);
func = _eo_kls_itr_func_get(klass, op);
if (EINA_LIKELY(func != NULL))
{
+ call->obj_id = eo2_call_stack.frame_ptr->obj_id;
call->func = func->func;
- call->data = _eo_data_scope_get(obj, func->src);
+
+ if (func->src == obj->klass)
+ {
+ if (eo2_call_stack.frame_ptr->obj_data == EO2_INVALID_DATA)
+ eo2_call_stack.frame_ptr->obj_data = _eo_data_scope_get(obj, func->src);
+
+ call->data = eo2_call_stack.frame_ptr->obj_data;
+ }
+ else
+ call->data = _eo_data_scope_get(obj, func->src);
+
return EINA_TRUE;
}
EAPI Eo_Op
-eo2_get_op_id(_Eo *obj, void *api_func)
+eo2_get_op_id(void *api_func)
{
int imin, imax, imid;
Eo2_Op_Description *op_desc;
Eo2_Op_Description *op_descs;
+ const _Eo * obj = eo2_call_stack.frame_ptr->obj;
imin = 0;
imax = obj->klass->desc->ops.count - 1;
/* #include "eo_private.h" */
EAPI void
-data_set(eo2_a, const char *key, const void *data, eo_base_data_free_func free_func);
+data_set(const char *key, const void *data, eo_base_data_free_func free_func);
EAPI void
-data_get(eo2_a, const char *key);
+data_get(const char *key);
EAPI void
-data_del(eo2_a, const char *key);
+data_del(const char *key);
EAPI void
-wref_add(eo2_a, Eo **wref);
+wref_add(Eo **wref);
EAPI void
-wref_del(eo2_a, Eo **wref);
+wref_del(Eo **wref);
EAPI void
-ev_cb_priority_add(eo2_a, const Eo_Event_Description *desc,
+ev_cb_priority_add(const Eo_Event_Description *desc,
Eo_Callback_Priority priority, Eo_Event_Cb func,
const void *user_data);
EAPI void
-ev_cb_del(eo2_a, const Eo_Event_Description *desc, Eo_Event_Cb func,
+ev_cb_del(const Eo_Event_Description *desc, Eo_Event_Cb func,
const void *user_data);
EAPI void
-ev_cb_array_priority_add(eo2_a, const Eo_Callback_Array_Item *array,
+ev_cb_array_priority_add(const Eo_Callback_Array_Item *array,
Eo_Callback_Priority priority, const void *user_data);
EAPI void
-ev_cb_array_del(eo2_a, const Eo_Callback_Array_Item *array,
+ev_cb_array_del(const Eo_Callback_Array_Item *array,
const void *user_data);
EAPI Eina_Bool
-ev_cb_call(eo2_a, const Eo_Event_Description *desc, void *event_info);
+ev_cb_call(const Eo_Event_Description *desc, void *event_info);
EAPI void
-ev_cb_forwarder_add(eo2_a, const Eo_Event_Description *desc, Eo *new_obj);
+ev_cb_forwarder_add(const Eo_Event_Description *desc, Eo *new_obj);
EAPI void
-ev_cb_forwarder_del(eo2_a, const Eo_Event_Description *desc, Eo *new_obj);
+ev_cb_forwarder_del(const Eo_Event_Description *desc, Eo *new_obj);
EAPI void
-ev_freeze(eo2_a);
+ev_freeze();
EAPI void
-ev_thaw(eo2_a);
+ev_thaw();
EAPI int
-ev_freeze_get(eo2_a);
+ev_freeze_get();
EAPI void
-ev_global_freeze(eo2_a);
+ev_global_freeze();
EAPI void
-ev_global_thaw(eo2_a);
+ev_global_thaw();
EAPI int
-ev_global_freeze_get(eo2_a);
+ev_global_freeze_get();
EAPI void
-dbg_info_get(eo2_a);
+dbg_info_get();
EAPI void
eo2_dbg_info_free(Eo_Dbg_Info *info);
typedef struct _Eo_Class _Eo_Class;
typedef struct _Eo_Object _Eo_Object;
typedef struct _Eo_Base Eo_Base;
+typedef struct _Eo_Internal _Eo;
/* Retrieves the pointer to the object from the id */
static inline _Eo_Object *_eo_obj_pointer_get(const Eo_Id obj_id);