From a129099d48dc4f0c4fe7f1993b2218439dc1c15e Mon Sep 17 00:00:00 2001 From: tasn Date: Thu, 23 Aug 2012 10:35:14 +0000 Subject: 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. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@75614 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Eo.h | 36 +++++++++++++++++++++++++++++++++++- src/lib/eo.c | 36 +++++++++++++++++++++++++++--------- src/tests/eo_suite/eo_test_general.c | 27 +++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/src/lib/Eo.h b/src/lib/Eo.h index f9de616..b6e10f3 100644 --- a/src/lib/Eo.h +++ b/src/lib/Eo.h @@ -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 diff --git a/src/lib/eo.c b/src/lib/eo.c index 7d8f07f..4d2a2f2 100644 --- a/src/lib/eo.c +++ b/src/lib/eo.c @@ -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; diff --git a/src/tests/eo_suite/eo_test_general.c b/src/tests/eo_suite/eo_test_general.c index ac395d2..20ab4b5 100644 --- a/src/tests/eo_suite/eo_test_general.c +++ b/src/tests/eo_suite/eo_test_general.c @@ -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); } -- cgit v1.2.3