forked from enlightenment/efl
eo2: _Eo_Class_Description swallows op_descs
remove OpDescs argument from macros, eo2_get_op_id() uses binary search
This commit is contained in:
parent
41aff7524d
commit
f05f51dd60
|
@ -477,6 +477,7 @@ struct _Eo_Class_Description
|
|||
size_t data_size; /**< The size of data (private + protected + public) this class needs per object. */
|
||||
void (*class_constructor)(Eo_Class *klass); /**< The constructor of the class. */
|
||||
void (*class_destructor)(Eo_Class *klass); /**< The destructor of the class. */
|
||||
Eo2_Op_Description *op_descs; /**< should replace ops.descs */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -603,12 +604,9 @@ EAPI Eina_Bool eo_shutdown(void);
|
|||
|
||||
/************************************ EO2 ************************************/
|
||||
|
||||
// computes size of Eo2_Op_Description[]
|
||||
#define OP_DESC_SIZE(desc) (sizeof(desc)/sizeof(Eo2_Op_Description) -1 )
|
||||
|
||||
// sort Eo2_Op_Description[] by eapi_func then attribute OP ids
|
||||
EAPI void
|
||||
eo2_class_funcs_set(Eo_Class *klass_id, Eo2_Op_Description *op_descs, int n);
|
||||
eo2_class_funcs_set(Eo_Class *klass_id);
|
||||
|
||||
// opaque type used to pass object pointer to EAPI calls
|
||||
typedef struct _Eo_Internal _Eo;
|
||||
|
@ -630,9 +628,9 @@ typedef struct _Eo2_Op_Call_Data
|
|||
#define EO_FUNC_CALLV(...) func(objid, call.data, __VA_ARGS__)
|
||||
|
||||
// cache OP id, get real fct and object data then do the call
|
||||
#define _EO_FUNC_COMMON(Name, Ret, Func, DefRet, OpDescs) \
|
||||
#define _EO_FUNC_COMMON(Name, Ret, Func, DefRet) \
|
||||
static Eo_Op op = EO_NOOP; \
|
||||
if ( op == EO_NOOP ) op = eo2_get_op_id(OpDescs, (void*)Name); \
|
||||
if ( op == EO_NOOP ) op = eo2_get_op_id(obj, (void*)Name); \
|
||||
Eo2_Op_Call_Data call; \
|
||||
if (!eo2_call_resolve(obj, op, &call)) return DefRet; \
|
||||
__##Name##_func func = (__##Name##_func) call.func; \
|
||||
|
@ -640,24 +638,24 @@ typedef struct _Eo2_Op_Call_Data
|
|||
|
||||
/* XXX: Essential, because we need to adjust objid for comp objects. */
|
||||
// to define an EAPI function
|
||||
#define EO_FUNC_BODY(Name, Ret, Func, DefRet, OpDescs) \
|
||||
#define EO_FUNC_BODY(Name, Ret, Func, DefRet) \
|
||||
Ret \
|
||||
Name(_Eo *obj, Eo *objid) \
|
||||
{ \
|
||||
typedef Ret (*__##Name##_func)(Eo *, void *obj_data); \
|
||||
_EO_FUNC_COMMON(Name, Ret, Func, DefRet, OpDescs) \
|
||||
_EO_FUNC_COMMON(Name, Ret, Func, DefRet) \
|
||||
}
|
||||
|
||||
#define EO_FUNC_BODYV(Name, Ret, Func, DefRet, OpDescs, ...) \
|
||||
#define EO_FUNC_BODYV(Name, Ret, Func, DefRet, ...) \
|
||||
Ret \
|
||||
Name(_Eo *obj, Eo *objid, __VA_ARGS__) \
|
||||
{ \
|
||||
typedef Ret (*__##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
|
||||
_EO_FUNC_COMMON(Name, Ret, Func, DefRet, OpDescs) \
|
||||
_EO_FUNC_COMMON(Name, Ret, Func, DefRet) \
|
||||
}
|
||||
|
||||
// returns the OP id corresponding to the given api_func
|
||||
EAPI Eo_Op eo2_get_op_id(Eo2_Op_Description *op_descs, void *api_func);
|
||||
EAPI Eo_Op eo2_get_op_id(_Eo *obj, 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)
|
||||
|
|
|
@ -297,14 +297,26 @@ eo2_call_resolve_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op, Eo2_Op_C
|
|||
|
||||
|
||||
EAPI Eo_Op
|
||||
eo2_get_op_id(Eo2_Op_Description *op_descs, void *api_func)
|
||||
eo2_get_op_id(_Eo *obj, void *api_func)
|
||||
{
|
||||
int imin, imax, imid;
|
||||
Eo2_Op_Description *op_desc;
|
||||
Eo2_Op_Description *op_descs;
|
||||
|
||||
/* do a binary search, when it's swallowed by _Eo_Class_Description */
|
||||
for (op_desc = op_descs; op_desc->op != EO_NOOP; op_desc++)
|
||||
imin = 0;
|
||||
imax = obj->klass->desc->ops.count - 1;
|
||||
op_descs = obj->klass->desc->op_descs;
|
||||
|
||||
while (imax >= imin)
|
||||
{
|
||||
if (op_desc->api_func == api_func)
|
||||
imid = (imax + imin) / 2;
|
||||
op_desc = op_descs + imid;
|
||||
|
||||
if (op_desc->api_func > api_func)
|
||||
imin = imid + 1;
|
||||
else if (op_desc->api_func < api_func)
|
||||
imax = imid - 1;
|
||||
else
|
||||
return op_desc->op;
|
||||
}
|
||||
|
||||
|
@ -323,9 +335,9 @@ eo2_api_funcs_cmp(const void *p1, const void *p2)
|
|||
}
|
||||
|
||||
EAPI void
|
||||
eo2_class_funcs_set(Eo_Class *klass_id, Eo2_Op_Description *op_descs, int n)
|
||||
eo2_class_funcs_set(Eo_Class *klass_id)
|
||||
{
|
||||
int i, base_op_id;
|
||||
int i, base_op_id, n;
|
||||
_Eo_Class *klass;
|
||||
Eo2_Op_Description *op_desc;
|
||||
|
||||
|
@ -334,15 +346,21 @@ eo2_class_funcs_set(Eo_Class *klass_id, Eo2_Op_Description *op_descs, int n)
|
|||
|
||||
base_op_id = *klass->desc->ops.base_op_id;
|
||||
|
||||
/* to speed up eo2_get_op_id */
|
||||
qsort((void*)op_descs, n, sizeof(Eo2_Op_Description), eo2_api_funcs_cmp);
|
||||
// klass->desc->ops.count only counts class OP, not _constructor or _destructor
|
||||
for (op_desc = klass->desc->op_descs; op_desc->op_type != EO_OP_TYPE_INVALID; op_desc++);
|
||||
n = op_desc - klass->desc->op_descs;
|
||||
|
||||
qsort((void*)klass->desc->op_descs, n, sizeof(Eo2_Op_Description), eo2_api_funcs_cmp);
|
||||
|
||||
i = 0;
|
||||
for (op_desc = op_descs; op_desc->op_type != EO_OP_TYPE_INVALID; op_desc++)
|
||||
for (op_desc = klass->desc->op_descs; op_desc->op_type != EO_OP_TYPE_INVALID; op_desc++)
|
||||
{
|
||||
// take care of overriding, maybe ok ??
|
||||
if (op_desc->op == EO_NOOP)
|
||||
{
|
||||
if(op_desc->api_func == NULL)
|
||||
ERR("Setting implementation for NULL EAPI for class '%s'. Func index: %lu",
|
||||
klass->desc->name, (unsigned long) (op_desc - klass->desc->op_descs));
|
||||
|
||||
op_desc->op = base_op_id + i;
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -1007,6 +1007,7 @@ static const Eo_Class_Description class_desc = {
|
|||
event_desc,
|
||||
sizeof(Private_Data),
|
||||
_class_constructor,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue