#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;
_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
};
}
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
};
#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
_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
};
}
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;
{
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
};
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
};
#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);
}
_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
};
}
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
};
#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; \
{
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
};
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
};
}
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;
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
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
#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;
}
}
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);
}
{
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
};
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
};
#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;
_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
};
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
};
#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);
}
}
_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
};
#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);
}
}
_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
};
#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; \
{
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
};
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
};
* @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
* @{
*/
{
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. */
};
/**
* @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, 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(op, func) { 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
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. */
};
/**
* @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
* @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.
* 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.
*
*
* @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 op The wanted op.
* @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.
+ *
+ * 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.
}
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)
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;
}
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;
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;
}
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;
}
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;
{
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);
+ }
}
}
}
}
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;
{
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
};
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
};
}
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);
}
{
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
};
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
};
}
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);
}
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