From 64ad6affa8e23b8b2ba99cecdf852c8d8307e878 Mon Sep 17 00:00:00 2001 From: barbieri Date: Thu, 9 Feb 2012 16:20:16 +0000 Subject: [PATCH] eina_model: helper function to setup subclass during runtime. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@67795 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/include/eina_model.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib/eina_model.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/include/eina_model.h b/src/include/eina_model.h index 9e5aa01..1240a4a 100644 --- a/src/include/eina_model.h +++ b/src/include/eina_model.h @@ -979,6 +979,60 @@ EAPI Eina_Bool eina_model_type_check(const Eina_Model_Type *type) EINA_ARG_NONNU EAPI const char *eina_model_type_name_get(const Eina_Model_Type *type) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT EINA_PURE; EAPI const Eina_Model_Type *eina_model_type_parent_get(const Eina_Model_Type *type) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT EINA_PURE; +/** + * @brief Setup the type to be a subclass of another parent type. + * @param type type to be modified + * @param parent type to be used as parent + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * Although @a type is modified, the following properties are not + * touched or they are actually used for validation: + * + * @li @c type->version must be #EINA_MODEL_TYPE_VERSION; + * @li @c type->private_size unmodified, should be set to type's size; + * @li @c type->name unmodified, should be set to type's name. + * + * + * All other fields are modified as follow: + * + * @li @c type->type_size initiated to parent->type_size + * @li @c type->interfaces = NULL; + * @li @c type->events = NULL; + * @li @c type->setup = NULL; + * @li @c type->flush = NULL; + * @li @c type->constructor = NULL; + * @li @c type->destructor = NULL; + * @li @c type->copy = NULL; + * @li @c type->deep_copy = NULL; + * @li @c type->compare = NULL; + * @li @c type->load = NULL; + * @li @c type->unload = NULL; + * @li @c type->property_get = NULL; + * @li @c type->property_set = NULL; + * @li @c type->property_del = NULL; + * @li @c type->properties_names_list_get = NULL; + * @li @c type->child_count = NULL; + * @li @c type->child_get = NULL; + * @li @c type->child_set = NULL; + * @li @c type->child_del = NULL; + * @li @c type->child_insert_at = NULL; + * @li @c type->child_find = NULL; + * @li @c type->child_search = NULL; + * @li @c type->child_sort = NULL; + * @li @c type->child_iterator_get = NULL; + * @li @c type->child_reversed_iterator_get = NULL; + * @li @c type->child_sorted_iterator_get = NULL; + * @li @c type->child_filtered_iterator_get = NULL; + * @li @c type->to_string = NULL; + * + * If you have custom methods, overload them afterwards + * eina_model_type_subclass_setup() returns with #EINA_TRUE. + * + * @since 1.2 + */ +EAPI Eina_Bool eina_model_type_subclass_setup(Eina_Model_Type *type, + const Eina_Model_Type *parent) EINA_ARG_NONNULL(1, 2); + EAPI Eina_Bool eina_model_type_subclass_check(const Eina_Model_Type *type, const Eina_Model_Type *self_or_parent) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_PURE; diff --git a/src/lib/eina_model.c b/src/lib/eina_model.c index de5de0b..21ad4ab 100644 --- a/src/lib/eina_model.c +++ b/src/lib/eina_model.c @@ -4207,7 +4207,6 @@ eina_model_type_parent_get(const Eina_Model_Type *type) return type->parent; } - #define EINA_MODEL_TYPE_INSTANCE_CHECK(type, model) \ EINA_SAFETY_ON_NULL_RETURN(type); \ EINA_SAFETY_ON_FALSE_RETURN(_eina_model_type_check(type)); \ @@ -4578,6 +4577,61 @@ eina_model_type_to_string(const Eina_Model_Type *type, const Eina_Model *model) } EAPI Eina_Bool +eina_model_type_subclass_setup(Eina_Model_Type *type, const Eina_Model_Type *parent) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(parent, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(parent), EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(type->version == EINA_MODEL_TYPE_VERSION, + EINA_FALSE); + + type->parent = parent; + type->type_size = parent->type_size; + type->interfaces = NULL; + type->events = NULL; + + type->setup = NULL; + type->flush = NULL; + type->constructor = NULL; + type->destructor = NULL; + type->copy = NULL; + type->deep_copy = NULL; + type->compare = NULL; + type->load = NULL; + type->unload = NULL; + type->property_get = NULL; + type->property_set = NULL; + type->property_del = NULL; + type->properties_names_list_get = NULL; + type->child_count = NULL; + type->child_get = NULL; + type->child_set = NULL; + type->child_del = NULL; + type->child_insert_at = NULL; + type->child_find = NULL; + type->child_search = NULL; + type->child_sort = NULL; + type->child_iterator_get = NULL; + type->child_reversed_iterator_get = NULL; + type->child_sorted_iterator_get = NULL; + type->child_filtered_iterator_get = NULL; + type->to_string = NULL; + type->__extension_ptr0 = NULL; + type->__extension_ptr1 = NULL; + type->__extension_ptr2 = NULL; + type->__extension_ptr3 = NULL; + + if (type->type_size > sizeof(Eina_Model_Type)) + { + unsigned char *p = (unsigned char *)type; + p += sizeof(Eina_Model_Type); + memset(p, 0, type->type_size - sizeof(Eina_Model_Type)); + } + + return EINA_TRUE; +} + +EAPI Eina_Bool eina_model_type_subclass_check(const Eina_Model_Type *type, const Eina_Model_Type *self_or_parent) { EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); -- 2.7.4