eina_model: new events for load/unload.

Added the events: loaded and unloaded to notify eina_model_load() and
eina_model_unload() were called.

To be more specific, the interfaces used by EINA_MODEL_TYPE_MIXIN
(Eina_Model_Interface_Properties and Eina_Model_Interface_Children)
also do:
 * properties,loaded
 * properties,unloaded
 * children,loaded
 * children,unloaded



SVN revision: 68035
This commit is contained in:
Gustavo Sverzut Barbieri 2012-02-16 19:48:13 +00:00
parent f7787c0e26
commit 88d6b934aa
3 changed files with 262 additions and 9 deletions

View File

@ -534,6 +534,14 @@ EAPI void eina_model_xunref(Eina_Model *model,
* @li child,inserted: new child was added (eina_model_child_append() or eina_model_child_insert_at())
* @li child,set: child was replaced (eina_model_child_set())
* @li child,deleted: eina_model_child_del() was done.
* @li loaded: eina_model_load() was done.
* @li unloaded: eina_model_unload() was done.
*
* Mix-in interfaces may emit these:
* @li properties,loaded
* @li properties,unloaded
* @li children,loaded
* @li children,unloaded
*
* One can be notified of events with eina_model_event_callback_add().
*

View File

@ -86,6 +86,12 @@ static const char _eina_model_str_children_changed[] = "children,changed";
static const char _eina_model_str_child_inserted[] = "child,inserted";
static const char _eina_model_str_child_set[] = "child,set";
static const char _eina_model_str_child_del[] = "child,deleted";
static const char _eina_model_str_loaded[] = "loaded";
static const char _eina_model_str_unloaded[] = "unloaded";
static const char _eina_model_str_properties_loaded[] = "properties,loaded";
static const char _eina_model_str_properties_unloaded[] = "properties,unloaded";
static const char _eina_model_str_children_loaded[] = "children,loaded";
static const char _eina_model_str_children_unloaded[] = "children,unloaded";
#ifdef CRITICAL
#undef CRITICAL
@ -1992,6 +1998,8 @@ static const Eina_Model_Event_Description _eina_model_type_base_events[] = {
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_child_inserted, "u", "model child was inserted, child position is given."),
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_child_set, "u", "model child was set, child position is given."),
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_child_del, "u", "model child was deleted, child position is given."),
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_loaded, "", "model was loaded"),
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_unloaded, "", "model was unloaded"),
EINA_MODEL_EVENT_DESCRIPTION_SENTINEL
};
@ -2375,6 +2383,12 @@ static const Eina_Model_Type _EINA_MODEL_TYPE_MIXIN = {
};
#undef EINA_MODEL_TYPE_MIXIN_GET
/* Events for all Properties interface */
static const Eina_Model_Event_Description _eina_model_interface_properties_events[] = {
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_properties_loaded, "", "model properties were loaded"),
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_properties_unloaded, "", "model properties were unloaded"),
EINA_MODEL_EVENT_DESCRIPTION_SENTINEL
};
/* EINA_MODEL_INTERFACE_PROPERTIES_HASH ******************************/
@ -2536,7 +2550,7 @@ static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_HA
sizeof(Eina_Model_Interface_Properties),
_EINA_MODEL_INTERFACE_NAME_PROPERTIES,
NULL, /* no parent interfaces */
NULL, /* no extra events */
_eina_model_interface_properties_events,
_eina_model_interface_properties_hash_setup,
_eina_model_interface_properties_hash_flush,
_eina_model_interface_properties_hash_constructor,
@ -2686,7 +2700,7 @@ static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_ST
sizeof(Eina_Model_Interface_Properties),
_EINA_MODEL_INTERFACE_NAME_PROPERTIES,
NULL, /* no parent interfaces */
NULL, /* no extra events */
_eina_model_interface_properties_events,
_eina_model_interface_properties_struct_setup,
_eina_model_interface_properties_struct_flush,
_eina_model_interface_properties_struct_constructor,
@ -2708,6 +2722,13 @@ static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_ST
_eina_model_interface_properties_struct_names_list
};
/* Events for all Children interface */
static const Eina_Model_Event_Description _eina_model_interface_children_events[] = {
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_children_loaded, "", "model children were loaded"),
EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_children_unloaded, "", "model children were unloaded"),
EINA_MODEL_EVENT_DESCRIPTION_SENTINEL
};
/* EINA_MODEL_INTERFACE_CHILDREN_INARRAY ******************************/
#define EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model) \
@ -2864,7 +2885,7 @@ static const Eina_Model_Interface_Children _EINA_MODEL_INTERFACE_CHILDREN_INARRA
sizeof(Eina_Model_Interface_Children),
_EINA_MODEL_INTERFACE_NAME_CHILDREN,
NULL, /* no parent interfaces */
NULL, /* no extra events */
_eina_model_interface_children_events,
_eina_model_interface_children_inarray_setup,
_eina_model_interface_children_inarray_flush,
_eina_model_interface_children_inarray_constructor,
@ -3988,15 +4009,52 @@ eina_model_compare(const Eina_Model *a, const Eina_Model *b)
EAPI Eina_Bool
eina_model_load(Eina_Model *model)
{
Eina_Bool ret;
EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE);
EINA_MODEL_TYPE_CALL_OPTIONAL_RETURN(model, load, EINA_TRUE);
eina_error_set(0);
if (model->desc->ops.type.load)
{
ret = model->desc->ops.type.load(model);
if (ret)
_eina_model_event_callback_call(model, _eina_model_str_loaded, NULL);
}
else
{
eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING);
ret = EINA_FALSE;
ERR("Method load() not implemented for model %p (%s)",
model, model->desc->cache.types[0]->name);
}
return ret;
}
EAPI Eina_Bool
eina_model_unload(Eina_Model *model)
{
Eina_Bool ret;
EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE);
EINA_MODEL_TYPE_CALL_OPTIONAL_RETURN(model, unload, EINA_TRUE);
eina_error_set(0);
if (model->desc->ops.type.unload)
{
ret = model->desc->ops.type.unload(model);
if (ret)
_eina_model_event_callback_call
(model, _eina_model_str_unloaded, NULL);
}
else
{
eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING);
ret = EINA_FALSE;
ERR("Method unload() not implemented for model %p (%s)",
model, model->desc->cache.types[0]->name);
}
return ret;
}
EAPI Eina_Bool
@ -5062,26 +5120,40 @@ EAPI Eina_Bool
eina_model_interface_properties_load(const Eina_Model_Interface *iface, Eina_Model *model)
{
Eina_Bool (*load)(Eina_Model *);
Eina_Bool ret;
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
load = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, load));
EINA_SAFETY_ON_NULL_RETURN_VAL(load, EINA_FALSE);
return load(model);
ret = load(model);
if (ret)
_eina_model_event_callback_call
(model, _eina_model_str_properties_loaded, NULL);
return ret;
}
EAPI Eina_Bool
eina_model_interface_properties_unload(const Eina_Model_Interface *iface, Eina_Model *model)
{
Eina_Bool (*unload)(Eina_Model *);
Eina_Bool ret;
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
unload = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, unload));
EINA_SAFETY_ON_NULL_RETURN_VAL(unload, EINA_FALSE);
return unload(model);
ret = unload(model);
if (ret)
_eina_model_event_callback_call
(model, _eina_model_str_properties_unloaded, NULL);
return ret;
}
EAPI Eina_Bool
@ -5166,26 +5238,40 @@ EAPI Eina_Bool
eina_model_interface_children_load(const Eina_Model_Interface *iface, Eina_Model *model)
{
Eina_Bool (*load)(Eina_Model *);
Eina_Bool ret;
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
load = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, load));
EINA_SAFETY_ON_NULL_RETURN_VAL(load, EINA_FALSE);
return load(model);
ret = load(model);
if (ret)
_eina_model_event_callback_call
(model, _eina_model_str_children_loaded, NULL);
return ret;
}
EAPI Eina_Bool
eina_model_interface_children_unload(const Eina_Model_Interface *iface, Eina_Model *model)
{
Eina_Bool (*unload)(Eina_Model *);
Eina_Bool ret;
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
unload = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, unload));
EINA_SAFETY_ON_NULL_RETURN_VAL(unload, EINA_FALSE);
return unload(model);
ret = unload(model);
if (ret)
_eina_model_event_callback_call
(model, _eina_model_str_children_unloaded, NULL);
return ret;
}
EAPI int

View File

@ -1112,6 +1112,164 @@ START_TEST(eina_model_test_inheritance)
}
END_TEST
static Eina_Bool
_myproperties_load(Eina_Model *m)
{
Eina_Value v;
Eina_Bool ret;
int count;
if (!eina_model_property_get(m, "load_count", &v))
return EINA_FALSE;
eina_value_get(&v, &count);
count++;
eina_value_set(&v, count);
ret = eina_model_property_set(m, "load_count", &v);
eina_value_flush(&v);
return ret;
}
static Eina_Bool
_myproperties_unload(Eina_Model *m)
{
Eina_Value v;
Eina_Bool ret;
int count;
if (!eina_model_property_get(m, "load_count", &v))
return EINA_FALSE;
eina_value_get(&v, &count);
count--;
eina_value_set(&v, count);
ret = eina_model_property_set(m, "load_count", &v);
eina_value_flush(&v);
return ret;
}
static Eina_Bool
_mychildren_load(Eina_Model *m)
{
Eina_Model *c = eina_model_new(EINA_MODEL_TYPE_GENERIC);
int ret = eina_model_child_append(m, c);
eina_model_unref(c);
return ret >= 0;
}
static Eina_Bool
_mychildren_unload(Eina_Model *m)
{
int count = eina_model_child_count(m);
EINA_SAFETY_ON_FALSE_RETURN_VAL(count > 0, EINA_FALSE);
return eina_model_child_del(m, count - 1);
}
START_TEST(eina_model_test_ifaces_load_unload)
{
unsigned int count_loaded = 0, count_unloaded = 0;
unsigned int count_ploaded = 0, count_punloaded = 0;
unsigned int count_cloaded = 0, count_cunloaded = 0;
static Eina_Model_Interface_Properties piface;
static Eina_Model_Interface_Children ciface;
static const Eina_Model_Interface *piface_parents[2] = {NULL, NULL};
static const Eina_Model_Interface *ciface_parents[2] = {NULL, NULL};
static const Eina_Model_Interface *type_ifaces[3] = {
&piface.base, &ciface.base, NULL
};
static Eina_Model_Type type;
Eina_Model *m;
Eina_Value v;
int count;
eina_init();
/* do after eina_init() otherwise interfaces are not set */
piface_parents[0] = EINA_MODEL_INTERFACE_PROPERTIES_HASH;
ciface_parents[0] = EINA_MODEL_INTERFACE_CHILDREN_INARRAY;
memset(&piface, 0, sizeof(piface));
piface.base.version = EINA_MODEL_INTERFACE_VERSION;
piface.base.interface_size = sizeof(piface);
piface.base.name = EINA_MODEL_INTERFACE_NAME_PROPERTIES;
piface.base.interfaces = piface_parents;
piface.load = _myproperties_load;
piface.unload = _myproperties_unload;
memset(&ciface, 0, sizeof(ciface));
ciface.base.version = EINA_MODEL_INTERFACE_VERSION;
ciface.base.interface_size = sizeof(ciface);
ciface.base.name = EINA_MODEL_INTERFACE_NAME_CHILDREN;
ciface.base.interfaces = ciface_parents;
ciface.load = _mychildren_load;
ciface.unload = _mychildren_unload;
type.version = EINA_MODEL_TYPE_VERSION;
type.private_size = 0;
type.name = "MyType";
eina_model_type_subclass_setup(&type, EINA_MODEL_TYPE_GENERIC);
type.interfaces = type_ifaces;
m = eina_model_new(&type);
fail_unless(m != NULL);
eina_model_event_callback_add
(m, "loaded", _eina_test_model_cb_count, &count_loaded);
eina_model_event_callback_add
(m, "unloaded", _eina_test_model_cb_count, &count_unloaded);
eina_model_event_callback_add
(m, "properties,loaded", _eina_test_model_cb_count, &count_ploaded);
eina_model_event_callback_add
(m, "properties,unloaded", _eina_test_model_cb_count, &count_punloaded);
eina_model_event_callback_add
(m, "children,loaded", _eina_test_model_cb_count, &count_cloaded);
eina_model_event_callback_add
(m, "children,unloaded", _eina_test_model_cb_count, &count_cunloaded);
fail_unless(eina_value_setup(&v, EINA_VALUE_TYPE_INT));
fail_unless(eina_value_set(&v, 0));
fail_unless(eina_model_property_set(m, "load_count", &v));
eina_value_flush(&v);
fail_unless(eina_model_load(m));
fail_unless(eina_model_load(m));
fail_unless(eina_model_load(m));
/* each load increments one for load_count property */
fail_unless(eina_model_property_get(m, "load_count", &v));
fail_unless(eina_value_pget(&v, &count));
ck_assert_int_eq(count, 3);
eina_value_flush(&v);
/* each load adds one child */
ck_assert_int_eq(eina_model_child_count(m), 3);
fail_unless(eina_model_unload(m));
fail_unless(eina_model_unload(m));
fail_unless(eina_model_unload(m));
ck_assert_int_eq(count_loaded, 3);
ck_assert_int_eq(count_unloaded, 3);
ck_assert_int_eq(count_ploaded, 3);
ck_assert_int_eq(count_punloaded, 3);
ck_assert_int_eq(count_cloaded, 3);
ck_assert_int_eq(count_cunloaded, 3);
ck_assert_int_eq(eina_model_refcount(m), 1);
eina_model_unref(m);
eina_shutdown();
}
END_TEST
void
eina_test_model(TCase *tc)
{
@ -1126,4 +1284,5 @@ eina_test_model(TCase *tc)
tcase_add_test(tc, eina_model_test_struct);
tcase_add_test(tc, eina_model_test_struct_complex_members);
tcase_add_test(tc, eina_model_test_inheritance);
tcase_add_test(tc, eina_model_test_ifaces_load_unload);
}