forked from enlightenment/efl
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:
parent
f7787c0e26
commit
88d6b934aa
|
@ -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().
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue