Eobj: Added infrastructure for const functions and eobj_query.

SVN revision: 70431
This commit is contained in:
Tom Hacohen 2012-04-24 08:04:14 +00:00
parent b004b4c833
commit 4e05a6193c
18 changed files with 243 additions and 73 deletions

View File

@ -11,7 +11,7 @@ EAPI Eobj_Op INHERIT_BASE_ID = 0;
#define MY_CLASS INHERIT_CLASS
static void
_prot_print(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
_prot_print(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
{
Simple_Protected_Data *pd = eobj_data_get(obj, SIMPLE_CLASS);
(void) list;
@ -22,7 +22,7 @@ static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print),
EOBJ_OP_FUNC_CONST(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print),
EOBJ_OP_FUNC_SENTINEL
};
@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
}
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."),
EOBJ_OP_DESCRIPTION_CONST(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -11,11 +11,11 @@ EAPI Eobj_Op COMP_BASE_ID = 0;
#define MY_CLASS COMP_CLASS
static void
_a_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
_a_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
{
int *a;
a = va_arg(*list, int *);
eobj_do_super(obj, SIMPLE_A_GET(a));
eobj_query_super(obj, SIMPLE_A_GET(a));
}
static void
@ -39,7 +39,7 @@ static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC_SENTINEL
};

View File

@ -23,9 +23,9 @@ _a_set(Eobj *obj, void *class_data, va_list *list)
}
static void
_a_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
_a_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
{
Simple_Public_Data *pd = class_data;
const Simple_Public_Data *pd = class_data;
int *a;
a = va_arg(*list, int *);
*a = pd->a;
@ -36,7 +36,7 @@ _class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC_SENTINEL
};
@ -45,7 +45,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0;
#define MY_CLASS MIXIN_CLASS
static void
_add_and_print_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
_add_and_print_set(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
{
int a, b, x;
eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
eobj_query(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
x = va_arg(*list, const int);
printf("%s %d\n", __func__, a + b + x);
}
@ -39,7 +39,7 @@ static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set),
EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set),
EOBJ_OP_FUNC_SENTINEL
};
@ -47,7 +47,7 @@ _class_constructor(Eobj_Class *klass)
}
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"),
EOBJ_OP_DESCRIPTION_CONST(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -18,9 +18,9 @@ static char *class_var = NULL;
#define _GET_SET_FUNC(name) \
static void \
_##name##_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) \
_##name##_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) \
{ \
Private_Data *pd = class_data; \
const Private_Data *pd = class_data; \
int *name; \
name = va_arg(*list, int *); \
*name = pd->name; \
@ -62,9 +62,9 @@ _class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
EOBJ_OP_FUNC_SENTINEL
};
@ -81,9 +81,9 @@ _class_destructor(Eobj_Class *klass EINA_UNUSED)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -47,7 +47,7 @@ _color_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
}
static void
_color_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
_color_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
{
Evas_Object *evas_obj = eobj_evas_object_get(obj);
int *r, *g, *b, *a;
@ -109,7 +109,7 @@ _class_constructor(Eobj_Class *klass)
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_POSITION_SET), _position_set),
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SIZE_SET), _size_set),
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_SET), _color_set),
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get),
EOBJ_OP_FUNC_CONST(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get),
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_VISIBILITY_SET), _visibility_set),
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), _child_add),
EOBJ_OP_FUNC_SENTINEL
@ -122,7 +122,7 @@ static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_POSITION_SET, "ii", "Position of an evas object."),
EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_SIZE_SET, "ii", "Size of an evas object."),
EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_SET, "iiii", "Color of an evas object."),
EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."),
EOBJ_OP_DESCRIPTION_CONST(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."),
EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_VISIBILITY_SET, "b", "Visibility of an evas object."),
EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_CHILD_ADD, "o", "Add a child eobj."),
EOBJ_OP_DESCRIPTION_SENTINEL

View File

@ -73,10 +73,10 @@ const Eobj_Class *evas_object_class_get(void) EINA_CONST;
#define EVAS_OBJ_STR "Evas_Obj"
/* FIXME: Hack in the meanwhile. */
static inline Evas_Object *
eobj_evas_object_get(Eobj *obj)
eobj_evas_object_get(const Eobj *obj)
{
void *data;
eobj_do(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data));
eobj_query(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data));
return data;
}

View File

@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
}
static void
_a_print(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
_a_print(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
{
Simple_Public_Data *pd = class_data;
const Simple_Public_Data *pd = class_data;
(void) list;
printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a);
}
@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
EOBJ_OP_FUNC_SENTINEL
};
@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0;
#define MY_CLASS MIXIN_CLASS
static void
_ab_sum_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
_ab_sum_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
{
int a, b;
eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
eobj_query(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
int *sum = va_arg(*list, int *);
if (sum)
*sum = a + b;
@ -35,7 +35,7 @@ static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
EOBJ_OP_FUNC_SENTINEL
};
@ -44,7 +44,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_AB_SUM_GET, "i", "Get the sum of a and b."),
EOBJ_OP_DESCRIPTION_CONST(MIXIN_SUB_ID_AB_SUM_GET, "i", "Get the sum of a and b."),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -10,19 +10,20 @@
#define MY_CLASS MIXIN2_CLASS
static void
_ab_sum_get(Eobj *obj, void *class_data, va_list *list)
_ab_sum_get(const Eobj *obj, const void *class_data, va_list *list)
{
Mixin2_Public_Data *pd = class_data;
/* This cast is a hack just for the tests... */
Mixin2_Public_Data *pd = (Mixin2_Public_Data *) class_data;
int *sum = va_arg(*list, int *);
printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__);
eobj_do_super(obj, MIXIN_AB_SUM_GET(sum));
eobj_query_super(obj, MIXIN_AB_SUM_GET(sum));
++*sum;
pd->count += 2;
{
int _a, _b;
eobj_do(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
eobj_query(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
fail_if(*sum != _a + _b + 1);
}
}
@ -43,7 +44,7 @@ static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
EOBJ_OP_FUNC_SENTINEL
};

View File

@ -10,19 +10,20 @@
#define MY_CLASS MIXIN3_CLASS
static void
_ab_sum_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
_ab_sum_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
{
Mixin3_Public_Data *pd = class_data;
/* This cast is just a hack for the test. */
Mixin3_Public_Data *pd = (Mixin3_Public_Data *) class_data;
int *sum = va_arg(*list, int *);
printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__);
eobj_do_super(obj, MIXIN_AB_SUM_GET(sum));
eobj_query_super(obj, MIXIN_AB_SUM_GET(sum));
++*sum;
pd->count += 3;
{
int _a, _b;
eobj_do(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
eobj_query(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
fail_if(*sum != _a + _b + 2);
}
}
@ -43,7 +44,7 @@ static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
EOBJ_OP_FUNC_SENTINEL
};

View File

@ -18,9 +18,9 @@ typedef struct
#define _GET_SET_FUNC(name) \
static void \
_##name##_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) \
_##name##_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) \
{ \
Private_Data *pd = class_data; \
const Private_Data *pd = class_data; \
int *name; \
name = va_arg(*list, int *); \
*name = pd->name; \
@ -44,9 +44,9 @@ _class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
EOBJ_OP_FUNC_SENTINEL
};
@ -55,9 +55,9 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -86,9 +86,21 @@ typedef unsigned int Eobj_Op;
* @typedef eobj_op_func_type
* The type of the Op functions. This is the type of the functions used by
* Eobj.
*
* @see eobj_op_func_type_const
*/
typedef void (*eobj_op_func_type)(Eobj *, void *class_data, va_list *list);
/**
* @typedef eobj_op_func_type_const
* The type of the const Op functions. This is the type of the functions used
* by Eobj. This is the same as #eobj_op_func_type, except that this should
* be used with functions that don't modify the data.
*
* @see eobj_op_func_type
*/
typedef void (*eobj_op_func_type_const)(const Eobj *, const void *class_data, va_list *list);
/**
* @addtogroup Eobj_Events Eobj's Event Handling
* @{
@ -207,6 +219,7 @@ struct _Eobj_Op_Func_Description
{
Eobj_Op op; /**< The op */
eobj_op_func_type func; /**< The function to call for the op. */
Eina_Bool constant; /**< #EINA_TRUE if this function is a const. */
};
/**
@ -219,15 +232,27 @@ typedef struct _Eobj_Op_Func_Description Eobj_Op_Func_Description;
* @def EOBJ_OP_FUNC(op, func)
* A convenience macro to be used when populating the #Eobj_Op_Func_Description
* array.
*
* @see EOBJ_OP_FUNC_CONST
*/
#define EOBJ_OP_FUNC(op, func) { op, func }
#define EOBJ_OP_FUNC(op, func) { op, EOBJ_TYPECHECK(eobj_op_func_type, func), EINA_FALSE }
/**
* @def EOBJ_OP_FUNC_CONST(op, func)
* A convenience macro to be used when populating the #Eobj_Op_Func_Description
* array.
* The same as #EOBJ_OP_FUNC but for const functions.
*
* @see EOBJ_OP_FUNC
*/
#define EOBJ_OP_FUNC_CONST(op, func) { op, (eobj_op_func_type) EOBJ_TYPECHECK(eobj_op_func_type_const, func), EINA_TRUE }
/**
* @def EOBJ_OP_FUNC_SENTINEL
* A convenience macro to be used when populating the #Eobj_Op_Func_Description
* array. It must appear at the end of the ARRAY.
*/
#define EOBJ_OP_FUNC_SENTINEL { 0, NULL }
#define EOBJ_OP_FUNC_SENTINEL { 0, NULL, EINA_FALSE }
/**
* @struct _Eobj_Op_Description
@ -239,6 +264,7 @@ struct _Eobj_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; /**< #EINA_TRUE if this op's implementation should not change the obj. */
};
/**
@ -292,9 +318,25 @@ typedef struct _Eobj_Class_Description Eobj_Class_Description;
* @param type The type string for the op.
* @param doc Additional doc for the op.
* @see Eobj_Op_Description
* @see EOBJ_OP_DESCRIPTION_CONST
* @see EOBJ_OP_DESCRIPTION_SENTINEL
*/
#define EOBJ_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc }
#define EOBJ_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_FALSE }
/**
* @def EOBJ_OP_DESCRIPTION_CONST(op, type, doc)
* An helper macro to help populating #Eobj_Op_Description
* This macro is the same as EOBJ_OP_DESCRIPTION but indicates that the op's
* implementation should not change the object.
* @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 Eobj_Op_Description
* @see EOBJ_OP_DESCRIPTION
* @see EOBJ_OP_DESCRIPTION_SENTINEL
*/
#define EOBJ_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_TRUE }
/**
* @def EOBJ_OP_DESCRIPTION_SENTINEL
* An helper macro to help populating #Eobj_Op_Description
@ -302,7 +344,7 @@ typedef struct _Eobj_Class_Description Eobj_Class_Description;
* @see Eobj_Op_Description
* @see EOBJ_OP_DESCRIPTION
*/
#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL }
#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL, EINA_FALSE }
/**
* @brief Create a new class.
@ -361,11 +403,19 @@ EAPI Eina_Bool eobj_shutdown(void);
* A convenience wrapper around eobj_do_internal()
* @see eobj_do_internal
*/
#define eobj_do(object, ...) eobj_do_internal(object, __VA_ARGS__, (Eobj_Op) 0)
#define eobj_do(obj, ...) eobj_do_internal(obj, EINA_FALSE, __VA_ARGS__, EOBJ_NOOP)
/**
* @def eobj_query
* Same as #eobj_do but only for const ops.
* @see eobj_do
*/
#define eobj_query(obj, ...) eobj_do_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_TRUE, __VA_ARGS__, EOBJ_NOOP)
/**
* @brief Issues ops on an object.
* @param obj The object to work on
* @param constant #EINA_TRUE if this call is on a constant object.
* @param ... NULL terminated list of OPs and parameters.
* @return #EINA_TRUE on success.
*
@ -374,20 +424,53 @@ EAPI Eina_Bool eobj_shutdown(void);
*
* @see #eobj_do
*/
EAPI Eina_Bool eobj_do_internal(Eobj *obj, ...);
EAPI Eina_Bool eobj_do_internal(Eobj *obj, Eina_Bool constant, ...);
/**
* @brief Calls the super function for the specific op.
* @param obj The object to work on
* @param ... list of parameters.
* @return #EINA_TRUE on success.
*
* Unlike eobj_do() and eobj_query(), this function only accepts one op.
*
* Use the helper macros, don't pass the parameters manually.
*
* Same as eobj_do_super() just for const objects.
*
* @see #eobj_query
* @see eobj_do_super()
*/
#define eobj_query_super(obj, ...) eobj_do_super_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_TRUE, __VA_ARGS__)
/**
* @brief Calls the super function for the specific op.
* @param obj The object to work on
* @param ... list of parameters.
* @return #EINA_TRUE on success.
*
* Unlike eobj_do() and eobj_query(), this function only accepts one op.
*
* @see #eobj_query
* @see eobj_query_super()
*/
#define eobj_do_super(obj, ...) eobj_do_super_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_FALSE, __VA_ARGS__)
/**
* @brief Calls the super function for the specific op.
* @param obj The object to work on
* @param constant #EINA_TRUE if this call is on a constant object.
* @param op The wanted op.
* @param ... list of parameters.
* @return #EINA_TRUE on success.
*
* Use the helper macros, don't pass the parameters manually.
* Don't use this function, use the wrapping macros instead.
*
* @see #eobj_do
* @see #eobj_do_super
* @see #eobj_query_super
*/
EAPI Eina_Bool eobj_do_super(Eobj *obj, Eobj_Op op, ...);
EAPI Eina_Bool eobj_do_super_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, ...);
/**
* @brief Gets the class of the object.

View File

@ -345,12 +345,21 @@ _eobj_kls_itr_reached_end(const Eobj *obj)
}
static Eina_Bool
_eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
_eobj_op_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, va_list *p_list)
{
const Eobj_Class *klass;
Eina_Bool ret = EINA_FALSE;
Eina_Bool _itr_init;
const Eobj_Op_Description *op_desc = _eobj_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;
}
_itr_init = _eobj_kls_itr_init(obj, op);
klass = _eobj_kls_itr_get(obj);
while (klass)
@ -373,7 +382,7 @@ _eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
Eobj *emb_obj;
EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
{
if (_eobj_op_internal(emb_obj, op, p_list))
if (_eobj_op_internal(emb_obj, constant, op, p_list))
{
ret = EINA_TRUE;
goto end;
@ -388,7 +397,7 @@ end:
}
EAPI Eina_Bool
eobj_do_internal(Eobj *obj, ...)
eobj_do_internal(Eobj *obj, Eina_Bool constant, ...)
{
Eina_Bool ret = EINA_TRUE;
Eobj_Op op = EOBJ_NOOP;
@ -398,12 +407,12 @@ eobj_do_internal(Eobj *obj, ...)
eobj_ref(obj);
va_start(p_list, obj);
va_start(p_list, constant);
op = va_arg(p_list, Eobj_Op);
while (op)
{
if (!_eobj_op_internal(obj, op, &p_list))
if (!_eobj_op_internal(obj, constant, op, &p_list))
{
const Eobj_Class *op_klass = OP_CLASS_GET(op);
const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
@ -423,7 +432,7 @@ eobj_do_internal(Eobj *obj, ...)
}
EAPI Eina_Bool
eobj_do_super(Eobj *obj, Eobj_Op op, ...)
eobj_do_super_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, ...)
{
const Eobj_Class *obj_klass;
Eina_Bool ret = EINA_TRUE;
@ -439,7 +448,7 @@ eobj_do_super(Eobj *obj, Eobj_Op op, ...)
}
va_start(p_list, op);
if (!_eobj_op_internal(obj, op, &p_list))
if (!_eobj_op_internal(obj, constant, op, &p_list))
{
const Eobj_Class *op_klass = OP_CLASS_GET(op);
const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
@ -616,7 +625,16 @@ eobj_class_funcs_set(Eobj_Class *klass, const Eobj_Op_Func_Description *func_des
{
for ( ; itr->op != 0 ; itr++)
{
dich_func_set(klass, itr->op, itr->func);
const Eobj_Op_Description *op_desc = _eobj_op_id_desc_get(itr->op);
if (EINA_LIKELY(!op_desc || (itr->constant == op_desc->constant)))
{
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);
}
}
}
}

View File

@ -67,9 +67,10 @@ _data_set(Eobj *obj, void *class_data, va_list *list)
}
static void
_data_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
_data_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
{
Private_Data *pd = class_data;
/* We don't really change it... */
Private_Data *pd = (Private_Data *) class_data;
const char *key = va_arg(*list, const char *);
void **data = va_arg(*list, void **);
Eobj_Generic_Data_Node *node;
@ -145,7 +146,7 @@ _class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_SET), _data_set),
EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get),
EOBJ_OP_FUNC_CONST(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get),
EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_DEL), _data_del),
EOBJ_OP_FUNC_SENTINEL
};
@ -155,7 +156,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_SET, "?", "Set data for key."),
EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."),
EOBJ_OP_DESCRIPTION_CONST(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."),
EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_DEL, "?", "Del key."),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
}
static void
_a_print(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
_a_print(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
{
Simple_Public_Data *pd = class_data;
const Simple_Public_Data *pd = class_data;
(void) list;
printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a);
}
@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
EOBJ_OP_FUNC_SENTINEL
};
@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
EOBJ_OP_DESCRIPTION_SENTINEL
};

View File

@ -293,10 +293,70 @@ START_TEST(eobj_bad_interface)
}
END_TEST
static int _const_ops_counter = 0;
static void
_const_ops_a_set(const Eobj *obj EINA_UNUSED, const void *class_data EINA_UNUSED, va_list *list)
{
int a = va_arg(*list, int);
(void) a;
_const_ops_counter++;
}
static void
_const_ops_a_print(Eobj *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
{
_const_ops_counter++;
}
static void
_const_ops_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _const_ops_a_set),
EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _const_ops_a_print),
EOBJ_OP_FUNC_SENTINEL
};
eobj_class_funcs_set(klass, func_desc);
}
START_TEST(eobj_const_ops)
{
eobj_init();
const Eobj_Class *klass;
static Eobj_Class_Description class_desc = {
"Simple",
EOBJ_CLASS_TYPE_REGULAR,
EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
NULL,
0,
NULL,
NULL,
_const_ops_class_constructor,
NULL
};
klass = eobj_class_new(&class_desc, SIMPLE_CLASS, NULL);
fail_if(!klass);
Eobj *obj = eobj_add(klass, NULL);
eobj_do(obj, SIMPLE_A_SET(7), SIMPLE_A_PRINT());
fail_if(_const_ops_counter != 0);
eobj_unref(obj);
eobj_shutdown();
}
END_TEST
void eobj_test_class_errors(TCase *tc)
{
tcase_add_test(tc, eobj_incomplete_desc);
tcase_add_test(tc, eobj_inherit_errors);
tcase_add_test(tc, eobj_inconsistent_mro);
tcase_add_test(tc, eobj_bad_interface);
tcase_add_test(tc, eobj_const_ops);
}

View File

@ -165,6 +165,12 @@ START_TEST(eobj_op_errors)
fail_if(eobj_ref_get(obj) != 1);
eobj_unref(obj);
obj = eobj_add(SIMPLE_CLASS, NULL);
fail_if(!eobj_do(obj, SIMPLE_A_PRINT()));
fail_if(!eobj_query(obj, SIMPLE_A_PRINT()));
fail_if(eobj_query(obj, SIMPLE_A_SET(1)));
eobj_shutdown();
}
END_TEST