eo2: _Eo_Class_Description swallows op_descs

remove OpDescs argument from macros,
eo2_get_op_id() uses binary search
This commit is contained in:
Jérémy Zurcher 2013-12-25 15:04:26 +01:00 committed by Tom Hacohen
parent 41aff7524d
commit f05f51dd60
3 changed files with 38 additions and 21 deletions

View File

@ -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)

View File

@ -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++;
}

View File

@ -1007,6 +1007,7 @@ static const Eo_Class_Description class_desc = {
event_desc,
sizeof(Private_Data),
_class_constructor,
NULL,
NULL
};