Eina model: Added an advanced inheritance + interface example.

SVN revision: 67965
This commit is contained in:
Tom Hacohen 2012-02-15 08:18:47 +00:00
parent 2f2ac7115e
commit de808a0fb8
12 changed files with 704 additions and 1 deletions

View File

@ -0,0 +1,67 @@
/*
* 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);
}

View File

@ -0,0 +1,27 @@
/*
* 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_ */

View File

@ -0,0 +1,72 @@
/*
* 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);
}

View File

@ -0,0 +1,24 @@
/*
* 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_ */

View File

@ -0,0 +1,146 @@
/*
* 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);
}

View File

@ -0,0 +1,24 @@
/*
* 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_ */

View File

@ -0,0 +1,110 @@
/*
* 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;
}

View File

@ -0,0 +1,87 @@
/*
* 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);
}

View File

@ -0,0 +1,24 @@
/*
* 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_ */

View File

@ -0,0 +1,59 @@
/*
* 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);
}

View File

@ -0,0 +1,45 @@
/*
* 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_ */

View File

@ -25,10 +25,26 @@
#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
@ -280,6 +296,8 @@
* @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.
*
* @{
*/