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
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
};
};
#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 ******************************/
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,
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,
_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) \
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,
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
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
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
}
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)
{
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);
}