forked from enlightenment/efl
Eo: Added support for class functions.
SVN revision: 71119
This commit is contained in:
parent
90804082c0
commit
2cf5e56694
|
@ -37,6 +37,15 @@ _print2(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UN
|
|||
printf("Hey2\n");
|
||||
}
|
||||
|
||||
static void
|
||||
_class_print(const Eo_Class *klass, va_list *list)
|
||||
{
|
||||
(void) list;
|
||||
printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
|
||||
fail_if(!eo_class_do_super(klass, simple_class_print()));
|
||||
fail_if(eo_class_do_super(klass, simple_class_print2()));
|
||||
}
|
||||
|
||||
static void
|
||||
_class_constructor(Eo_Class *klass)
|
||||
{
|
||||
|
@ -44,6 +53,7 @@ _class_constructor(Eo_Class *klass)
|
|||
EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
|
||||
EO_OP_FUNC(INHERIT2_ID(INHERIT2_SUB_ID_PRINT), _print),
|
||||
EO_OP_FUNC(INHERIT2_ID(INHERIT2_SUB_ID_PRINT2), _print2),
|
||||
EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT), _class_print),
|
||||
EO_OP_FUNC_SENTINEL
|
||||
};
|
||||
|
||||
|
|
|
@ -38,6 +38,15 @@ main(int argc, char *argv[])
|
|||
|
||||
fail_if(eo_do_super(obj, simple_a_print()));
|
||||
|
||||
fail_if(eo_do(obj, simple_class_print()));
|
||||
|
||||
fail_if(!eo_class_do(SIMPLE_CLASS, simple_class_print()));
|
||||
fail_if(!eo_class_do(INHERIT_CLASS, simple_class_print()));
|
||||
fail_if(!eo_class_do(INHERIT2_CLASS, simple_class_print()));
|
||||
fail_if(!eo_class_do(INHERIT3_CLASS, simple_class_print()));
|
||||
|
||||
fail_if(eo_class_do(SIMPLE_CLASS, simple_a_print()));
|
||||
|
||||
eo_constructor_super(obj);
|
||||
eo_destructor_super(obj);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "simple.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "../eunit_tests.h"
|
||||
|
||||
EAPI Eo_Op SIMPLE_BASE_ID = 0;
|
||||
|
||||
|
@ -25,12 +26,30 @@ _a_print(const Eo *obj EINA_UNUSED, const void *class_data, va_list *list)
|
|||
printf("Print %s %d\n", eo_class_name_get(MY_CLASS), pd->a);
|
||||
}
|
||||
|
||||
static void
|
||||
_class_print(const Eo_Class *klass, va_list *list)
|
||||
{
|
||||
(void) list;
|
||||
printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
|
||||
fail_if(eo_class_do_super(klass, simple_class_print()));
|
||||
fail_if(eo_class_do_super(klass, simple_class_print2()));
|
||||
}
|
||||
|
||||
static void
|
||||
_class_print2(const Eo_Class *klass, va_list *list)
|
||||
{
|
||||
(void) list;
|
||||
printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
|
||||
}
|
||||
|
||||
static void
|
||||
_class_constructor(Eo_Class *klass)
|
||||
{
|
||||
const Eo_Op_Func_Description func_desc[] = {
|
||||
EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
|
||||
EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
|
||||
EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT), _class_print),
|
||||
EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT2), _class_print2),
|
||||
EO_OP_FUNC_SENTINEL
|
||||
};
|
||||
|
||||
|
@ -40,6 +59,8 @@ _class_constructor(Eo_Class *klass)
|
|||
static const Eo_Op_Description op_desc[] = {
|
||||
EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
|
||||
EO_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
|
||||
EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_PRINT, "", "Print class name."),
|
||||
EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_PRINT2, "", "Print2 class name."),
|
||||
EO_OP_DESCRIPTION_SENTINEL
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ extern EAPI Eo_Op SIMPLE_BASE_ID;
|
|||
enum {
|
||||
SIMPLE_SUB_ID_A_SET,
|
||||
SIMPLE_SUB_ID_A_PRINT,
|
||||
SIMPLE_SUB_ID_CLASS_PRINT,
|
||||
SIMPLE_SUB_ID_CLASS_PRINT2,
|
||||
SIMPLE_SUB_ID_LAST
|
||||
};
|
||||
|
||||
|
@ -20,6 +22,8 @@ typedef struct
|
|||
|
||||
#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
|
||||
#define simple_a_print() SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT)
|
||||
#define simple_class_print() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT)
|
||||
#define simple_class_print2() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT2)
|
||||
|
||||
extern const Eo_Event_Description _SIG_A_CHANGED;
|
||||
#define SIG_A_CHANGED (&(_SIG_A_CHANGED))
|
||||
|
|
|
@ -41,6 +41,24 @@
|
|||
*/
|
||||
EAPI extern Eina_Lock _eo_class_creation_lock;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* An enum representing the possible types of an Op.
|
||||
*/
|
||||
enum _Eo_Op_Type
|
||||
{
|
||||
EO_OP_TYPE_REGULAR = 0, /**< Regular op. */
|
||||
EO_OP_TYPE_CONST, /**< Const op - object should not change. */
|
||||
EO_OP_TYPE_CLASS, /**< Class op - a class op. Like static in Java/C++. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @typedef Eo_Op_Type
|
||||
* A convenience typedef for #_Eo_Op_Type.
|
||||
*/
|
||||
typedef enum _Eo_Op_Type Eo_Op_Type;
|
||||
|
||||
/**
|
||||
* @defgroup Eo Eo Generic Object System
|
||||
*
|
||||
|
@ -75,6 +93,13 @@ typedef struct _Eo Eo;
|
|||
*/
|
||||
typedef unsigned int Eo_Op;
|
||||
|
||||
/**
|
||||
* @typedef Eo_Class
|
||||
* The basic Object class type.
|
||||
* @ingroup Eo_Class
|
||||
*/
|
||||
typedef struct _Eo_Class Eo_Class;
|
||||
|
||||
/**
|
||||
* @def EO_NOOP
|
||||
* A special #Eo_Op meaning "No operation".
|
||||
|
@ -100,6 +125,16 @@ typedef void (*eo_op_func_type)(Eo *, void *class_data, va_list *list);
|
|||
*/
|
||||
typedef void (*eo_op_func_type_const)(const Eo *, const void *class_data, va_list *list);
|
||||
|
||||
/**
|
||||
* @typedef eo_op_func_type_class
|
||||
* The type of the class Op functions. This is the same as #eo_op_func_type,\
|
||||
* exepct that it's for usage with class functions, and not with object
|
||||
* functions.
|
||||
*
|
||||
* @see eo_op_func_type
|
||||
*/
|
||||
typedef void (*eo_op_func_type_class)(const Eo_Class *, va_list *list);
|
||||
|
||||
/**
|
||||
* @addtogroup Eo_Events Eo's Event Handling
|
||||
* @{
|
||||
|
@ -141,12 +176,6 @@ typedef struct _Eo_Event_Description Eo_Event_Description;
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Eo_Class
|
||||
* The basic Object class type.
|
||||
*/
|
||||
typedef struct _Eo_Class Eo_Class;
|
||||
|
||||
/**
|
||||
* @def EO_DEFINE_CLASS(class_get_func_name, class_desc, parent_class, ...)
|
||||
* A convenience macro to be used for creating the class_get function. This
|
||||
|
@ -218,7 +247,7 @@ struct _Eo_Op_Func_Description
|
|||
{
|
||||
Eo_Op op; /**< The op */
|
||||
eo_op_func_type func; /**< The function to call for the op. */
|
||||
Eina_Bool constant; /**< @c EINA_TRUE if this function is a const. */
|
||||
Eo_Op_Type op_type; /**< The type of the op */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -234,7 +263,7 @@ typedef struct _Eo_Op_Func_Description Eo_Op_Func_Description;
|
|||
*
|
||||
* @see EO_OP_FUNC_CONST
|
||||
*/
|
||||
#define EO_OP_FUNC(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EINA_FALSE }
|
||||
#define EO_OP_FUNC(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EO_OP_TYPE_REGULAR }
|
||||
|
||||
/**
|
||||
* @def EO_OP_FUNC_CONST(op, func)
|
||||
|
@ -244,7 +273,17 @@ typedef struct _Eo_Op_Func_Description Eo_Op_Func_Description;
|
|||
*
|
||||
* @see EO_OP_FUNC
|
||||
*/
|
||||
#define EO_OP_FUNC_CONST(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_const, func), EINA_TRUE }
|
||||
#define EO_OP_FUNC_CONST(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_const, func), EO_OP_TYPE_CONST }
|
||||
|
||||
/**
|
||||
* @def EO_OP_FUNC_CLASS(op, func)
|
||||
* A convenience macro to be used when populating the #Eo_Op_Func_Description
|
||||
* array.
|
||||
* The same as #EO_OP_FUNC but for class functions.
|
||||
*
|
||||
* @see EO_OP_FUNC
|
||||
*/
|
||||
#define EO_OP_FUNC_CLASS(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_class, func), EO_OP_TYPE_CLASS }
|
||||
|
||||
/**
|
||||
* @def EO_OP_FUNC_SENTINEL
|
||||
|
@ -263,7 +302,7 @@ struct _Eo_Op_Description
|
|||
const char *name; /**< The name of the op. */
|
||||
const char *type; /**< descripbes the Op's function signature. */
|
||||
const char *doc; /**< Explanation about the Op. */
|
||||
Eina_Bool constant; /**< @c EINA_TRUE if this op's implementation should not change the obj. */
|
||||
Eo_Op_Type op_type; /**< The type of the Op. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -317,10 +356,11 @@ typedef struct _Eo_Class_Description Eo_Class_Description;
|
|||
* @param type The type string for the op.
|
||||
* @param doc Additional doc for the op.
|
||||
* @see Eo_Op_Description
|
||||
* @see EO_OP_DESCRIPTION_CLASS
|
||||
* @see EO_OP_DESCRIPTION_CONST
|
||||
* @see EO_OP_DESCRIPTION_SENTINEL
|
||||
*/
|
||||
#define EO_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_FALSE }
|
||||
#define EO_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EO_OP_TYPE_REGULAR }
|
||||
|
||||
/**
|
||||
* @def EO_OP_DESCRIPTION_CONST(op, type, doc)
|
||||
|
@ -334,7 +374,21 @@ typedef struct _Eo_Class_Description Eo_Class_Description;
|
|||
* @see EO_OP_DESCRIPTION
|
||||
* @see EO_OP_DESCRIPTION_SENTINEL
|
||||
*/
|
||||
#define EO_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_TRUE }
|
||||
#define EO_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EO_OP_TYPE_CONST }
|
||||
|
||||
/**
|
||||
* @def EO_OP_DESCRIPTION_CLASS(op, type, doc)
|
||||
* An helper macro to help populating #Eo_Op_Description
|
||||
* This macro is the same as EO_OP_DESCRIPTION but indicates that the op's
|
||||
* implementation is of type CLASS.
|
||||
* @param sub_id The sub id of the op being described.
|
||||
* @param type The type string for the op.
|
||||
* @param doc Additional doc for the op.
|
||||
* @see Eo_Op_Description
|
||||
* @see EO_OP_DESCRIPTION
|
||||
* @see EO_OP_DESCRIPTION_SENTINEL
|
||||
*/
|
||||
#define EO_OP_DESCRIPTION_CLASS(sub_id, type, doc) { sub_id, #sub_id, type, doc, EO_OP_TYPE_CLASS }
|
||||
|
||||
/**
|
||||
* @def EO_OP_DESCRIPTION_SENTINEL
|
||||
|
@ -412,9 +466,16 @@ EAPI Eina_Bool eo_shutdown(void);
|
|||
#define eo_query(obj, ...) eo_do_internal((Eo *) EO_TYPECHECK(const Eo *, obj), EINA_TRUE, __VA_ARGS__, EO_NOOP)
|
||||
|
||||
/**
|
||||
* @brief Issues ops on an object.
|
||||
* @def eo_class_do
|
||||
* A convenience wrapper around eo_class_do_internal()
|
||||
* @see eo_class_do_internal
|
||||
*/
|
||||
#define eo_class_do(klass, ...) eo_class_do_internal(klass, __VA_ARGS__, EO_NOOP)
|
||||
|
||||
/**
|
||||
* @brief Calls op functions of an object
|
||||
* @param obj The object to work on
|
||||
* @param constant @c EINA_TRUE if this call is on a constant object.
|
||||
* @param op_type The type of the ops that are passed.
|
||||
* @param ... NULL terminated list of OPs and parameters.
|
||||
* @return @c EINA_TRUE on success.
|
||||
*
|
||||
|
@ -423,7 +484,20 @@ EAPI Eina_Bool eo_shutdown(void);
|
|||
*
|
||||
* @see #eo_do
|
||||
*/
|
||||
EAPI Eina_Bool eo_do_internal(Eo *obj, Eina_Bool constant, ...);
|
||||
EAPI Eina_Bool eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...);
|
||||
|
||||
/**
|
||||
* @brief Calls op functions of a class.
|
||||
* @param klass The class to work on
|
||||
* @param ... NULL terminated list of OPs and parameters.
|
||||
* @return @c EINA_TRUE on success.
|
||||
*
|
||||
* Use the helper macros, don't pass the parameters manually.
|
||||
* Use #eo_do instead of this function.
|
||||
*
|
||||
* @see #eo_class_do
|
||||
*/
|
||||
EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
|
||||
|
||||
/**
|
||||
* @brief Calls the super function for the specific op.
|
||||
|
@ -455,10 +529,22 @@ EAPI Eina_Bool eo_do_internal(Eo *obj, Eina_Bool constant, ...);
|
|||
*/
|
||||
#define eo_do_super(obj, ...) eo_do_super_internal(obj, EINA_FALSE, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Calls the super function for the specific op.
|
||||
* @param klass The klass to work on
|
||||
* @param ... list of parameters.
|
||||
* @return @c EINA_TRUE on success.
|
||||
*
|
||||
* Unlike eo_class_do(), this function only accepts one op.
|
||||
*
|
||||
* @see #eo_class_do
|
||||
*/
|
||||
#define eo_class_do_super(klass, ...) eo_class_do_super_internal(klass, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Calls the super function for the specific op.
|
||||
* @param obj The object to work on
|
||||
* @param constant @c EINA_TRUE if this call is on a constant object.
|
||||
* @param op_type The type of the ops that are passed.
|
||||
* @param op The wanted op.
|
||||
* @param ... list of parameters.
|
||||
* @return @c EINA_TRUE on success.
|
||||
|
@ -469,7 +555,21 @@ EAPI Eina_Bool eo_do_internal(Eo *obj, Eina_Bool constant, ...);
|
|||
* @see #eo_do_super
|
||||
* @see #eo_query_super
|
||||
*/
|
||||
EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eina_Bool constant, Eo_Op op, ...);
|
||||
EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...);
|
||||
|
||||
/**
|
||||
* @brief Calls the super function for the specific op.
|
||||
* @param klass The klass to work on
|
||||
* @param op The wanted op.
|
||||
* @param ... list of parameters.
|
||||
* @return @c EINA_TRUE on success.
|
||||
*
|
||||
* Don't use this function, use the wrapping macros instead.
|
||||
*
|
||||
* @see #eo_class_do
|
||||
* @see #eo_class_do_super
|
||||
*/
|
||||
EAPI Eina_Bool eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...);
|
||||
|
||||
/**
|
||||
* @brief Gets the class of the object.
|
||||
|
|
|
@ -113,6 +113,7 @@ struct _Eo_Class
|
|||
size_t extn_data_size;
|
||||
|
||||
const Eo_Class **mro;
|
||||
Eo_Kls_Itr mro_itr;
|
||||
|
||||
size_t data_offset; /* < Offset of the data within object data. */
|
||||
|
||||
|
@ -340,29 +341,62 @@ _eo_kls_itr_reached_end(const Eo_Kls_Itr *cur)
|
|||
return !(*kls_itr && *(kls_itr + 1));
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
|
||||
static inline const op_type_funcs *
|
||||
_eo_kls_itr_func_get(const Eo_Class *klass, Eo_Kls_Itr *mro_itr, Eo_Op op, Eo_Kls_Itr *prev_state)
|
||||
{
|
||||
const Eo_Class *klass;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
|
||||
|
||||
if (op_desc &&
|
||||
((constant == EINA_TRUE) && (op_desc->constant == EINA_FALSE)))
|
||||
{
|
||||
ERR("Tried calling non-const or non-existant op '%s' (%d) from a const (query) function.", (op_desc) ? op_desc->name : NULL, op);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
Eo_Kls_Itr prev_state;
|
||||
_eo_kls_itr_init(obj->klass, &obj->mro_itr, op, &prev_state);
|
||||
klass = _eo_kls_itr_get(&obj->mro_itr);
|
||||
_eo_kls_itr_init(klass, mro_itr, op, prev_state);
|
||||
klass = _eo_kls_itr_get(mro_itr);
|
||||
if (klass)
|
||||
{
|
||||
const op_type_funcs *func = _dich_func_get(klass, op);
|
||||
|
||||
if (func && func->func)
|
||||
{
|
||||
return func;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_eo_op_err_no_op_print(Eo_Op op, const Eo_Class *klass)
|
||||
{
|
||||
const Eo_Class *op_klass = OP_CLASS_GET(op);
|
||||
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, _eo_op_id_name_get(op), _dom_name,
|
||||
(klass) ? klass->desc->name : NULL);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
|
||||
{
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
|
||||
|
||||
if (op_desc)
|
||||
{
|
||||
if (op_desc->op_type == EO_OP_TYPE_CLASS)
|
||||
{
|
||||
ERR("Tried calling a class op '%s' (%d) from a non-class context.", (op_desc) ? op_desc->name : NULL, op);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else if ((op_type == EO_OP_TYPE_CONST) &&
|
||||
(op_desc->op_type != EO_OP_TYPE_CONST))
|
||||
{
|
||||
ERR("Tried calling non-const or non-existant op '%s' (%d) from a const (query) function.", (op_desc) ? op_desc->name : NULL, op);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
Eo_Kls_Itr prev_state;
|
||||
|
||||
{
|
||||
const op_type_funcs *func =
|
||||
_eo_kls_itr_func_get(obj->klass, &obj->mro_itr, op, &prev_state);
|
||||
if (func)
|
||||
{
|
||||
func->func(obj, _eo_data_get(obj, func->src), p_list);
|
||||
ret = EINA_TRUE;
|
||||
|
@ -376,7 +410,7 @@ _eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
|
|||
Eo *emb_obj;
|
||||
EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
|
||||
{
|
||||
if (_eo_op_internal(emb_obj, constant, op, p_list))
|
||||
if (_eo_op_internal(emb_obj, op_type, op, p_list))
|
||||
{
|
||||
ret = EINA_TRUE;
|
||||
goto end;
|
||||
|
@ -390,7 +424,7 @@ end:
|
|||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eo_do_internal(Eo *obj, Eina_Bool constant, ...)
|
||||
eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
|
||||
{
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
Eo_Op op = EO_NOOP;
|
||||
|
@ -400,18 +434,14 @@ eo_do_internal(Eo *obj, Eina_Bool constant, ...)
|
|||
|
||||
_eo_ref(obj);
|
||||
|
||||
va_start(p_list, constant);
|
||||
va_start(p_list, op_type);
|
||||
|
||||
op = va_arg(p_list, Eo_Op);
|
||||
while (op)
|
||||
{
|
||||
if (!_eo_op_internal(obj, constant, op, &p_list))
|
||||
if (!_eo_op_internal(obj, op_type, op, &p_list))
|
||||
{
|
||||
const Eo_Class *op_klass = OP_CLASS_GET(op);
|
||||
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, _eo_op_id_name_get(op), _dom_name,
|
||||
obj->klass->desc->name);
|
||||
_eo_op_err_no_op_print(op, obj->klass);
|
||||
ret = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -425,27 +455,110 @@ eo_do_internal(Eo *obj, Eina_Bool constant, ...)
|
|||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eo_do_super_internal(Eo *obj, Eina_Bool constant, Eo_Op op, ...)
|
||||
eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
|
||||
{
|
||||
const Eo_Class *obj_klass;
|
||||
const Eo_Class *nklass;
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
va_list p_list;
|
||||
EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
|
||||
|
||||
/* Advance the kls itr. */
|
||||
obj_klass = _eo_kls_itr_next(&obj->mro_itr, op);
|
||||
nklass = _eo_kls_itr_next(&obj->mro_itr, op);
|
||||
|
||||
if (obj->mro_itr.op != op)
|
||||
return EINA_FALSE;
|
||||
|
||||
va_start(p_list, op);
|
||||
if (!_eo_op_internal(obj, constant, op, &p_list))
|
||||
if (!_eo_op_internal(obj, op_type, op, &p_list))
|
||||
{
|
||||
const Eo_Class *op_klass = OP_CLASS_GET(op);
|
||||
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, _eo_op_id_name_get(op), _dom_name,
|
||||
(obj_klass) ? obj_klass->desc->name : NULL);
|
||||
_eo_op_err_no_op_print(op, nklass);
|
||||
ret = EINA_FALSE;
|
||||
}
|
||||
va_end(p_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eo_class_op_internal(Eo_Class *klass, Eo_Op op, va_list *p_list)
|
||||
{
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
|
||||
|
||||
if (op_desc)
|
||||
{
|
||||
if (op_desc->op_type != EO_OP_TYPE_CLASS)
|
||||
{
|
||||
ERR("Tried calling an instant op '%s' (%d) from a class context.", (op_desc) ? op_desc->name : NULL, op);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
Eo_Kls_Itr prev_state;
|
||||
|
||||
{
|
||||
const op_type_funcs *func =
|
||||
_eo_kls_itr_func_get(klass, &klass->mro_itr, op, &prev_state);
|
||||
if (func)
|
||||
{
|
||||
((eo_op_func_type_class) func->func)(klass, p_list);
|
||||
ret = EINA_TRUE;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
_eo_kls_itr_end(&klass->mro_itr, &prev_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eo_class_do_internal(const Eo_Class *klass, ...)
|
||||
{
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
Eo_Op op = EO_NOOP;
|
||||
va_list p_list;
|
||||
|
||||
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
|
||||
|
||||
va_start(p_list, klass);
|
||||
|
||||
op = va_arg(p_list, Eo_Op);
|
||||
while (op)
|
||||
{
|
||||
if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
|
||||
{
|
||||
_eo_op_err_no_op_print(op, klass);
|
||||
ret = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
op = va_arg(p_list, Eo_Op);
|
||||
}
|
||||
|
||||
va_end(p_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...)
|
||||
{
|
||||
const Eo_Class *nklass;
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
va_list p_list;
|
||||
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
|
||||
|
||||
/* Advance the kls itr. */
|
||||
nklass = _eo_kls_itr_next(&((Eo_Class *) klass)->mro_itr, op);
|
||||
|
||||
if (klass->mro_itr.op != op)
|
||||
return EINA_FALSE;
|
||||
|
||||
va_start(p_list, op);
|
||||
if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
|
||||
{
|
||||
_eo_op_err_no_op_print(op, nklass);
|
||||
ret = EINA_FALSE;
|
||||
}
|
||||
va_end(p_list);
|
||||
|
@ -635,13 +748,13 @@ eo_class_funcs_set(Eo_Class *klass, const Eo_Op_Func_Description *func_descs)
|
|||
{
|
||||
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(itr->op);
|
||||
|
||||
if (EINA_LIKELY(!op_desc || (itr->constant == op_desc->constant)))
|
||||
if (EINA_LIKELY(!op_desc || (itr->op_type == op_desc->op_type)))
|
||||
{
|
||||
_dich_func_set(klass, itr->op, itr->func);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Set function's constant property (%d) is different than the one in the op description (%d) for op '%s' in class '%s'.", itr->constant, op_desc->constant, op_desc->name, klass->desc->name);
|
||||
ERR("Set function's op type (%d) is different than the one in the op description (%d) for op '%s' in class '%s'.", itr->op_type, op_desc->op_type, op_desc->name, klass->desc->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,20 @@ _a_print(const Eo *obj EINA_UNUSED, const void *class_data, va_list *list)
|
|||
printf("Print %s %d\n", eo_class_name_get(MY_CLASS), pd->a);
|
||||
}
|
||||
|
||||
static void
|
||||
_class_hi_print(const Eo_Class *klass, va_list *list)
|
||||
{
|
||||
(void) list;
|
||||
printf("Hi Print %s\n", eo_class_name_get(klass));
|
||||
}
|
||||
|
||||
static void
|
||||
_class_constructor(Eo_Class *klass)
|
||||
{
|
||||
const Eo_Op_Func_Description func_desc[] = {
|
||||
EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
|
||||
EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
|
||||
EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), _class_hi_print),
|
||||
EO_OP_FUNC_SENTINEL
|
||||
};
|
||||
|
||||
|
@ -40,6 +48,7 @@ _class_constructor(Eo_Class *klass)
|
|||
static const Eo_Op_Description op_desc[] = {
|
||||
EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
|
||||
EO_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
|
||||
EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_HI_PRINT, "", "Print Hi"),
|
||||
EO_OP_DESCRIPTION_SENTINEL
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ extern EAPI Eo_Op SIMPLE_BASE_ID;
|
|||
enum {
|
||||
SIMPLE_SUB_ID_A_SET,
|
||||
SIMPLE_SUB_ID_A_PRINT,
|
||||
SIMPLE_SUB_ID_CLASS_HI_PRINT,
|
||||
SIMPLE_SUB_ID_LAST
|
||||
};
|
||||
|
||||
|
@ -20,6 +21,7 @@ typedef struct
|
|||
|
||||
#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
|
||||
#define simple_a_print() SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT)
|
||||
#define simple_class_hi_print() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT)
|
||||
|
||||
extern const Eo_Event_Description _SIG_A_CHANGED;
|
||||
#define SIG_A_CHANGED (&(_SIG_A_CHANGED))
|
||||
|
|
|
@ -309,19 +309,29 @@ _const_ops_a_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *l
|
|||
_const_ops_counter++;
|
||||
}
|
||||
|
||||
static void
|
||||
_const_ops_class_hi_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
|
||||
{
|
||||
_const_ops_counter++;
|
||||
}
|
||||
|
||||
static void
|
||||
_const_ops_class_constructor(Eo_Class *klass)
|
||||
{
|
||||
const Eo_Op_Func_Description func_desc[] = {
|
||||
EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _const_ops_a_set),
|
||||
EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _const_ops_a_print),
|
||||
EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), (eo_op_func_type_const) _const_ops_a_set),
|
||||
EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), (eo_op_func_type) _const_ops_a_print),
|
||||
EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), (eo_op_func_type_class) _const_ops_a_set),
|
||||
EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), (eo_op_func_type_class) _const_ops_a_print),
|
||||
EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), (eo_op_func_type_const) _const_ops_class_hi_print),
|
||||
EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), (eo_op_func_type) _const_ops_class_hi_print),
|
||||
EO_OP_FUNC_SENTINEL
|
||||
};
|
||||
|
||||
eo_class_funcs_set(klass, func_desc);
|
||||
}
|
||||
|
||||
START_TEST(eo_const_ops)
|
||||
START_TEST(eo_op_types)
|
||||
{
|
||||
eo_init();
|
||||
|
||||
|
@ -343,7 +353,7 @@ START_TEST(eo_const_ops)
|
|||
fail_if(!klass);
|
||||
|
||||
Eo *obj = eo_add(klass, NULL);
|
||||
eo_do(obj, simple_a_set(7), simple_a_print());
|
||||
eo_do(obj, simple_a_set(7), simple_a_print(), simple_class_hi_print());
|
||||
fail_if(_const_ops_counter != 0);
|
||||
|
||||
eo_unref(obj);
|
||||
|
@ -358,5 +368,5 @@ void eo_test_class_errors(TCase *tc)
|
|||
tcase_add_test(tc, eo_inherit_errors);
|
||||
tcase_add_test(tc, eo_inconsistent_mro);
|
||||
tcase_add_test(tc, eo_bad_interface);
|
||||
tcase_add_test(tc, eo_const_ops);
|
||||
tcase_add_test(tc, eo_op_types);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue