From 73b595df2fc8c2a3d77a07b9c74c4a549e362834 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Tue, 24 Jan 2012 22:17:57 +0000 Subject: [PATCH] more efficient model properties based on struct. this is a killer, should be very efficient in memory and speed to set/get items: instead of a hash of properties, keep them in a C struct! The constraint is that properties have fixed types defined at compile time and cannot be deleted, but this is expected in many cases (ie: esql rows). SVN revision: 67517 --- legacy/eina/src/include/eina_model.h | 77 ++++++ legacy/eina/src/lib/eina_model.c | 303 +++++++++++++++++++++++- legacy/eina/src/tests/eina_test_model.c | 141 ++++++++++- 3 files changed, 512 insertions(+), 9 deletions(-) diff --git a/legacy/eina/src/include/eina_model.h b/legacy/eina/src/include/eina_model.h index 958b31cbcd..640e6971d5 100644 --- a/legacy/eina/src/include/eina_model.h +++ b/legacy/eina/src/include/eina_model.h @@ -714,10 +714,31 @@ EAPI extern const Eina_Model_Type *EINA_MODEL_TYPE_MIXIN; * Should be generic enough to hold lots of items with runtime * configurable properties of any type. * + * @see #EINA_MODEL_TYPE_STRUCT + * * @since 1.2 */ EAPI extern const Eina_Model_Type *EINA_MODEL_TYPE_GENERIC; +/** + * @var EINA_MODEL_TYPE_STRUCT + * + * Subclass of #EINA_MODEL_TYPE_MIXIN that uses + * #EINA_MODEL_INTERFACE_PROPERTIES_STRUCT and + * #EINA_MODEL_INTERFACE_CHILDREN_INARRAY. + * + * Should be struct enough to hold lots of items with compile time + * configurable properties of any type. + * + * @see #EINA_MODEL_TYPE_GENERIC + * + * @since 1.2 + */ +EAPI extern const Eina_Model_Type *EINA_MODEL_TYPE_STRUCT; + +EAPI Eina_Model *eina_model_struct_new(const Eina_Value_Struct_Desc *desc) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT EINA_MALLOC; + + /** * @var EINA_MODEL_INTERFACE_NAME_PROPERTIES * @@ -775,10 +796,66 @@ EAPI Eina_List *eina_model_interface_properties_names_list_get(const Eina_Model_ * hash data type. For huge number of elements it's better to * use custom implementation instead. * + * @see EINA_MODEL_INTERFACE_PROPERTIES_STRUCT + * * @since 1.2 */ EAPI extern const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_HASH; +/** + * @var EINA_MODEL_INTERFACE_PROPERTIES_STRUCT + * + * Implements #Eina_Model_Interface_Properties + * (#EINA_MODEL_INTERFACE_NAME_PROPERTIES) using #Eina_Value_Struct. + * + * The interface private data is #Eina_Value of type + * #EINA_VALUE_TYPE_STRUCT. Properties will be accessed using + * #Eina_Value_Struct::desc information that can be set by types such + * as #EINA_MODEL_TYPE_STRUCT + * + * @see EINA_MODEL_INTERFACE_PROPERTIES_HASH + * + * @since 1.2 + */ +EAPI extern const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_STRUCT; + +/** + * @brief Configure the internal properties of model implementing #EINA_MODEL_INTERFACE_PROPERTIES_STRUCT. + * + * @param model The model instance to configure. + * @param desc The structure description to use. + * @param memory If not @c NULL, will be adopted by model. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This will setup the internal pointers so that the given @a desc is + * used to manage the properties of this struct. + * + * If a given memory is provided, it will be adopted (not copied!), + * being free'd when the model is gone. + * + * @see #EINA_VALUE_TYPE_STRUCT + * + * @since 1.2 + */ +EAPI Eina_Bool eina_model_struct_set(Eina_Model *model, + const Eina_Value_Struct_Desc *desc, + void *memory) EINA_ARG_NONNULL(1, 2); +/** + * @brief Get the internal properties of model implementing #EINA_MODEL_INTERFACE_PROPERTIES_STRUCT. + * + * @param model the model instance. + * @param p_desc where to return the structure description in use. + * @param p_memory where to return the structure memory in use. + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * No copies are made! The memory and description may be invalidaded + * by calls to eina_model_struct_set() or eina_model_del(). + * + * @since 1.2 + */ +EAPI Eina_Bool eina_model_struct_get(const Eina_Model *model, + const Eina_Value_Struct_Desc **p_desc, + void **p_memory) EINA_ARG_NONNULL(1, 2); /** * @var EINA_MODEL_INTERFACE_NAME_CHILDREN diff --git a/legacy/eina/src/lib/eina_model.c b/legacy/eina/src/lib/eina_model.c index d9452cb1a7..fc37203eb0 100644 --- a/legacy/eina/src/lib/eina_model.c +++ b/legacy/eina/src/lib/eina_model.c @@ -2493,13 +2493,189 @@ static const Eina_Model_Interface _EINA_MODEL_INTERFACE_PROPERTIES_HASH = { &_EINA_MODEL_INTERFACE_PROPERTIES_HASH_VALUE }; -/* TODO: properties using Eina_Value_Type_Struct - * - * Would be bit more cumbersome to do, as the user still needs to - * derivate the interface to specify the Eina_Value_Struct_Desc, but - * given this struct everything should be easy to do (query it for - * valid properties and their type, covert type if needed). - */ +/* EINA_MODEL_INTERFACE_PROPERTIES_STRUCT ******************************/ + +static Eina_Value_Struct * +_eina_model_interface_properties_struct_private_get(const Eina_Model *model) +{ + Eina_Value *val = eina_model_interface_private_data_get + (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); + return val->value.ptr; +} + +#define EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model) \ + Eina_Value_Struct *priv = \ + _eina_model_interface_properties_struct_private_get(model) + +static Eina_Bool +_eina_model_interface_properties_struct_setup(Eina_Model *model) +{ + Eina_Value *val = eina_model_interface_private_data_get + (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); + + DBG("setup interface properties (struct) at %p model %p (%s)", + val, model, model->desc->cache.types[0]->name); + + return eina_value_setup(val, EINA_VALUE_TYPE_STRUCT); +} + +static Eina_Bool +_eina_model_interface_properties_struct_flush(Eina_Model *model) +{ + Eina_Value *val = eina_model_interface_private_data_get + (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); + + DBG("flush interface properties (struct) at %p model %p (%s)", + val, model, model->desc->cache.types[0]->name); + + if (val->type) + { + ERR("interface properties flushed with values! val=%p, model %p (%s)", + val, model, model->desc->cache.types[0]->name); + eina_value_flush(val); + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_model_interface_properties_struct_constructor(Eina_Model *model) +{ + EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model); + + DBG("construct interface properties (struct) at %p model %p (%s)", + priv, model, model->desc->cache.types[0]->name); + + return EINA_TRUE; +} + +static Eina_Bool +_eina_model_interface_properties_struct_destructor(Eina_Model *model) +{ + Eina_Value *val = eina_model_interface_private_data_get + (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); + + DBG("destroy interface properties (struct) at %p model %p (%s)", + val, model, model->desc->cache.types[0]->name); + + eina_value_flush(val); + val->type = NULL; + + return EINA_TRUE; +} + +static Eina_Bool +_eina_model_interface_properties_struct_get(const Eina_Model *model, const char *name, Eina_Value *val) +{ + EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model); + const Eina_Value_Struct_Member *m; + const void *p; + + /* highly optimized, but duplicates code from eina_inline_value.x */ + + m = eina_value_struct_member_find(priv, name); + EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); + + p = eina_value_struct_member_memory_get(priv, m); + EINA_SAFETY_ON_NULL_RETURN_VAL(p, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_setup(val, m->type), EINA_FALSE); + EINA_SAFETY_ON_FALSE_GOTO(eina_value_pset(val, p), error); + return EINA_TRUE; + + error: + eina_value_flush(val); + return EINA_FALSE; +} + +static Eina_Bool +_eina_model_interface_properties_struct_set(Eina_Model *model, const char *name, const Eina_Value *val) +{ + EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model); + const Eina_Value_Struct_Member *m; + const void *src; + void *dst; + + /* highly optimized, but duplicates code from eina_inline_value.x */ + + m = eina_value_struct_member_find(priv, name); + EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(val->type == m->type, EINA_FALSE); + + dst = eina_value_struct_member_memory_get(priv, m); + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE); + src = eina_value_memory_get(val); + EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); + + eina_value_type_flush(m->type, dst); + if (!eina_value_type_setup(m->type, dst)) goto error_setup; + if (!eina_value_type_pset(m->type, dst, src)) goto error_set; + return EINA_TRUE; + + error_set: + eina_value_type_flush(m->type, dst); + error_setup: + return EINA_FALSE; +} + +static Eina_Bool +_eina_model_interface_properties_struct_del(Eina_Model *model __UNUSED__, const char *name __UNUSED__) +{ + return EINA_FALSE; /* not allowed */ +} + +static Eina_List * +_eina_model_interface_properties_struct_names_list(const Eina_Model *model) +{ + EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model); + const Eina_Value_Struct_Member *itr; + Eina_List *list = NULL; + + EINA_SAFETY_ON_NULL_RETURN_VAL(priv, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(priv->desc, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(priv->desc->members, NULL); + + itr = priv->desc->members; + if (priv->desc->member_count) + { + const Eina_Value_Struct_Member *end = itr + priv->desc->member_count; + for (; itr < end; itr++) + list = eina_list_append(list, eina_stringshare_add(itr->name)); + } + else + { + for (; itr->name != NULL; itr++) + list = eina_list_append(list, eina_stringshare_add(itr->name)); + } + + return list; +} +#undef EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET + +static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_VALUE = { + EINA_MODEL_INTERFACE_PROPERTIES_VERSION, + NULL, /* no compare */ + NULL, /* no load */ + NULL, /* no unload */ + _eina_model_interface_properties_struct_get, + _eina_model_interface_properties_struct_set, + _eina_model_interface_properties_struct_del, + _eina_model_interface_properties_struct_names_list +}; + +static const Eina_Model_Interface _EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = { + EINA_MODEL_INTERFACE_VERSION, + sizeof(Eina_Value), + _EINA_MODEL_INTERFACE_NAME_PROPERTIES, + NULL, /* no parent interfaces */ + NULL, /* no extra events */ + _eina_model_interface_properties_struct_setup, + _eina_model_interface_properties_struct_flush, + _eina_model_interface_properties_struct_constructor, + _eina_model_interface_properties_struct_destructor, + NULL, + NULL, + &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_VALUE +}; /* EINA_MODEL_INTERFACE_CHILDREN_INARRAY ******************************/ @@ -2720,6 +2896,50 @@ static const Eina_Model_Type _EINA_MODEL_TYPE_GENERIC = { NULL /* inherit from mix-in */ }; +/* EINA_MODEL_TYPE_STRUCT ********************************************/ + +static const Eina_Model_Interface *_EINA_MODEL_TYPE_STRUCT_IFACES[] = { + &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT, + &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY, + NULL +}; + +static const Eina_Model_Type _EINA_MODEL_TYPE_STRUCT = { + EINA_MODEL_TYPE_VERSION, + 0, + "Eina_Model_Type_Struct", + &_EINA_MODEL_TYPE_MIXIN, + _EINA_MODEL_TYPE_STRUCT_IFACES, + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL, /* inherit from mix-in */ + NULL /* inherit from mix-in */ +}; + /** */ @@ -2799,8 +3019,10 @@ eina_model_init(void) EINA_MODEL_TYPE_BASE = &_EINA_MODEL_TYPE_BASE; EINA_MODEL_TYPE_MIXIN = &_EINA_MODEL_TYPE_MIXIN; EINA_MODEL_TYPE_GENERIC = &_EINA_MODEL_TYPE_GENERIC; + EINA_MODEL_TYPE_STRUCT = &_EINA_MODEL_TYPE_STRUCT; EINA_MODEL_INTERFACE_PROPERTIES_HASH = &_EINA_MODEL_INTERFACE_PROPERTIES_HASH; + EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT; EINA_MODEL_INTERFACE_CHILDREN_INARRAY = &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY; @@ -2881,8 +3103,10 @@ EAPI Eina_Error EINA_ERROR_MODEL_METHOD_MISSING = 0; EAPI const Eina_Model_Type *EINA_MODEL_TYPE_BASE = NULL; EAPI const Eina_Model_Type *EINA_MODEL_TYPE_MIXIN = NULL; EAPI const Eina_Model_Type *EINA_MODEL_TYPE_GENERIC = NULL; +EAPI const Eina_Model_Type *EINA_MODEL_TYPE_STRUCT = NULL; EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_HASH = NULL; +EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = NULL; EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_CHILDREN_INARRAY = NULL; EAPI const char *EINA_MODEL_INTERFACE_NAME_PROPERTIES = "Eina_Model_Interface_Properties"; @@ -4846,3 +5070,68 @@ eina_model_interface_children_sort(const Eina_Model_Interface *iface, Eina_Model EINA_SAFETY_ON_NULL_RETURN(sort); return sort(model, compare); } + +static Eina_Bool +_eina_model_struct_set(Eina_Model *m, const Eina_Value_Struct_Desc *desc, void *memory) +{ + Eina_Value_Struct st = {desc, memory}; + Eina_Value *val = eina_model_interface_private_data_get + (m, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); + return eina_value_pset(val, &st); +} + +EAPI Eina_Model * +eina_model_struct_new(const Eina_Value_Struct_Desc *desc) +{ + Eina_Model *m; + + EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL + (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, NULL); + + m = eina_model_new(EINA_MODEL_TYPE_STRUCT); + EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); + + EINA_SAFETY_ON_FALSE_GOTO(_eina_model_struct_set(m, desc, NULL), error); + return m; + + error: + eina_model_del(m); + return NULL; +} + +EAPI Eina_Bool +eina_model_struct_set(Eina_Model *model, const Eina_Value_Struct_Desc *desc, void *memory) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(desc, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL + (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, EINA_FALSE); + EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL + (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT, model, EINA_FALSE); + + return _eina_model_struct_set(model, desc, memory); +} + +EAPI Eina_Bool +eina_model_struct_get(const Eina_Model *model, const Eina_Value_Struct_Desc **p_desc, void **p_memory) +{ + const Eina_Value *val; + Eina_Value_Struct st; + + EINA_SAFETY_ON_NULL_RETURN_VAL(p_desc, EINA_FALSE); + + *p_desc = NULL; + if (p_memory) *p_memory = NULL; + + EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL + (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT, model, EINA_FALSE); + + val = eina_model_interface_private_data_get + (model, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); + + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_pget(val, &st), EINA_FALSE); + + *p_desc = st.desc; + if (p_memory) *p_memory = st.memory; + return EINA_FALSE; +} diff --git a/legacy/eina/src/tests/eina_test_model.c b/legacy/eina/src/tests/eina_test_model.c index 90b0bb3b0c..0eb516d5af 100644 --- a/legacy/eina/src/tests/eina_test_model.c +++ b/legacy/eina/src/tests/eina_test_model.c @@ -50,6 +50,30 @@ _eina_test_model_check_safety_null(const Eina_Log_Domain *d, Eina_Log_Level leve eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args); } +static void +_eina_test_model_check_safety_false(const Eina_Log_Domain *d, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, void *data, va_list args) +{ + Eina_Bool *ck = data; + + if ((level == EINA_LOG_LEVEL_ERR) && (strcmp(fmt, "%s") == 0)) + { + const char *str; + va_list cp_args; + + va_copy(cp_args, args); + str = va_arg(cp_args, const char *); + va_end(cp_args); + if (eina_str_has_prefix(str, "safety check failed: ") && + eina_str_has_suffix(str, " is false")) + { + *ck = EINA_TRUE; + return; + } + } + *ck = EINA_FALSE; + eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args); +} + static void _eina_test_model_cb_count(void *data, Eina_Model *model, const Eina_Model_Event_Description *desc, void *event_info) { @@ -213,7 +237,6 @@ START_TEST(eina_model_test_children) char *s; int i; - printf("eina_model_test_children: BEGIN\n"); eina_init(); m = eina_model_new(EINA_MODEL_TYPE_GENERIC); @@ -321,7 +344,6 @@ START_TEST(eina_model_test_children) ck_assert_int_eq(count_cdel, 2); eina_shutdown(); - printf("eina_model_test_children: END\n"); } END_TEST @@ -717,6 +739,120 @@ START_TEST(eina_model_test_child_filtered_iterator) } END_TEST +START_TEST(eina_model_test_struct) +{ + unsigned int count_del = 0, count_pset = 0, count_pdel = 0; + Eina_Model *m; + struct myst { + int i; + char c; + }; + const Eina_Value_Struct_Member myst_members[] = { + {"i", EINA_VALUE_TYPE_INT, 0}, + {"c", EINA_VALUE_TYPE_CHAR, 4}, + {NULL, NULL, 0} + }; + const Eina_Value_Struct_Desc myst_desc = { + EINA_VALUE_STRUCT_DESC_VERSION, + NULL, myst_members, 2, sizeof(struct myst) + }; + Eina_Value inv, outv; + int i; + char c; + Eina_List *lst; + Eina_Bool ck; + + eina_init(); + + m = eina_model_struct_new(&myst_desc); + fail_unless(m != NULL); + + eina_model_event_callback_add + (m, "deleted", _eina_test_model_cb_count, &count_del); + eina_model_event_callback_add + (m, "property,set", _eina_test_model_cb_count, &count_pset); + eina_model_event_callback_add + (m, "property,deleted", _eina_test_model_cb_count, &count_pdel); + + fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_set(&inv, 1234)); + fail_unless(eina_value_get(&inv, &i)); + ck_assert_int_eq(i, 1234); + fail_unless(eina_model_property_set(m, "i", &inv)); + + eina_value_flush(&inv); + fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_set(&inv, 33)); + fail_unless(eina_value_get(&inv, &c)); + ck_assert_int_eq(c, 33); + fail_unless(eina_model_property_set(m, "c", &inv)); + + lst = eina_model_properties_names_list_get(m); + ck_assert_int_eq(eina_list_count(lst), 2); + + lst = eina_list_sort(lst, 0, EINA_COMPARE_CB(strcmp)); + ck_assert_str_eq("c", eina_list_nth(lst, 0)); + ck_assert_str_eq("i", eina_list_nth(lst, 1)); + + eina_model_properties_names_list_free(lst); + + fail_unless(eina_model_property_get(m, "i", &outv)); + fail_unless(outv.type == EINA_VALUE_TYPE_INT); + fail_unless(eina_value_get(&outv, &i)); + ck_assert_int_eq(i, 1234); + eina_value_flush(&outv); + + fail_unless(eina_model_property_get(m, "c", &outv)); + fail_unless(outv.type == EINA_VALUE_TYPE_CHAR); + fail_unless(eina_value_get(&outv, &c)); + ck_assert_int_eq(c, 33); + eina_value_flush(&outv); + + eina_value_flush(&inv); + + /* negative test (check safety was displayed by using print_cb) */ + eina_log_print_cb_set(_eina_test_model_check_safety_null, &ck); + + ck = EINA_FALSE; + fail_if(eina_model_property_get(m, "non-existent", &outv)); + fail_unless(ck == EINA_TRUE); + + ck = EINA_FALSE; + fail_if(eina_model_property_get(m, NULL, &outv)); + fail_unless(ck == EINA_TRUE); + + fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_STRING)); + fail_unless(eina_value_set(&inv, "hello world")); + + eina_log_print_cb_set(_eina_test_model_check_safety_false, &ck); + + ck = EINA_FALSE; + fail_if(eina_model_property_set(m, "i", &inv)); + fail_unless(ck == EINA_TRUE); + + ck = EINA_FALSE; + fail_if(eina_model_property_set(m, "c", &inv)); + fail_unless(ck == EINA_TRUE); + + /* revert print_cb to default */ + eina_log_print_cb_set(eina_log_print_cb_stderr, NULL); + + fail_if(eina_model_property_del(m, "value")); + fail_if(eina_model_property_del(m, "i")); + fail_if(eina_model_property_del(m, "c")); + + eina_value_flush(&inv); + + ck_assert_int_eq(eina_model_refcount(m), 1); + + eina_model_unref(m); + ck_assert_int_eq(count_del, 1); + ck_assert_int_eq(count_pset, 2); + ck_assert_int_eq(count_pdel, 0); + eina_shutdown(); +} +END_TEST + void eina_test_model(TCase *tc) { @@ -728,4 +864,5 @@ eina_test_model(TCase *tc) tcase_add_test(tc, eina_model_test_child_reversed_iterator); tcase_add_test(tc, eina_model_test_child_sorted_iterator); tcase_add_test(tc, eina_model_test_child_filtered_iterator); + tcase_add_test(tc, eina_model_test_struct); }