forked from enlightenment/efl
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
This commit is contained in:
parent
19a47340a5
commit
73b595df2f
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue