From f05f51dd60abf37fed81ef7fc467e167b0fdc34e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Wed, 25 Dec 2013 15:04:26 +0100 Subject: [PATCH] eo2: _Eo_Class_Description swallows op_descs remove OpDescs argument from macros, eo2_get_op_id() uses binary search --- src/lib/eo/Eo.h | 20 +++++++++----------- src/lib/eo/eo.c | 38 ++++++++++++++++++++++++++++---------- src/lib/eo/eo_base_class.c | 1 + 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 8391802..afa10bf 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -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) diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 0412d3c..8a69b2a 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -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++; } diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index c83b19b..b5a5edd 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -1007,6 +1007,7 @@ static const Eo_Class_Description class_desc = { event_desc, sizeof(Private_Data), _class_constructor, + NULL, NULL }; -- 2.7.4