#define EINA_MODEL_TYPE_VERSION (1)
unsigned int version; /**< must be #EINA_MODEL_TYPE_VERSION */
unsigned int private_size; /**< used to allocate type private data */
+ unsigned int type_size; /**< used to know sizeof(Eina_Model_Type) or subtypes (which may be bigger, by including Eina_Model_Type as a header */
const char *name; /**< name for debug and introspection */
const Eina_Model_Type *parent; /**< parent type, must be EINA_MODEL_TYPE_BASE or a child of */
const Eina_Model_Interface **interfaces; /**< null terminated array of interfaces */
Eina_Iterator *(*child_sorted_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count, Eina_Compare_Cb compare);
Eina_Iterator *(*child_filtered_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count, Eina_Each_Cb match, const void *data);
char *(*to_string)(const Eina_Model *model); /**< used to represent model as string, usually for debug purposes or user convenience */
- const void *value; /**< may hold extension methods */
+ void *__extension_ptr0; /**< not to be used */
+ void *__extension_ptr1; /**< not to be used */
+ void *__extension_ptr2; /**< not to be used */
+ void *__extension_ptr3; /**< not to be used */
};
+#define EINA_MODEL_TYPE_INIT(name, type, private_type, parent, interfaces, events) \
+ {EINA_MODEL_TYPE_VERSION, \
+ sizeof(private_type), \
+ sizeof(type), \
+ name, \
+ parent, \
+ interfaces, \
+ events, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }
+
+#define EINA_MODEL_TYPE_INIT_NOPRIVATE(name, type, parent, interfaces, events) \
+ {EINA_MODEL_TYPE_VERSION, \
+ 0, \
+ sizeof(type), \
+ name, \
+ parent, \
+ interfaces, \
+ events, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }
+
+#define EINA_MODEL_TYPE_INIT_NULL \
+ {0, \
+ 0, \
+ 0, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }
+
EAPI Eina_Bool eina_model_type_constructor(const Eina_Model_Type *type,
Eina_Model *model) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
EAPI Eina_Bool eina_model_type_destructor(const Eina_Model_Type *type,
EAPI char *eina_model_type_to_string(const Eina_Model_Type *type,
const Eina_Model *model) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
+
+/**
+ * @brief Get resolved method from types that extend Eina_Model_Type given offset.
+ *
+ * @param model the model to query the method
+ * @param offset the byte offset in the structure given as type, it
+ * must be bigger than Eina_Model_Type itself.
+ * @return address to resolved method, or @c NULL if method is not
+ * implemented.
+ *
+ * When implementing new types that augments the basic methods from
+ * Eina_Model_Type, the recommended structure layout is as follow:
+ * @code
+ * typedef struct _My_Type My_Type;
+ * struct _My_Type {
+ * Eina_Model_Type base;
+ * int (*my_method)(Eina_Model *model);
+ * };
+ *
+ * int my_type_my_method(Eina_Model *model);
+ * @endcode
+ *
+ * Then the implementation of @c my_type_my_method() needs to get the
+ * most specific @c my_method that is not @c NULL from type hierarchy,
+ * also called "resolve the method".
+ *
+ * To do this in an efficient way, Eina_Model infrastructure
+ * pre-resolves all methods and provides this function for efficient
+ * query. The recommended implementation of my_type_my_method() would
+ * be:
+ * @code
+ * int my_type_my_method(Eina_Model *model)
+ * {
+ * int (*meth)(Eina_Model *);
+ *
+ * EINA_SAFETY_ON_FALSE_RETURN(eina_model_instance_check(model, MY_TYPE), -1);
+ *
+ * meth = eina_model_method_resolve(model, offsetof(My_Type, my_method));
+ * EINA_SAFETY_ON_NULL_RETURN(meth, -1);
+ * return meth(model);
+ * }
+ * @endcode
+ *
+ * @note offset must be bigger than Eina_Model_Type, otherwise use
+ * specific functions such as eina_model_property_get().
+ *
+ * @since 1.2
+ */
+EAPI const void *eina_model_method_resolve(const Eina_Model *model,
+ unsigned int offset) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT EINA_PURE;
+
+EAPI const void *eina_model_type_method_resolve(const Eina_Model_Type *type,
+ const Eina_Model *model,
+ unsigned int offset) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_PURE;
+
/**
* @struct _Eina_Model_Interface
*
#define EINA_MODEL_INTERFACE_VERSION (1)
unsigned int version; /**< must be #EINA_MODEL_INTERFACE_VERSION */
unsigned int private_size; /**< used to allocate interface private data */
+ unsigned int interface_size; /**< used to know sizeof(Eina_Model_Interface) or subtypes (which may be bigger, by including Eina_Model_Interface as header */
const char *name; /**< name for debug and introspection */
const Eina_Model_Interface **interfaces; /**< null terminated array of parent interfaces */
const Eina_Model_Event_Description *events; /**< null terminated array of events */
Eina_Bool (*destructor)(Eina_Model *model); /**< destruct interface instance, flush will be called after it. Should call parent's destructor if needed. Release reference to other models here. */
Eina_Bool (*copy)(const Eina_Model *src, Eina_Model *dst); /**< copy interface private data, do @b not call parent interface copy! */
Eina_Bool (*deep_copy)(const Eina_Model *src, Eina_Model *dst); /**< deep copy interface private data, do @b not call parent interface deep copy! */
- const void *value; /**< holds the actual interface methods */
+ void *__extension_ptr0; /**< not to be used */
+ void *__extension_ptr1; /**< not to be used */
+ void *__extension_ptr2; /**< not to be used */
+ void *__extension_ptr3; /**< not to be used */
};
+#define EINA_MODEL_INTERFACE_INIT(name, iface, private_type, parent, events) \
+ {EINA_MODEL_INTERFACE_VERSION, \
+ sizeof(private_type), \
+ sizeof(iface), \
+ name, \
+ parent, \
+ events, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }
+
+#define EINA_MODEL_INTERFACE_INIT_NOPRIVATE(name, iface, parent, events) \
+ {EINA_MODEL_INTERFACE_VERSION, \
+ 0, \
+ sizeof(iface), \
+ name, \
+ parent, \
+ events, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }
+
+#define EINA_MODEL_INTERFACE_INIT_NULL \
+ {0, \
+ 0, \
+ 0, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }
+
EAPI Eina_Bool eina_model_interface_constructor(const Eina_Model_Interface *iface,
Eina_Model *model) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
EAPI Eina_Bool eina_model_interface_destructor(const Eina_Model_Interface *iface,
const Eina_Model *src,
Eina_Model *dst) EINA_ARG_NONNULL(1, 2, 3);
+EAPI const void *eina_model_interface_method_resolve(const Eina_Model_Interface *iface,
+ const Eina_Model *model,
+ unsigned int offset) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_PURE;
+
struct _Eina_Model_Event_Description
{
typedef struct _Eina_Model_Interface_Properties Eina_Model_Interface_Properties;
struct _Eina_Model_Interface_Properties
{
+ Eina_Model_Interface base;
#define EINA_MODEL_INTERFACE_PROPERTIES_VERSION (1)
unsigned int version;
Eina_Bool (*compare)(const Eina_Model *a, const Eina_Model *b, int *cmp);
*/
struct _Eina_Model_Interface_Children
{
+ Eina_Model_Interface base;
#define EINA_MODEL_INTERFACE_CHILDREN_VERSION (1)
unsigned int version;
Eina_Bool (*compare)(const Eina_Model *a, const Eina_Model *b, int *cmp);
Eina_Iterator *(*child_sorted_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count, Eina_Compare_Cb compare);
Eina_Iterator *(*child_filtered_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count, Eina_Each_Cb match, const void *data);
char *(*to_string)(const Eina_Model *model); /**< used to represent model as string, usually for debug purposes or user convenience */
+ const void **extension;
} type;
} ops;
struct {
static Eina_Bool
_eina_model_description_type_fill(Eina_Model_Description *desc, const Eina_Model_Type *type)
{
- const Eina_Model_Type *itr;
- unsigned int count;
+ const Eina_Model_Type *itr, *last_itr = NULL;
+ unsigned int count, child_size = 0;
for (count = 0, itr = type; itr != NULL; itr = itr->parent, count++)
{
CRITICAL("Type %p provides no name!", itr);
return EINA_FALSE;
}
+ if (itr->type_size < sizeof(Eina_Model_Type))
+ {
+ CRITICAL("Type %p %s size must be >= sizeof(Eina_Model_Type)!",
+ itr, itr->name);
+ return EINA_FALSE;
+ }
+ if (child_size == 0) child_size = itr->type_size;
+ else if (child_size < itr->type_size)
+ {
+ CRITICAL("Type %p %s size is bigger than its child type %p %s!",
+ itr, itr->name, last_itr, last_itr->name);
+ return EINA_FALSE;
+ }
+ last_itr = itr;
#define DEF_METH(meth) \
if (!desc->ops.type.meth) desc->ops.type.meth = itr->meth
CK_METH(property_get);
#undef CK_METH
+ if (child_size <= sizeof(Eina_Model_Type))
+ desc->ops.type.extension = NULL;
+ else
+ {
+ unsigned ext_size = child_size - sizeof(Eina_Model_Type);
+ unsigned ext_count = ext_size / sizeof(void *);
+
+ if (ext_size % sizeof(void *) != 0)
+ {
+ CRITICAL("Extension size %u is not multiple of sizeof(void*)",
+ ext_size);
+ return EINA_FALSE;
+ }
+
+ desc->ops.type.extension = calloc(ext_count, sizeof(void *));
+ EINA_SAFETY_ON_NULL_RETURN_VAL(desc->ops.type.extension, EINA_FALSE);
+
+ for (itr = type; itr != NULL; itr = itr->parent)
+ {
+ unsigned cur_size = itr->type_size - sizeof(Eina_Model_Type);
+ unsigned i, cur_count = cur_size / sizeof(void *);
+ const void * const *ptr = (const void **)((const char *)itr + sizeof(Eina_Model_Type));
+
+ if (cur_size == 0) break;
+
+ for (i = 0; i < cur_count; i++)
+ {
+ if (desc->ops.type.extension[i]) continue;
+ desc->ops.type.extension[i] = ptr[i];
+ }
+ }
+ }
+
desc->cache.types = malloc(count * sizeof(Eina_Model_Type *));
- EINA_SAFETY_ON_NULL_RETURN_VAL(desc->cache.types, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_GOTO(desc->cache.types, cache_types_failed);
desc->total.types = count;
for (count = 0, itr = type; itr != NULL; itr = itr->parent, count++)
desc->cache.types[count] = itr;
return EINA_TRUE;
+
+ cache_types_failed:
+ free(desc->ops.type.extension);
+ return EINA_FALSE;
}
static inline Eina_Bool
free(desc->cache.ifaces);
failed_ifaces:
free(desc->cache.types);
+ free(desc->ops.type.extension);
failed_type:
free(desc);
return NULL;
INF("Disposed model description for type %p (%s)", type, type->name);
+ free(desc->ops.type.extension);
free(desc->cache.types);
free(desc->cache.ifaces);
free(desc->cache.privates);
const unsigned char *ptr = (const unsigned char *)iface;
const void **addr = (const void **)(ptr + offset);
+ if (offset + sizeof(void *) > iface->interface_size) return NULL;
+
if (*addr) return *addr;
if (!iface->interfaces) return NULL;
return NULL;
}
-/* similar to _eina_model_interface_find_offset(), but looks for
- * offset in Eina_Model_Interface::value instead of the interface
- * itself.
- */
-static const void *
-_eina_model_interface_value_find_offset(const Eina_Model_Interface *iface, unsigned int offset)
-{
- const Eina_Model_Interface **itr;
- const unsigned char *ptr = iface->value;
- const void **addr = (const void **)(ptr + offset);
-
- if ((ptr) && (*addr)) return *addr;
- if (!iface->interfaces) return NULL;
-
- for (itr = iface->interfaces; *itr != NULL; itr++)
- {
- const void *r = _eina_model_interface_value_find_offset(*itr, offset);
- if (r)
- return r;
- }
-
- return NULL;
-}
-
static void
_eina_model_event_callback_free_deleted(Eina_Model *model)
{
static const Eina_Model_Type _EINA_MODEL_TYPE_BASE = {
EINA_MODEL_TYPE_VERSION,
0, /* there is no private data */
+ sizeof(Eina_Model_Type),
"Eina_Model_Type_Base",
NULL, /* should be the only type with NULL here! */
NULL, /* no interfaces implemented */
_eina_model_type_base_child_sorted_iterator_get,
_eina_model_type_base_child_filtered_iterator_get,
_eina_model_type_base_to_string,
- NULL /* no extensions */
+ NULL, /* extension pointer */
+ NULL, /* extension pointer */
+ NULL, /* extension pointer */
+ NULL /* extension pointer */
};
/*
if (priv->if_properties)
{
Eina_Bool (*compare)(const Eina_Model*, const Eina_Model*, int *) =
- _eina_model_interface_value_find_offset
+ _eina_model_interface_find_offset
(priv->if_properties,
offsetof(Eina_Model_Interface_Properties, compare));
if (priv->if_children)
{
Eina_Bool (*compare)(const Eina_Model*, const Eina_Model*, int *) =
- _eina_model_interface_value_find_offset
+ _eina_model_interface_find_offset
(priv->if_children,
offsetof(Eina_Model_Interface_Children, compare));
static const Eina_Model_Type _EINA_MODEL_TYPE_MIXIN = {
EINA_MODEL_TYPE_VERSION,
sizeof(Eina_Model_Type_Mixin_Data),
+ sizeof(Eina_Model_Type),
"Eina_Model_Type_Mixin",
&_EINA_MODEL_TYPE_BASE,
NULL, /* no interfaces implemented */
NULL, /* use default sorted iterator get */
NULL, /* use default filtered iterator get */
NULL, /* use default to string */
- NULL /* no extensions */
+ NULL, /* extension pointer */
+ NULL, /* extension pointer */
+ NULL, /* extension pointer */
+ NULL /* extension pointer */
};
#undef EINA_MODEL_TYPE_MIXIN_GET
}
#undef EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET
-static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_HASH_VALUE = {
+static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_HASH = {
+ {
+ EINA_MODEL_INTERFACE_VERSION,
+ sizeof(Eina_Hash *),
+ sizeof(Eina_Model_Interface_Properties),
+ _EINA_MODEL_INTERFACE_NAME_PROPERTIES,
+ NULL, /* no parent interfaces */
+ NULL, /* no extra events */
+ _eina_model_interface_properties_hash_setup,
+ _eina_model_interface_properties_hash_flush,
+ _eina_model_interface_properties_hash_constructor,
+ _eina_model_interface_properties_hash_destructor,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
EINA_MODEL_INTERFACE_PROPERTIES_VERSION,
NULL, /* no compare */
NULL, /* no load */
_eina_model_interface_properties_hash_names_list
};
-static const Eina_Model_Interface _EINA_MODEL_INTERFACE_PROPERTIES_HASH = {
- EINA_MODEL_INTERFACE_VERSION,
- sizeof(Eina_Hash *),
- _EINA_MODEL_INTERFACE_NAME_PROPERTIES,
- NULL, /* no parent interfaces */
- NULL, /* no extra events */
- _eina_model_interface_properties_hash_setup,
- _eina_model_interface_properties_hash_flush,
- _eina_model_interface_properties_hash_constructor,
- _eina_model_interface_properties_hash_destructor,
- NULL,
- NULL,
- &_EINA_MODEL_INTERFACE_PROPERTIES_HASH_VALUE
-};
-
/* EINA_MODEL_INTERFACE_PROPERTIES_STRUCT ******************************/
static Eina_Value_Struct *
}
#undef EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET
-static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_VALUE = {
+static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = {
+ {
+ EINA_MODEL_INTERFACE_VERSION,
+ sizeof(Eina_Value),
+ sizeof(Eina_Model_Interface_Properties),
+ _EINA_MODEL_INTERFACE_NAME_PROPERTIES,
+ NULL, /* no parent interfaces */
+ NULL, /* no extra events */
+ _eina_model_interface_properties_struct_setup,
+ _eina_model_interface_properties_struct_flush,
+ _eina_model_interface_properties_struct_constructor,
+ _eina_model_interface_properties_struct_destructor,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
EINA_MODEL_INTERFACE_PROPERTIES_VERSION,
NULL, /* no compare */
NULL, /* no load */
_eina_model_interface_properties_struct_names_list
};
-static const Eina_Model_Interface _EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = {
- EINA_MODEL_INTERFACE_VERSION,
- sizeof(Eina_Value),
- _EINA_MODEL_INTERFACE_NAME_PROPERTIES,
- NULL, /* no parent interfaces */
- NULL, /* no extra events */
- _eina_model_interface_properties_struct_setup,
- _eina_model_interface_properties_struct_flush,
- _eina_model_interface_properties_struct_constructor,
- _eina_model_interface_properties_struct_destructor,
- NULL,
- NULL,
- &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_VALUE
-};
-
/* EINA_MODEL_INTERFACE_CHILDREN_INARRAY ******************************/
#define EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model) \
}
#undef EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET
-static const Eina_Model_Interface_Children _EINA_MODEL_INTERFACE_CHILDREN_INARRAY_VALUE = {
+static const Eina_Model_Interface_Children _EINA_MODEL_INTERFACE_CHILDREN_INARRAY = {
+ {
+ EINA_MODEL_INTERFACE_VERSION,
+ sizeof(Eina_Inarray),
+ sizeof(Eina_Model_Interface_Children),
+ _EINA_MODEL_INTERFACE_NAME_CHILDREN,
+ NULL, /* no parent interfaces */
+ NULL, /* no extra events */
+ _eina_model_interface_children_inarray_setup,
+ _eina_model_interface_children_inarray_flush,
+ _eina_model_interface_children_inarray_constructor,
+ _eina_model_interface_children_inarray_destructor,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
EINA_MODEL_INTERFACE_CHILDREN_VERSION,
NULL, /* no compare */
NULL, /* no load */
_eina_model_interface_children_inarray_sort
};
-static const Eina_Model_Interface _EINA_MODEL_INTERFACE_CHILDREN_INARRAY = {
- EINA_MODEL_INTERFACE_VERSION,
- sizeof(Eina_Inarray),
- _EINA_MODEL_INTERFACE_NAME_CHILDREN,
- NULL, /* no parent interfaces */
- NULL, /* no extra events */
- _eina_model_interface_children_inarray_setup,
- _eina_model_interface_children_inarray_flush,
- _eina_model_interface_children_inarray_constructor,
- _eina_model_interface_children_inarray_destructor,
- NULL,
- NULL,
- &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY_VALUE
-};
-
/* EINA_MODEL_TYPE_GENERIC ********************************************/
static const Eina_Model_Interface *_EINA_MODEL_TYPE_GENERIC_IFACES[] = {
- &_EINA_MODEL_INTERFACE_PROPERTIES_HASH,
- &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY,
+ &_EINA_MODEL_INTERFACE_PROPERTIES_HASH.base,
+ &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY.base,
NULL
};
-static const Eina_Model_Type _EINA_MODEL_TYPE_GENERIC = {
- EINA_MODEL_TYPE_VERSION,
- 0,
- "Eina_Model_Type_Generic",
- &_EINA_MODEL_TYPE_MIXIN,
- _EINA_MODEL_TYPE_GENERIC_IFACES,
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL /* inherit from mix-in */
-};
+static const Eina_Model_Type _EINA_MODEL_TYPE_GENERIC =
+ EINA_MODEL_TYPE_INIT_NOPRIVATE("Eina_Model_Type_Generic",
+ Eina_Model_Type,
+ &_EINA_MODEL_TYPE_MIXIN,
+ _EINA_MODEL_TYPE_GENERIC_IFACES,
+ NULL);
/* EINA_MODEL_TYPE_STRUCT ********************************************/
static const Eina_Model_Interface *_EINA_MODEL_TYPE_STRUCT_IFACES[] = {
- &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT,
- &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY,
+ &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base,
+ &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY.base,
NULL
};
-static const Eina_Model_Type _EINA_MODEL_TYPE_STRUCT = {
- EINA_MODEL_TYPE_VERSION,
- 0,
- "Eina_Model_Type_Struct",
- &_EINA_MODEL_TYPE_MIXIN,
- _EINA_MODEL_TYPE_STRUCT_IFACES,
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL, /* inherit from mix-in */
- NULL /* inherit from mix-in */
-};
+static const Eina_Model_Type _EINA_MODEL_TYPE_STRUCT =
+ EINA_MODEL_TYPE_INIT_NOPRIVATE("Eina_Model_Type_Struct",
+ Eina_Model_Type,
+ &_EINA_MODEL_TYPE_MIXIN,
+ _EINA_MODEL_TYPE_STRUCT_IFACES,
+ NULL);
/**
*/
EINA_MODEL_TYPE_GENERIC = &_EINA_MODEL_TYPE_GENERIC;
EINA_MODEL_TYPE_STRUCT = &_EINA_MODEL_TYPE_STRUCT;
- EINA_MODEL_INTERFACE_PROPERTIES_HASH = &_EINA_MODEL_INTERFACE_PROPERTIES_HASH;
- EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT;
+ EINA_MODEL_INTERFACE_PROPERTIES_HASH = &_EINA_MODEL_INTERFACE_PROPERTIES_HASH.base;
+ EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base;
- EINA_MODEL_INTERFACE_CHILDREN_INARRAY = &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY;
+ EINA_MODEL_INTERFACE_CHILDREN_INARRAY = &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY.base;
EINA_MODEL_INTERFACE_NAME_PROPERTIES = _EINA_MODEL_INTERFACE_NAME_PROPERTIES;
EINA_MODEL_INTERFACE_NAME_CHILDREN = _EINA_MODEL_INTERFACE_NAME_CHILDREN;
return NULL;
}
+EAPI const void *
+eina_model_method_resolve(const Eina_Model *model, unsigned int offset)
+{
+ const Eina_Model_Description *desc;
+
+ EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(offset > sizeof(Eina_Model_Type), NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(offset % sizeof(void *) == 0, NULL);
+
+ desc = model->desc;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL
+ (offset + sizeof(void *) < desc->cache.types[0]->type_size, NULL);
+
+ offset -= sizeof(Eina_Model_Type);
+ offset /= sizeof(void *);
+ return desc->ops.type.extension[offset];
+}
+
+EAPI const void *
+eina_model_type_method_resolve(const Eina_Model_Type *type, const Eina_Model *model, unsigned int offset)
+{
+ const Eina_Model_Description *desc;
+
+ EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(offset > sizeof(Eina_Model_Type), NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(offset % sizeof(void *) == 0, NULL);
+
+ desc = model->desc;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL
+ (offset + sizeof(void *) < desc->cache.types[0]->type_size, NULL);
+
+ return _eina_model_type_find_offset(type, offset);
+}
+
/* interface functions ************************************************/
EAPI Eina_Bool
return deep_copy(src, dst);
}
+EAPI const void *
+eina_model_interface_method_resolve(const Eina_Model_Interface *iface, const Eina_Model *model, unsigned int offset)
+{
+ EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(offset > sizeof(Eina_Model_Interface), NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(offset % sizeof(void *) == 0, NULL);
+ return _eina_model_interface_find_offset(iface, offset);
+}
+
/* Eina_Model_Interface_Properties ************************************/
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, a, EINA_FALSE);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, b, EINA_FALSE);
- compare = _eina_model_interface_value_find_offset
+ compare = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, compare));
EINA_SAFETY_ON_NULL_RETURN_VAL(compare, EINA_FALSE);
return compare(a, b, cmp);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- load = _eina_model_interface_value_find_offset
+ 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);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- unload = _eina_model_interface_value_find_offset
+ 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);
EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- get = _eina_model_interface_value_find_offset
+ get = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, get));
EINA_SAFETY_ON_NULL_RETURN_VAL(get, EINA_FALSE);
return get(model, name, value);
EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), EINA_FALSE);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- set = _eina_model_interface_value_find_offset
+ set = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, set));
EINA_SAFETY_ON_NULL_RETURN_VAL(set, EINA_FALSE);
return set(model, name, value);
EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- del = _eina_model_interface_value_find_offset
+ del = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, del));
EINA_SAFETY_ON_NULL_RETURN_VAL(del, EINA_FALSE);
return del(model, name);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, NULL);
- names_list_get = _eina_model_interface_value_find_offset
+ names_list_get = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Properties, names_list_get));
EINA_SAFETY_ON_NULL_RETURN_VAL(names_list_get, NULL);
return names_list_get(model);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, a, EINA_FALSE);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, b, EINA_FALSE);
- compare = _eina_model_interface_value_find_offset
+ compare = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, compare));
EINA_SAFETY_ON_NULL_RETURN_VAL(compare, EINA_FALSE);
return compare(a, b, cmp);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- load = _eina_model_interface_value_find_offset
+ 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);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- unload = _eina_model_interface_value_find_offset
+ 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);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, -1);
- count = _eina_model_interface_value_find_offset
+ count = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, count));
EINA_SAFETY_ON_NULL_RETURN_VAL(count, -1);
return count(model);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, NULL);
- get = _eina_model_interface_value_find_offset
+ get = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, get));
EINA_SAFETY_ON_NULL_RETURN_VAL(get, NULL);
return get(model, position);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE);
- set = _eina_model_interface_value_find_offset
+ set = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, set));
EINA_SAFETY_ON_NULL_RETURN_VAL(set, EINA_FALSE);
return set(model, position, child);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
- del = _eina_model_interface_value_find_offset
+ del = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, del));
EINA_SAFETY_ON_NULL_RETURN_VAL(del, EINA_FALSE);
return del(model, position);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE);
EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE);
- insert_at = _eina_model_interface_value_find_offset
+ insert_at = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, insert_at));
EINA_SAFETY_ON_NULL_RETURN_VAL(insert_at, EINA_FALSE);
return insert_at(model, position, child);
EINA_SAFETY_ON_NULL_RETURN(compare);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK(iface, model);
- sort = _eina_model_interface_value_find_offset
+ sort = _eina_model_interface_find_offset
(iface, offsetof(Eina_Model_Interface_Children, sort));
EINA_SAFETY_ON_NULL_RETURN(sort);
return sort(model, compare);
{
Eina_Value_Struct st = {desc, memory};
Eina_Value *val = eina_model_interface_private_data_get
- (m, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT);
+ (m, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base);
return eina_value_pset(val, &st);
}
EINA_SAFETY_ON_FALSE_RETURN_VAL
(desc->version == EINA_VALUE_STRUCT_DESC_VERSION, EINA_FALSE);
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL
- (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT, model, EINA_FALSE);
+ (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base, model, EINA_FALSE);
return _eina_model_struct_set(model, desc, memory);
}
if (p_memory) *p_memory = NULL;
EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL
- (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT, model, EINA_FALSE);
+ (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base, model, EINA_FALSE);
val = eina_model_interface_private_data_get
- (model, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT);
+ (model, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base);
EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_pget(val, &st), EINA_FALSE);