forked from enlightenment/efl
Eina model: Fix issues with interface inheritance.
The ptr comparison had issues. Order of interface overrides was wrong. SVN revision: 67915
This commit is contained in:
parent
478d4c5cce
commit
b1bb770688
|
@ -3487,23 +3487,17 @@ EAPI const Eina_Model_Interface *
|
||||||
eina_model_interface_get(const Eina_Model *model, const char *name)
|
eina_model_interface_get(const Eina_Model *model, const char *name)
|
||||||
{
|
{
|
||||||
const Eina_Model_Description *desc;
|
const Eina_Model_Description *desc;
|
||||||
const Eina_Model_Interface **itr, **itr_end;
|
const Eina_Model_Interface **itr, **itr_first;
|
||||||
|
|
||||||
EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL);
|
EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||||
|
|
||||||
desc = model->desc;
|
desc = model->desc;
|
||||||
itr = desc->cache.ifaces;
|
itr_first = desc->cache.ifaces;
|
||||||
itr_end = itr + desc->total.ifaces;
|
itr = itr_first + desc->total.ifaces - 1;
|
||||||
|
|
||||||
/* try pointer comparison for the speed aware users */
|
|
||||||
for (; itr < itr_end; itr++)
|
|
||||||
if ((*itr)->name == name)
|
|
||||||
return *itr;
|
|
||||||
|
|
||||||
/* fallback to strcmp if user is lazy about speed */
|
/* fallback to strcmp if user is lazy about speed */
|
||||||
itr = desc->cache.ifaces;
|
for (; itr >= itr_first; itr--)
|
||||||
for (; itr < itr_end; itr++)
|
|
||||||
if (strcmp((*itr)->name, name) == 0)
|
if (strcmp((*itr)->name, name) == 0)
|
||||||
return *itr;
|
return *itr;
|
||||||
|
|
||||||
|
@ -4798,7 +4792,7 @@ eina_model_type_subclass_check(const Eina_Model_Type *type, const Eina_Model_Typ
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const Eina_Model_Interface *
|
static inline const Eina_Model_Interface *
|
||||||
_eina_model_type_interface_get(const Eina_Model_Type *type, const char *name, Eina_Bool ptr_cmp)
|
_eina_model_type_interface_get(const Eina_Model_Type *type, const char *name, Eina_Bool ptr_cmp __UNUSED__)
|
||||||
{
|
{
|
||||||
const Eina_Model_Interface **itr;
|
const Eina_Model_Interface **itr;
|
||||||
|
|
||||||
|
@ -4808,15 +4802,8 @@ _eina_model_type_interface_get(const Eina_Model_Type *type, const char *name, Ei
|
||||||
if (!type->interfaces)
|
if (!type->interfaces)
|
||||||
return _eina_model_type_interface_get(type->parent, name, ptr_cmp);
|
return _eina_model_type_interface_get(type->parent, name, ptr_cmp);
|
||||||
|
|
||||||
if (ptr_cmp)
|
|
||||||
{
|
{
|
||||||
for (itr = type->interfaces; itr != NULL; itr++)
|
for (itr = type->interfaces ; itr != NULL ; itr++)
|
||||||
if ((*itr)->name == name)
|
|
||||||
return *itr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (itr = type->interfaces; itr != NULL; itr++)
|
|
||||||
if (strcmp((*itr)->name, name) == 0)
|
if (strcmp((*itr)->name, name) == 0)
|
||||||
return *itr;
|
return *itr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -967,6 +967,139 @@ START_TEST(eina_model_test_struct_complex_members)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
typedef struct _Animal_Type
|
||||||
|
{
|
||||||
|
Eina_Model_Type parent_class;
|
||||||
|
void (*eat)(Eina_Model *mdl);
|
||||||
|
} Animal_Type;
|
||||||
|
|
||||||
|
typedef struct _Human_Type
|
||||||
|
{
|
||||||
|
Animal_Type parent_class;
|
||||||
|
void (*talk)(Eina_Model *mdl);
|
||||||
|
} Human_Type;
|
||||||
|
|
||||||
|
typedef struct _Pooper_Interface
|
||||||
|
{
|
||||||
|
Eina_Model_Interface base_interface;
|
||||||
|
void (*poop)(Eina_Model *mdl);
|
||||||
|
} Pooper_Interface;
|
||||||
|
|
||||||
|
#define ANIMAL_TYPE(x) ((Animal_Type *) x)
|
||||||
|
#define HUMAN_TYPE(x) ((Human_Type *) x)
|
||||||
|
#define POOPER_IFACE(x) ((Pooper_Interface *) x)
|
||||||
|
#define POOPER_IFACE_NAME "Pooper_Interace"
|
||||||
|
|
||||||
|
#define INHER_CB_COUNT(prefix) \
|
||||||
|
static int prefix ## _count = 0; \
|
||||||
|
static void \
|
||||||
|
prefix (Eina_Model *mdl) \
|
||||||
|
{ \
|
||||||
|
(void) mdl; \
|
||||||
|
(prefix ## _count)++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
animal_eat(Eina_Model *mdl)
|
||||||
|
{
|
||||||
|
void (*pf)(Eina_Model *mdl);
|
||||||
|
pf = eina_model_method_resolve(mdl, Animal_Type, eat);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(pf);
|
||||||
|
pf(mdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pooper_poop(Eina_Model *mdl)
|
||||||
|
{
|
||||||
|
const Eina_Model_Interface *iface = NULL;
|
||||||
|
iface = eina_model_interface_get(mdl, POOPER_IFACE_NAME);
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(iface);
|
||||||
|
|
||||||
|
void (*pf)(Eina_Model *);
|
||||||
|
|
||||||
|
pf = eina_model_interface_method_resolve(iface, mdl, Pooper_Interface, poop);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(pf);
|
||||||
|
pf(mdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
INHER_CB_COUNT(_animal_poop);
|
||||||
|
INHER_CB_COUNT(_human_poop);
|
||||||
|
INHER_CB_COUNT(_animal_eat);
|
||||||
|
INHER_CB_COUNT(_human_eat);
|
||||||
|
|
||||||
|
START_TEST(eina_model_test_inheritance)
|
||||||
|
{
|
||||||
|
eina_init();
|
||||||
|
|
||||||
|
Pooper_Interface _ANIMAL_POOPER_IFACE;
|
||||||
|
Eina_Model_Interface *ANIMAL_POOPER_IFACE = (Eina_Model_Interface *) &_ANIMAL_POOPER_IFACE;
|
||||||
|
memset(&_ANIMAL_POOPER_IFACE, 0, sizeof(_ANIMAL_POOPER_IFACE));
|
||||||
|
ANIMAL_POOPER_IFACE->version = EINA_MODEL_INTERFACE_VERSION;
|
||||||
|
ANIMAL_POOPER_IFACE->interface_size = sizeof(Pooper_Interface);
|
||||||
|
ANIMAL_POOPER_IFACE->name = POOPER_IFACE_NAME;
|
||||||
|
POOPER_IFACE(ANIMAL_POOPER_IFACE)->poop = _animal_poop;
|
||||||
|
|
||||||
|
Pooper_Interface _HUMAN_POOPER_IFACE;
|
||||||
|
Eina_Model_Interface *HUMAN_POOPER_IFACE = (Eina_Model_Interface *) &_HUMAN_POOPER_IFACE;
|
||||||
|
memset(&_HUMAN_POOPER_IFACE, 0, sizeof(_HUMAN_POOPER_IFACE));
|
||||||
|
HUMAN_POOPER_IFACE->version = EINA_MODEL_INTERFACE_VERSION;
|
||||||
|
HUMAN_POOPER_IFACE->interface_size = sizeof(Pooper_Interface);
|
||||||
|
HUMAN_POOPER_IFACE->name = POOPER_IFACE_NAME;
|
||||||
|
POOPER_IFACE(HUMAN_POOPER_IFACE)->poop = _human_poop;
|
||||||
|
|
||||||
|
const Eina_Model_Interface *ANIMAL_IFACES[] = {ANIMAL_POOPER_IFACE, NULL};
|
||||||
|
const Eina_Model_Interface *HUMAN_IFACES[] = {HUMAN_POOPER_IFACE, NULL};
|
||||||
|
|
||||||
|
/* Init Animal Type */
|
||||||
|
Animal_Type _ANIMAL_TYPE;
|
||||||
|
Eina_Model_Type *ANIMAL_TYPE = (Eina_Model_Type *) &_ANIMAL_TYPE;
|
||||||
|
|
||||||
|
memset(&_ANIMAL_TYPE, 0, sizeof(_ANIMAL_TYPE));
|
||||||
|
Eina_Model_Type *type = (Eina_Model_Type *) &_ANIMAL_TYPE;
|
||||||
|
type->version = EINA_MODEL_TYPE_VERSION;
|
||||||
|
type->parent = EINA_MODEL_TYPE_BASE;
|
||||||
|
type->type_size = sizeof(Animal_Type);
|
||||||
|
type->name = "Animal_Type";
|
||||||
|
type->parent = EINA_MODEL_TYPE_GENERIC;
|
||||||
|
type->interfaces = ANIMAL_IFACES;
|
||||||
|
|
||||||
|
ANIMAL_TYPE(type)->eat = _animal_eat;
|
||||||
|
|
||||||
|
/* Init Human Type */
|
||||||
|
Animal_Type _HUMAN_TYPE;
|
||||||
|
Eina_Model_Type *HUMAN_TYPE = (Eina_Model_Type *) &_HUMAN_TYPE;
|
||||||
|
memset(&_HUMAN_TYPE, 0, sizeof(_HUMAN_TYPE));
|
||||||
|
type = (Eina_Model_Type *) &_HUMAN_TYPE;
|
||||||
|
type->version = EINA_MODEL_TYPE_VERSION;
|
||||||
|
type->parent = ANIMAL_TYPE;
|
||||||
|
type->type_size = sizeof(Human_Type);
|
||||||
|
type->name = "Human_Type";
|
||||||
|
type->interfaces = HUMAN_IFACES;
|
||||||
|
|
||||||
|
ANIMAL_TYPE(type)->eat = _human_eat;
|
||||||
|
|
||||||
|
Eina_Model *hm, *am;
|
||||||
|
am = eina_model_new(ANIMAL_TYPE);
|
||||||
|
hm = eina_model_new(HUMAN_TYPE);
|
||||||
|
|
||||||
|
animal_eat(am);
|
||||||
|
fail_if(_animal_eat_count != 1);
|
||||||
|
animal_eat(hm);
|
||||||
|
fail_if(_human_eat_count != 1);
|
||||||
|
|
||||||
|
pooper_poop(am);
|
||||||
|
fail_if(_animal_poop_count != 1);
|
||||||
|
pooper_poop(hm);
|
||||||
|
fail_if(_human_poop_count != 1);
|
||||||
|
|
||||||
|
fail_if(_animal_eat_count != 1);
|
||||||
|
fail_if(_human_eat_count != 1);
|
||||||
|
fail_if(_animal_poop_count != 1);
|
||||||
|
fail_if(_human_poop_count != 1);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
void
|
void
|
||||||
eina_test_model(TCase *tc)
|
eina_test_model(TCase *tc)
|
||||||
{
|
{
|
||||||
|
@ -980,4 +1113,5 @@ eina_test_model(TCase *tc)
|
||||||
tcase_add_test(tc, eina_model_test_child_filtered_iterator);
|
tcase_add_test(tc, eina_model_test_child_filtered_iterator);
|
||||||
tcase_add_test(tc, eina_model_test_struct);
|
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_struct_complex_members);
|
||||||
|
tcase_add_test(tc, eina_model_test_inheritance);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue