--- /dev/null
+/*
+ * animal.c
+ */
+
+#include "eina_model_04_animal.h"
+
+static Eina_Bool initialized = EINA_FALSE;
+
+static void
+_animal_eat(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Eat Animal\n");
+}
+
+static void
+_animal_breathe(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Breathe Animal\n");
+}
+
+static Animal_Type _ANIMAL_TYPE;
+const Eina_Model_Type * const ANIMAL_TYPE = (Eina_Model_Type *) &_ANIMAL_TYPE;
+
+void animal_init()
+{
+ if (initialized) return;
+ initialized = EINA_TRUE;
+
+ 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_MODEL_TYPE_NAME;
+ type->parent = EINA_MODEL_TYPE_GENERIC;
+
+ ANIMAL_TYPE(type)->breathe = _animal_breathe;
+ ANIMAL_TYPE(type)->eat = _animal_eat;
+}
+
+void
+animal_breathe(Eina_Model *mdl)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(eina_model_instance_check(mdl, ANIMAL_TYPE));
+
+ void (*pf)(Eina_Model *mdl);
+ pf = eina_model_method_resolve(mdl, Animal_Type, breathe);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
+
+void
+animal_eat(Eina_Model *mdl)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(eina_model_instance_check(mdl, ANIMAL_TYPE));
+
+ void (*pf)(Eina_Model *mdl);
+ pf = eina_model_method_resolve(mdl, Animal_Type, eat);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
+
--- /dev/null
+/*
+ * animal.h
+ */
+
+#ifndef ANIMAL_H_
+#define ANIMAL_H_
+
+#include <Eina.h>
+#include <eina_safety_checks.h>
+
+#define ANIMAL_MODEL_TYPE_NAME "Animal_Model_Type"
+
+extern const Eina_Model_Type * const ANIMAL_TYPE;
+#define ANIMAL_TYPE(x) ((Animal_Type *) x)
+
+typedef struct _Animal_Type
+{
+ Eina_Model_Type parent_class;
+ void (*eat)(Eina_Model *mdl);
+ void (*breathe)(Eina_Model *mdl);
+} Animal_Type;
+
+void animal_init();
+void animal_breathe(Eina_Model *mdl);
+void animal_eat(Eina_Model *mdl);
+
+#endif /* ANIMAL_H_ */
--- /dev/null
+/*
+ * child.c
+ */
+
+#include "eina_model_04_child.h"
+#include "eina_model_04_whistler.h"
+
+static Eina_Bool initialized = EINA_FALSE;
+
+static void
+_child_cry(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Cry Child\n");
+}
+
+static void
+_child_dive(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Dive Child\n");
+}
+
+static Child_Type _CHILD_TYPE;
+const Eina_Model_Type * const CHILD_TYPE = (Eina_Model_Type *) &_CHILD_TYPE;
+
+static const Diver_Interface _DIVER_INTERFACE;
+static const Eina_Model_Interface * const DIVER_INTERFACE =
+ (Eina_Model_Interface *) &_DIVER_INTERFACE;
+
+static const Eina_Model_Interface * CLASS_INTERFACE_ARRAY[] =
+ { &_DIVER_INTERFACE.base_interface, NULL }; //this array is for model
+
+void
+child_init()
+{
+ if (initialized) return;
+ initialized = EINA_TRUE;
+
+ human_init();
+
+ //overriding Diver Interface
+ Eina_Model_Interface * iface = (Eina_Model_Interface *) &_DIVER_INTERFACE;
+ iface->version = EINA_MODEL_INTERFACE_VERSION;
+ iface->interface_size = sizeof(Diver_Interface);
+ iface->name = DIVER_INTERFACE_NAME;
+ DIVER_INTERFACE(iface)->dive = _child_dive;
+
+ //creating instance of Child type
+ Eina_Model_Type *type = (Eina_Model_Type *) &_CHILD_TYPE;
+ type->version = EINA_MODEL_TYPE_VERSION;
+ type->parent = HUMAN_TYPE;
+ type->type_size = sizeof(Child_Type);
+ type->name = CHILD_MODEL_TYPE_NAME;
+ type->interfaces = CLASS_INTERFACE_ARRAY;
+ CHILD_TYPE(type)->cry = _child_cry;
+}
+
+//call for implemented Child Class function
+void
+child_cry(Eina_Model *mdl)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(eina_model_instance_check(mdl, CHILD_TYPE));
+
+ void (*pf)(Eina_Model *mdl);
+ pf = eina_model_method_resolve(mdl, Child_Type, cry);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t\t", __func__);
+ pf(mdl);
+}
--- /dev/null
+/*
+ * child.h
+ */
+
+#ifndef CHILD_H_
+#define CHILD_H_
+
+#include "eina_model_04_human.h"
+
+#define CHILD_MODEL_TYPE_NAME "Child_Model_Type"
+
+extern const Eina_Model_Type * const CHILD_TYPE;
+#define CHILD_TYPE(x) ((Child_Type *) x)
+
+typedef struct _Child_Type
+{
+ Human_Type parent_class;
+ void (*cry)(Eina_Model *mdl);
+} Child_Type;
+
+void child_init();
+void child_cry(Eina_Model *mdl);
+
+#endif /* CHILD_H_ */
--- /dev/null
+/*
+ * human.c
+ *
+ */
+
+#include "eina_model_04_human.h"
+#include "eina_model_04_whistler.h"
+
+static Eina_Bool initialized = EINA_FALSE;
+
+static void
+_human_eat(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Salad\n");
+}
+
+static void
+_human_walk(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Walk\n");
+}
+
+static void
+_human_whistle(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Whistle Human\n");
+}
+
+static void
+_human_swim(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Swim Human\n");
+}
+
+static void
+_human_dive(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Dive Human\n");
+}
+/*
+ * defining Human Model Instance
+ * defining Whistler Interface instance
+ * defining Swimmer Interface instance
+ * defining Diver Interface instance
+ */
+static Human_Type _HUMAN_TYPE;
+const Eina_Model_Type * const HUMAN_TYPE = (Eina_Model_Type *) &_HUMAN_TYPE;
+
+static const Whistler_Interface _WHISTLER_INTERFACE;
+static const Eina_Model_Interface * const WHISTLER_INTERFACE =
+ (Eina_Model_Interface *) &_WHISTLER_INTERFACE;
+
+static const Swimmer_Interface _SWIMMER_INTERFACE;
+static const Eina_Model_Interface * const SWIMMER_INTERFACE =
+ (Eina_Model_Interface *) &_SWIMMER_INTERFACE;
+
+static const Diver_Interface _DIVER_INTERFACE;
+static const Eina_Model_Interface * const DIVER_INTERFACE =
+ (Eina_Model_Interface *) &_DIVER_INTERFACE;
+
+/*
+ * defining parent interfaces for Diver Interface instance
+ * defining Interfaces for Human Model instance
+ */
+static const Eina_Model_Interface * PARENT_INTERFACES_ARRAY[] =
+ { &_SWIMMER_INTERFACE.base_interface, NULL }; //this array is for model
+static const Eina_Model_Interface * MODEL_INTERFACES_ARRAY[] =
+ { &_WHISTLER_INTERFACE.base_interface, &_DIVER_INTERFACE.base_interface,
+ NULL }; //this array is for model
+
+void
+human_init()
+{
+ if (initialized) return;
+ initialized = EINA_TRUE;
+
+ animal_init();
+
+ /*
+ * Initializing Whistler Interface Instance
+ */
+ Eina_Model_Interface *iface = (Eina_Model_Interface *) &_WHISTLER_INTERFACE;
+ iface->version = EINA_MODEL_INTERFACE_VERSION;
+ iface->interface_size = sizeof(Whistler_Interface);
+ iface->name = WHISTLER_INTERFACE_NAME;
+ WHISTLER_INTERFACE(iface)->whistle = _human_whistle;
+
+ /*
+ * Initializing Swimmer Interface Instance
+ */
+ iface = (Eina_Model_Interface *) &_SWIMMER_INTERFACE;
+ iface->version = EINA_MODEL_INTERFACE_VERSION;
+ iface->interface_size = sizeof(Swimmer_Interface);
+ iface->name = SWIMMER_INTERFACE_NAME;
+ SWIMMER_INTERFACE(iface)->swim = _human_swim;
+
+ /*
+ * Initializing Diver Interface Instance
+ * Diver_Interface is inherited from Swimmer
+ */
+ iface = (Eina_Model_Interface *) &_DIVER_INTERFACE;
+ iface->version = EINA_MODEL_INTERFACE_VERSION;
+ iface->interface_size = sizeof(Diver_Interface);
+ iface->name = DIVER_INTERFACE_NAME;
+ iface->interfaces = PARENT_INTERFACES_ARRAY;
+ DIVER_INTERFACE(iface)->dive = _human_dive;
+
+ /*
+ * Initializing instance of Human Model
+ */
+ Eina_Model_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_MODEL_TYPE_NAME;
+ type->interfaces = MODEL_INTERFACES_ARRAY;
+
+ ANIMAL_TYPE(type)->eat = _human_eat;
+ HUMAN_TYPE(type)->walk =_human_walk;
+}
+
+
+/*
+ * call for implemented Human Class function
+ */
+void
+human_walk(Eina_Model *mdl)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(eina_model_instance_check(mdl, HUMAN_TYPE));
+
+ void (*pf)(Eina_Model *mdl);
+ pf = eina_model_method_resolve(mdl, Human_Type, walk);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
--- /dev/null
+/*
+ * human.h
+ */
+
+#ifndef HUMAN_H_
+#define HUMAN_H_
+
+#include "eina_model_04_animal.h"
+
+#define HUMAN_MODEL_TYPE_NAME "Human_Model_Type"
+
+extern const Eina_Model_Type * const HUMAN_TYPE;
+#define HUMAN_TYPE(x) ((Human_Type *) x)
+
+typedef struct _Human_Type
+{
+ Animal_Type parent_class;
+ void (*walk)(Eina_Model *mdl);
+} Human_Type;
+
+void human_init();
+void human_walk(Eina_Model *mdl);
+
+#endif /* HUMAN_H_ */
--- /dev/null
+/*
+ * main_animal.c
+ * compile with: gcc `pkg-config --cflags --libs eina` eina_model_04_*.c -o eina_model_04
+ */
+
+/*
+ * This example demonstrates the extended usage of Eina Model.
+ * Class inheritance and interface implementation
+ *
+ * Animal Class is inherited from BaseClass and implements
+ * "_breathe_animal()" and "_eat_animal()" methods.
+ *
+ * Human Class is inherited from Animal class.
+ * Parrot Class is inherited from Animal class.
+ *
+ * Child Class is inherited from Human class.
+ *
+ * Human Class and Parrot Class implement Whistler Interface.
+ * Human Class implements Diver Interface. Diver Interface inherited from Swimmer Interface
+ *
+ *
+ * Animal Class (inherited from Base Class)
+ * + _breathe_animal()
+ * + _eat_animal()
+ * / -------/ \-------------\
+ * / \
+ * Human Class Parrot Class
+ * inherits inherits
+ * + animal_breathe() + animal_breathe()
+ * overrides overrides
+ * + animal_eat(); + animal_eat();
+ * implements implements
+ * + human_walk(); + parrot_fly();
+ *
+ * implements Whistler, Swimmer, implements Whistler,
+ * Diver Interfaces: + whistler_whistle()
+ * + whistler_whistle()
+ * + swimmer_swim()
+ * + diver_dive()
+ *
+ * ----------------------------------------------------------
+ * | Swim_Interface |
+ * | + swim() |
+ * | | |
+ * | | |
+ * | Dive Intarface (inherited from Swim Interface) |
+ * | + dive() |
+ * ---------------------------------------------------------
+ * |
+ * |
+ * Child Class
+ * + inherits all parent's methods
+ * + implements cry_child()
+ * + overrides dive() interface method
+ */
+
+#include <Eina.h>
+#include "eina_model_04_human.h"
+#include "eina_model_04_parrot.h"
+#include "eina_model_04_child.h"
+#include "eina_model_04_whistler.h"
+
+int
+main()
+{
+ Eina_Model *h, *p, *c;
+
+ eina_init();
+
+ human_init();
+ parrot_init();
+ child_init();
+
+ h = eina_model_new(HUMAN_TYPE);
+ p = eina_model_new(PARROT_TYPE);
+ c = eina_model_new(CHILD_TYPE);
+
+ animal_breathe(p);
+ animal_eat(p);
+ parrot_fly(p);
+ whistler_whistle(p);
+
+ printf("\n");
+ animal_breathe(h);
+ animal_eat(h);
+ human_walk(h);
+ whistler_whistle(h);
+ swimmer_swim(h);
+ diver_dive(h);
+
+ printf("\n");
+ animal_breathe(c);
+ animal_eat(c);
+ human_walk(c);
+ whistler_whistle(c);
+ swimmer_swim(c);
+ diver_dive(c);
+ child_cry(c);
+
+ eina_model_unref(c);
+ eina_model_unref(h);
+ eina_model_unref(p);
+
+ eina_shutdown();
+
+ return 0;
+}
+
+
+
--- /dev/null
+/*
+ * parrot.c
+ */
+
+#include "eina_model_04_parrot.h"
+#include "eina_model_04_whistler.h"
+
+static Eina_Bool initialized = EINA_FALSE;
+
+static void
+_parrot_fly(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Fly Parrot\n");
+}
+
+static void
+_parrot_eat(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Grain \n");
+}
+
+static void
+_parrot_whistle(Eina_Model *mdl)
+{
+ printf("%s\t%s", eina_model_type_name_get(eina_model_type_get(mdl)),
+ __func__);
+ printf("\t\t Whistle Parrot\n");
+}
+
+/*
+ * defining Parrot Model Instance
+ * defining Whistler Interface instance
+ */
+static Parrot_Type _PARROT_TYPE;
+const Eina_Model_Type * const PARROT_TYPE = (Eina_Model_Type *) &_PARROT_TYPE;
+
+static const Whistler_Interface _WHISTLER_INTERFACE;
+static const Eina_Model_Interface * const WHISTLER_INTERFACE =
+ (Eina_Model_Interface *) &_WHISTLER_INTERFACE;
+
+static const Eina_Model_Interface * MODEL_INTERFACES_ARRAY[] =
+ { &_WHISTLER_INTERFACE.base_interface, NULL }; //this array is for model
+
+void
+parrot_init()
+{
+ if (initialized) return;
+ initialized = EINA_TRUE;
+
+ animal_init();
+ /*
+ *overriding Whistler Interface (creating instance of Whistler Interface)
+ */
+ Eina_Model_Interface *iface = (Eina_Model_Interface *) &_WHISTLER_INTERFACE;
+ iface->version = EINA_MODEL_INTERFACE_VERSION;
+ iface->interface_size = sizeof(Whistler_Interface);
+ iface->name = WHISTLER_INTERFACE_NAME;
+ WHISTLER_INTERFACE(iface)->whistle = _parrot_whistle;
+
+ Eina_Model_Type *type = (Eina_Model_Type *) &_PARROT_TYPE;
+ type->version = EINA_MODEL_TYPE_VERSION;
+ type->parent = ANIMAL_TYPE;
+ type->type_size = sizeof(Parrot_Type);
+ type->name = PARROT_MODEL_TYPE_NAME;
+ type->interfaces = MODEL_INTERFACES_ARRAY;
+
+ ANIMAL_TYPE(type)->eat = _parrot_eat;
+ PARROT_TYPE(type)->fly = _parrot_fly;
+}
+
+
+void
+parrot_fly(Eina_Model *mdl)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(eina_model_instance_check(mdl, PARROT_TYPE));
+
+ void (*pf)(Eina_Model *mdl);
+ pf = eina_model_method_resolve(mdl, Parrot_Type, fly);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
+
--- /dev/null
+/*
+ * parrot.h
+ */
+
+#ifndef PARROT_H_
+#define PARROT_H_
+
+#include "eina_model_04_animal.h"
+
+#define PARROT_MODEL_TYPE_NAME "Parrot_Model_Type"
+
+extern const Eina_Model_Type * const PARROT_TYPE;
+#define PARROT_TYPE(x) ((Parrot_Type *) x)
+
+typedef struct _Parrot_Type
+{
+ Animal_Type parent_class;
+ void (*fly)(Eina_Model *mdl);
+} Parrot_Type;
+
+void parrot_init();
+void parrot_fly(Eina_Model *mdl);
+
+#endif /* PARROT_H_ */
--- /dev/null
+/*
+ * whistler.c
+ *
+ */
+
+#include "eina_model_04_whistler.h"
+
+void
+whistler_whistle(Eina_Model *mdl)
+{
+ const Eina_Model_Interface *iface = NULL;
+ iface = eina_model_interface_get(mdl, WHISTLER_INTERFACE_NAME);
+
+ EINA_SAFETY_ON_NULL_RETURN(iface);
+
+ void (*pf)(Eina_Model *);
+
+ pf = eina_model_interface_method_resolve(iface, mdl, Whistler_Interface, whistle);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
+/*
+ * call for overridden Swimmer Interface function
+ */
+void
+swimmer_swim(Eina_Model *mdl)
+{
+ const Eina_Model_Interface *iface = NULL;
+ iface = eina_model_interface_get(mdl, SWIMMER_INTERFACE_NAME);
+
+ EINA_SAFETY_ON_NULL_RETURN(iface);
+
+ void (*pf)(Eina_Model *);
+
+ pf = eina_model_interface_method_resolve(iface, mdl, Swimmer_Interface, swim);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
+
+/*
+ * call for overridden Diver Interface function
+ */
+void
+diver_dive(Eina_Model *mdl)
+{
+ const Eina_Model_Interface *iface = NULL;
+ iface = eina_model_interface_get(mdl, DIVER_INTERFACE_NAME);
+
+ EINA_SAFETY_ON_NULL_RETURN(iface);
+
+ void (*pf)(Eina_Model *);
+
+ pf = eina_model_interface_method_resolve(iface, mdl, Diver_Interface, dive);
+ EINA_SAFETY_ON_NULL_RETURN(pf);
+ printf("%s() \t", __func__);
+ pf(mdl);
+}
--- /dev/null
+/*
+ * whistler.h
+ */
+
+#ifndef WHISTLER_H_
+#define WHISTLER_H_
+
+#include <Eina.h>
+#include <eina_safety_checks.h>
+
+#define WHISTLER_INTERFACE_NAME "Whistler_Interface"
+#define SWIMMER_INTERFACE_NAME "Swimmer_Interface"
+#define DIVER_INTERFACE_NAME "Diver_Interface"
+
+#define WHISTLER_INTERFACE(x) ((Whistler_Interface *) x)
+#define SWIMMER_INTERFACE(x) ((Swimmer_Interface *) x)
+#define DIVER_INTERFACE(x) ((Diver_Interface *) x)
+
+typedef struct _Whistler_Interface
+{
+ Eina_Model_Interface base_interface;
+ void (*whistle)(Eina_Model *);
+
+} Whistler_Interface;
+
+typedef struct _Swimmer_Interface
+{
+ Eina_Model_Interface base_interface;
+ void (*swim)(Eina_Model *);
+
+} Swimmer_Interface;
+
+//Diver Interface will use Swimmer Interface as a parent
+typedef struct _Diver_Interface
+{
+ Eina_Model_Interface base_interface;
+ void (*dive)(Eina_Model *);
+
+} Diver_Interface;
+
+void whistler_whistle(Eina_Model *mdl);
+void swimmer_swim(Eina_Model *mdl);
+void diver_dive(Eina_Model *mdl);
+
+#endif /* WHISTLER_H_ */
#include <stdarg.h>
/**
- * @page eina_model_01_c eina_model_01.c Eina_Model inheritance and function overriding
+ * @page eina_model_01_c Eina_Model inheritance and function overriding
* @include eina_model_01.c
*/
/**
+ * @page eina_model_04_c Eina_Model inheritance, interfaces, and function overriding
+ * @include eina_model_04_main.c
+ * @include eina_model_04_animal.c
+ * @include eina_model_04_human.c
+ * @include eina_model_04_parrot.c
+ * @include eina_model_04_child.c
+ * @include eina_model_04_main.c
+ * @include eina_model_04_whistler.c
+ * @include eina_model_04_animal.h
+ * @include eina_model_04_human.h
+ * @include eina_model_04_whistler.h
+ * @include eina_model_04_child.h
+ * @include eina_model_04_parrot.h
+ */
+
+/**
* @page eina_model_02_example_page Creating a simple model
* @dontinclude eina_model_02.c
*
* @li @ref eina_model_03_example_page walk-through example on how to
* inherit types, a suggestion of eina_model_load() usage and uses
* #EINA_MODEL_TYPE_STRUCT.
+ * @li @ref eina_model_04_c Advanced inheritance, interfaces and interface
+ * function overloading example.
*
* @{
*/