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 #define MY_CLASS INHERIT_CLASS
static void 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); Simple_Protected_Data *pd = eobj_data_get(obj, SIMPLE_CLASS);
(void) list; (void) list;
@ -22,7 +22,7 @@ static void
_class_constructor(Eobj_Class *klass) _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
} }
static const Eobj_Op_Description op_desc[] = { 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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -11,11 +11,11 @@ EAPI Eobj_Op COMP_BASE_ID = 0;
#define MY_CLASS COMP_CLASS #define MY_CLASS COMP_CLASS
static void 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; int *a;
a = va_arg(*list, int *); a = va_arg(*list, int *);
eobj_do_super(obj, SIMPLE_A_GET(a)); eobj_query_super(obj, SIMPLE_A_GET(a));
} }
static void static void
@ -39,7 +39,7 @@ static void
_class_constructor(Eobj_Class *klass) _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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 EOBJ_OP_FUNC_SENTINEL
}; };

View File

@ -23,9 +23,9 @@ _a_set(Eobj *obj, void *class_data, va_list *list)
} }
static void 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; int *a;
a = va_arg(*list, int *); a = va_arg(*list, int *);
*a = pd->a; *a = pd->a;
@ -36,7 +36,7 @@ _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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_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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -45,7 +45,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = { 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_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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0;
#define MY_CLASS MIXIN_CLASS #define MY_CLASS MIXIN_CLASS
static void 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; 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); x = va_arg(*list, const int);
printf("%s %d\n", __func__, a + b + x); printf("%s %d\n", __func__, a + b + x);
} }
@ -39,7 +39,7 @@ static void
_class_constructor(Eobj_Class *klass) _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -47,7 +47,7 @@ _class_constructor(Eobj_Class *klass)
} }
static const Eobj_Op_Description op_desc[] = { 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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -18,9 +18,9 @@ static char *class_var = NULL;
#define _GET_SET_FUNC(name) \ #define _GET_SET_FUNC(name) \
static void \ 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; \ int *name; \
name = va_arg(*list, int *); \ name = va_arg(*list, int *); \
*name = pd->name; \ *name = pd->name; \
@ -62,9 +62,9 @@ _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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_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_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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -81,9 +81,9 @@ _class_destructor(Eobj_Class *klass EINA_UNUSED)
static const Eobj_Op_Description op_desc[] = { 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_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_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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -47,7 +47,7 @@ _color_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
} }
static void 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); Evas_Object *evas_obj = eobj_evas_object_get(obj);
int *r, *g, *b, *a; 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_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_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_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_VISIBILITY_SET), _visibility_set),
EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), _child_add), EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), _child_add),
EOBJ_OP_FUNC_SENTINEL 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_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_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_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_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(EVAS_OBJ_SUB_ID_CHILD_ADD, "o", "Add a child eobj."),
EOBJ_OP_DESCRIPTION_SENTINEL 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" #define EVAS_OBJ_STR "Evas_Obj"
/* FIXME: Hack in the meanwhile. */ /* FIXME: Hack in the meanwhile. */
static inline Evas_Object * static inline Evas_Object *
eobj_evas_object_get(Eobj *obj) eobj_evas_object_get(const Eobj *obj)
{ {
void *data; 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; return data;
} }

View File

@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
} }
static void 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; (void) list;
printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a); 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[] = { 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_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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = { 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_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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0;
#define MY_CLASS MIXIN_CLASS #define MY_CLASS MIXIN_CLASS
static void 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; 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 *); int *sum = va_arg(*list, int *);
if (sum) if (sum)
*sum = a + b; *sum = a + b;
@ -35,7 +35,7 @@ static void
_class_constructor(Eobj_Class *klass) _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -44,7 +44,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = { 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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -10,19 +10,20 @@
#define MY_CLASS MIXIN2_CLASS #define MY_CLASS MIXIN2_CLASS
static void 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 *); int *sum = va_arg(*list, int *);
printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__); 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; ++*sum;
pd->count += 2; pd->count += 2;
{ {
int _a, _b; 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); fail_if(*sum != _a + _b + 1);
} }
} }
@ -43,7 +44,7 @@ static void
_class_constructor(Eobj_Class *klass) _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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 EOBJ_OP_FUNC_SENTINEL
}; };

View File

@ -10,19 +10,20 @@
#define MY_CLASS MIXIN3_CLASS #define MY_CLASS MIXIN3_CLASS
static void 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 *); int *sum = va_arg(*list, int *);
printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__); 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; ++*sum;
pd->count += 3; pd->count += 3;
{ {
int _a, _b; 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); fail_if(*sum != _a + _b + 2);
} }
} }
@ -43,7 +44,7 @@ static void
_class_constructor(Eobj_Class *klass) _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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 EOBJ_OP_FUNC_SENTINEL
}; };

View File

@ -18,9 +18,9 @@ typedef struct
#define _GET_SET_FUNC(name) \ #define _GET_SET_FUNC(name) \
static void \ 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; \ int *name; \
name = va_arg(*list, int *); \ name = va_arg(*list, int *); \
*name = pd->name; \ *name = pd->name; \
@ -44,9 +44,9 @@ _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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_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_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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -55,9 +55,9 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = { 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_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_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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -86,9 +86,21 @@ typedef unsigned int Eobj_Op;
* @typedef eobj_op_func_type * @typedef eobj_op_func_type
* The type of the Op functions. This is the type of the functions used by * The type of the Op functions. This is the type of the functions used by
* Eobj. * Eobj.
*
* @see eobj_op_func_type_const
*/ */
typedef void (*eobj_op_func_type)(Eobj *, void *class_data, va_list *list); 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 * @addtogroup Eobj_Events Eobj's Event Handling
* @{ * @{
@ -207,6 +219,7 @@ struct _Eobj_Op_Func_Description
{ {
Eobj_Op op; /**< The op */ Eobj_Op op; /**< The op */
eobj_op_func_type func; /**< The function to call for 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) * @def EOBJ_OP_FUNC(op, func)
* A convenience macro to be used when populating the #Eobj_Op_Func_Description * A convenience macro to be used when populating the #Eobj_Op_Func_Description
* array. * 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 * @def EOBJ_OP_FUNC_SENTINEL
* A convenience macro to be used when populating the #Eobj_Op_Func_Description * A convenience macro to be used when populating the #Eobj_Op_Func_Description
* array. It must appear at the end of the ARRAY. * 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 * @struct _Eobj_Op_Description
@ -239,6 +264,7 @@ struct _Eobj_Op_Description
const char *name; /**< The name of the op. */ const char *name; /**< The name of the op. */
const char *type; /**< descripbes the Op's function signature. */ const char *type; /**< descripbes the Op's function signature. */
const char *doc; /**< Explanation about the Op. */ 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 type The type string for the op.
* @param doc Additional doc for the op. * @param doc Additional doc for the op.
* @see Eobj_Op_Description * @see Eobj_Op_Description
* @see EOBJ_OP_DESCRIPTION_CONST
* @see EOBJ_OP_DESCRIPTION_SENTINEL * @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 * @def EOBJ_OP_DESCRIPTION_SENTINEL
* An helper macro to help populating #Eobj_Op_Description * 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
* @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. * @brief Create a new class.
@ -361,11 +403,19 @@ EAPI Eina_Bool eobj_shutdown(void);
* A convenience wrapper around eobj_do_internal() * A convenience wrapper around eobj_do_internal()
* @see 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. * @brief Issues ops on an object.
* @param obj The object to work on * @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. * @param ... NULL terminated list of OPs and parameters.
* @return #EINA_TRUE on success. * @return #EINA_TRUE on success.
* *
@ -374,20 +424,53 @@ EAPI Eina_Bool eobj_shutdown(void);
* *
* @see #eobj_do * @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. * @brief Calls the super function for the specific op.
* @param obj The object to work on * @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 op The wanted op.
* @param ... list of parameters. * @param ... list of parameters.
* @return #EINA_TRUE on success. * @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
* @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. * @brief Gets the class of the object.

View File

@ -345,12 +345,21 @@ _eobj_kls_itr_reached_end(const Eobj *obj)
} }
static Eina_Bool 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; const Eobj_Class *klass;
Eina_Bool ret = EINA_FALSE; Eina_Bool ret = EINA_FALSE;
Eina_Bool _itr_init; 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); _itr_init = _eobj_kls_itr_init(obj, op);
klass = _eobj_kls_itr_get(obj); klass = _eobj_kls_itr_get(obj);
while (klass) while (klass)
@ -373,7 +382,7 @@ _eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
Eobj *emb_obj; Eobj *emb_obj;
EINA_LIST_FOREACH(obj->composite_objects, itr, 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; ret = EINA_TRUE;
goto end; goto end;
@ -388,7 +397,7 @@ end:
} }
EAPI Eina_Bool EAPI Eina_Bool
eobj_do_internal(Eobj *obj, ...) eobj_do_internal(Eobj *obj, Eina_Bool constant, ...)
{ {
Eina_Bool ret = EINA_TRUE; Eina_Bool ret = EINA_TRUE;
Eobj_Op op = EOBJ_NOOP; Eobj_Op op = EOBJ_NOOP;
@ -398,12 +407,12 @@ eobj_do_internal(Eobj *obj, ...)
eobj_ref(obj); eobj_ref(obj);
va_start(p_list, obj); va_start(p_list, constant);
op = va_arg(p_list, Eobj_Op); op = va_arg(p_list, Eobj_Op);
while (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 Eobj_Class *op_klass = OP_CLASS_GET(op);
const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
@ -423,7 +432,7 @@ eobj_do_internal(Eobj *obj, ...)
} }
EAPI Eina_Bool 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; const Eobj_Class *obj_klass;
Eina_Bool ret = EINA_TRUE; Eina_Bool ret = EINA_TRUE;
@ -439,7 +448,7 @@ eobj_do_super(Eobj *obj, Eobj_Op op, ...)
} }
va_start(p_list, 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 Eobj_Class *op_klass = OP_CLASS_GET(op);
const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; 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++) 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 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 *); const char *key = va_arg(*list, const char *);
void **data = va_arg(*list, void **); void **data = va_arg(*list, void **);
Eobj_Generic_Data_Node *node; Eobj_Generic_Data_Node *node;
@ -145,7 +146,7 @@ _class_constructor(Eobj_Class *klass)
{ {
const Eobj_Op_Func_Description func_desc[] = { 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_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(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_DEL), _data_del),
EOBJ_OP_FUNC_SENTINEL EOBJ_OP_FUNC_SENTINEL
}; };
@ -155,7 +156,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = { 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_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(EOBJ_BASE_SUB_ID_DATA_DEL, "?", "Del key."),
EOBJ_OP_DESCRIPTION_SENTINEL EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
} }
static void 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; (void) list;
printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a); 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[] = { 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_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 EOBJ_OP_FUNC_SENTINEL
}; };
@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass)
static const Eobj_Op_Description op_desc[] = { 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_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 EOBJ_OP_DESCRIPTION_SENTINEL
}; };

View File

@ -293,10 +293,70 @@ START_TEST(eobj_bad_interface)
} }
END_TEST 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) void eobj_test_class_errors(TCase *tc)
{ {
tcase_add_test(tc, eobj_incomplete_desc); tcase_add_test(tc, eobj_incomplete_desc);
tcase_add_test(tc, eobj_inherit_errors); tcase_add_test(tc, eobj_inherit_errors);
tcase_add_test(tc, eobj_inconsistent_mro); tcase_add_test(tc, eobj_inconsistent_mro);
tcase_add_test(tc, eobj_bad_interface); 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); fail_if(eobj_ref_get(obj) != 1);
eobj_unref(obj); 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(); eobj_shutdown();
} }
END_TEST END_TEST