diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 63e4c6b89a..5390e61c8e 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -1539,6 +1539,35 @@ EAPI Eo *_efl_added_get(void); EAPI Eo * _efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent, Eina_Bool ref, Eina_Bool is_fallback); +/** + * @typedef Efl_Substitute_Ctor_Cb + * Callback to be called instead of the object constructor. + * + * Only intended for binding creators. + * + * @param data Additional data previously supplied by the user + * @param obj_id The object being constructed. + * @return The constructed object in case of success, NULL otherwise. + */ +typedef Eo *(*Efl_Substitute_Ctor_Cb)(void *data, Eo *obj_id); + +/** + * @brief Just like _efl_add_internal_start() but with additional options + * + * Only intended for binding creators. + * + * @param file File name of the call site, used for debug logs. + * @param line Line number of the call site, used for debug logs. + * @param klass_id Pointer for the class being instantiated. + * @param ref Whether or not the object will have an additional reference if it has a parent. + * @param parent Object parent, can be NULL. + * @param is_fallback Whether or not the fallback @c efl_added behaviour is to be used. + * @param substitute_ctor Optional callback to replace the call for efl_constructor(), if NULL efl_constructor() will be called normally. + * @param sub_ctor_data Additional data to be passed to the @p substitute_ctor callback. + * @return An handle to the new object on success, NULL otherwise. + */ +EAPI Eo * _efl_add_internal_start_bindings(const char *file, int line, const Efl_Class *klass_id, Eo *parent, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data); + /** * @brief Unrefs the object and reparents it to NULL. * diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index db96b24ef7..c1156ec386 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -857,8 +857,8 @@ err_klass: return EINA_FALSE; } -EAPI Eo * -_efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback) +static Eo * +_efl_add_internal_start_do(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data) { const char *func_name = __FUNCTION__; _Eo_Object *obj; @@ -918,7 +918,8 @@ _efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, E if (parent_id) efl_parent_set(eo_id, parent_id); /* eo_id can change here. Freeing is done on the resolved object. */ - eo_id = efl_constructor(eo_id); + if (!substitute_ctor) eo_id = efl_constructor(eo_id); + else eo_id = substitute_ctor(sub_ctor_data, eo_id); // not likely so use goto to alleviate l1 instruction cache of rare code if (!eo_id) goto err_noid; // not likely so use goto to alleviate l1 instruction cache of rare code @@ -962,6 +963,17 @@ err_parent: return NULL; } +EAPI Eo * +_efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback) +{ + return _efl_add_internal_start_do(file, line, klass_id, parent_id, ref, is_fallback, NULL, NULL); +} + +EAPI Eo * _efl_add_internal_start_bindings(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data) +{ + return _efl_add_internal_start_do(file, line, klass_id, parent_id, ref, is_fallback, substitute_ctor, sub_ctor_data); +} + static Eo * _efl_add_internal_end(Eo *eo_id, Eo *finalized_id) {