Eo: Added eo_add_custom and support for passing ops to eo_add.

We can no do things like eo_add(CLASS, parent, age_set(7), score_set(100)),
or pass different constructors to object creation by using eo_add_custom and
passing the constructor.

SVN revision: 75614
This commit is contained in:
Tom Hacohen 2012-08-23 10:35:14 +00:00
parent ad096efc93
commit 410488aabe
3 changed files with 89 additions and 10 deletions

View File

@ -552,13 +552,47 @@ EAPI const Eo_Class *eo_class_get(const Eo *obj);
EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line);
/* @endcond */
/**
* @def eo_add
* @brief Create a new object with the default constructor.
* @param klass the class of the object to create.
* @param parent the parent to set to the object.
* @param ... The ops to run.
* @return An handle to the new object on success, NULL otherwise.
*/
#define eo_add(klass, parent, ...) \
({ \
(void) klass; \
eo_add_internal(klass, parent, eo_constructor(), ## __VA_ARGS__, EO_NOOP); \
})
/**
* @def eo_add_custom
* @brief Create a new object with a custom constructor.
* @param klass the class of the object to create.
* @param parent the parent to set to the object.
* @param ... The ops to run. With the constructor being first.
* @return An handle to the new object on success, NULL otherwise.
*/
#define eo_add_custom(klass, parent, ...) \
({ \
(void) klass; \
eo_add_internal(klass, parent, ## __VA_ARGS__, EO_NOOP); \
})
/**
* @brief Create a new object.
* @param klass the class of the object to create.
* @param parent the parent to set to the object.
* @param ... The ops to run. With the constructor being first.
* @return An handle to the new object on success, NULL otherwise.
*
* Use the helper macros, don't pass the parameters manually.
* Use #eo_add or #eo_add_custom instead of this function.
*
* @see #eo_add
*/
EAPI Eo *eo_add(const Eo_Class *klass, Eo *parent);
EAPI Eo *eo_add_internal(const Eo_Class *klass, Eo *parent, ...);
/**
* @brief Get the parent of an object

View File

@ -378,22 +378,19 @@ _eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
return EINA_FALSE;
}
EAPI Eina_Bool
eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
static inline Eina_Bool
_eo_dov_internal(Eo *obj, Eo_Op_Type op_type, va_list p_list)
{
Eina_Bool prev_error;
Eina_Bool ret = EINA_TRUE;
Eo_Op op = EO_NOOP;
Eo_Kls_Itr prev_state;
va_list p_list;
EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
prev_error = obj->do_error;
_eo_ref(obj);
va_start(p_list, op_type);
op = va_arg(p_list, Eo_Op);
while (op)
{
@ -409,8 +406,6 @@ eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
}
va_end(p_list);
_eo_unref(obj);
if (obj->do_error)
@ -421,6 +416,21 @@ eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
return ret;
}
EAPI Eina_Bool
eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
{
Eina_Bool ret = EINA_TRUE;
va_list p_list;
va_start(p_list, op_type);
ret = _eo_dov_internal(obj, op_type, p_list);
va_end(p_list);
return ret;
}
EAPI Eina_Bool
eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
{
@ -1095,7 +1105,7 @@ eo_parent_set(Eo *obj, const Eo *parent)
}
EAPI Eo *
eo_add(const Eo_Class *klass, Eo *parent)
eo_add_internal(const Eo_Class *klass, Eo *parent, ...)
{
Eina_Bool do_err;
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, NULL);
@ -1120,7 +1130,14 @@ eo_add(const Eo_Class *klass, Eo *parent)
_eo_condtor_reset(obj);
_eo_ref(obj);
do_err = !eo_do(obj, eo_constructor());
/* Run the relevant do stuff. */
{
va_list p_list;
va_start(p_list, parent);
do_err = !_eo_dov_internal(obj, EO_OP_TYPE_REGULAR, p_list);
va_end(p_list);
}
if (EINA_UNLIKELY(do_err))
{
@ -1133,6 +1150,7 @@ eo_add(const Eo_Class *klass, Eo *parent)
ERR("Object of class '%s' - Not all of the object constructors have been executed.", klass->desc->name);
goto fail;
}
_eo_unref(obj);
return obj;

View File

@ -695,6 +695,32 @@ START_TEST(eo_multiple_do)
}
END_TEST
START_TEST(eo_add_do_and_custom)
{
Simple_Public_Data *pd = NULL;
Eo *obj = NULL;
eo_init();
obj = eo_add_custom(SIMPLE_CLASS, NULL, eo_constructor());
fail_if(!obj);
eo_unref(obj);
obj = eo_add(SIMPLE_CLASS, NULL, simple_a_set(7));
fail_if(!obj);
pd = eo_data_get(obj, SIMPLE_CLASS);
fail_if(pd->a != 7);
eo_unref(obj);
obj = eo_add_custom(SIMPLE_CLASS, NULL, eo_constructor(), simple_a_set(7));
fail_if(!obj);
pd = eo_data_get(obj, SIMPLE_CLASS);
fail_if(pd->a != 7);
eo_unref(obj);
eo_shutdown();
}
END_TEST
void eo_test_general(TCase *tc)
{
tcase_add_test(tc, eo_generic_data);
@ -708,4 +734,5 @@ void eo_test_general(TCase *tc)
tcase_add_test(tc, eo_composite_tests);
tcase_add_test(tc, eo_isa_tests);
tcase_add_test(tc, eo_multiple_do);
tcase_add_test(tc, eo_add_do_and_custom);
}