eina_model: change the way extensions are done.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 31 Jan 2012 15:26:48 +0000 (15:26 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 31 Jan 2012 15:26:48 +0000 (15:26 +0000)
Thanks to Tasn review it was noticed that subclasses using "const void *value"
with sub-structure would have to resolve their methods manually, quite bad.

Then the extension will happen with structures inside structures, as
previously used in Evas_Smart_Class. To allow the system to resolve
the methods and keep it, it is now specificed the type_size.

A new function is added to help extensions:
eina_model_type_method_resolve(), together with few helper macros.

To allow Eina_Model_Type to be augmented with more methods without
breaking the ABI, 4 slots are left there. We expect we got it right
from beginning and these will never be used, but we can never be sure
;-)

Last but not least, similar changes were done to Eina_Model_Interface
for consistency matters.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eina@67635 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/include/eina_model.h
src/lib/eina_model.c

index 7723a70..7fac3c3 100644 (file)
@@ -495,6 +495,7 @@ struct _Eina_Model_Type
 #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 */
@@ -525,9 +526,132 @@ struct _Eina_Model_Type
    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,
@@ -609,6 +733,61 @@ EAPI Eina_Iterator *eina_model_type_child_filtered_iterator_get(const Eina_Model
 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
  *
@@ -628,6 +807,7 @@ 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 */
@@ -637,9 +817,69 @@ struct _Eina_Model_Interface
    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,
@@ -651,6 +891,10 @@ EAPI Eina_Bool eina_model_interface_deep_copy(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
 {
@@ -752,6 +996,7 @@ EAPI extern const char *EINA_MODEL_INTERFACE_NAME_PROPERTIES;
 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);
@@ -890,6 +1135,7 @@ typedef struct _Eina_Model_Interface_Children Eina_Model_Interface_Children;
  */
 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);
index 03d5488..2a8750c 100644 (file)
@@ -339,6 +339,7 @@ struct _Eina_Model_Description
          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 {
@@ -354,8 +355,8 @@ struct _Eina_Model_Description
 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++)
      {
@@ -370,6 +371,20 @@ _eina_model_description_type_fill(Eina_Model_Description *desc, const Eina_Model
              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
@@ -424,14 +439,51 @@ _eina_model_description_type_fill(Eina_Model_Description *desc, const Eina_Model
    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
@@ -859,6 +911,7 @@ _eina_model_description_get_internal(const Eina_Model_Type *type)
    free(desc->cache.ifaces);
  failed_ifaces:
    free(desc->cache.types);
+   free(desc->ops.type.extension);
  failed_type:
    free(desc);
    return NULL;
@@ -880,6 +933,7 @@ _eina_model_description_dispose_internal(Eina_Model_Description *desc)
 
    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);
@@ -1040,6 +1094,8 @@ _eina_model_interface_find_offset(const Eina_Model_Interface *iface, unsigned in
    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;
 
@@ -1053,30 +1109,6 @@ _eina_model_interface_find_offset(const Eina_Model_Interface *iface, unsigned in
    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)
 {
@@ -1945,6 +1977,7 @@ static const Eina_Model_Event_Description _eina_model_type_base_events[] = {
 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 */
@@ -1975,7 +2008,10 @@ static const Eina_Model_Type _EINA_MODEL_TYPE_BASE = {
   _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 */
 };
 
 /*
@@ -2087,7 +2123,7 @@ _eina_model_type_mixin_compare(const Eina_Model *a, const Eina_Model *b, int *cm
    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));
 
@@ -2103,7 +2139,7 @@ _eina_model_type_mixin_compare(const Eina_Model *a, const Eina_Model *b, int *cm
         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));
 
@@ -2280,6 +2316,7 @@ _eina_model_type_mixin_child_sort(Eina_Model *model, Eina_Compare_Cb 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 */
@@ -2310,7 +2347,10 @@ static const Eina_Model_Type _EINA_MODEL_TYPE_MIXIN = {
   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
 
@@ -2468,7 +2508,25 @@ _eina_model_interface_properties_hash_names_list(const Eina_Model *model)
 }
 #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 */
@@ -2479,21 +2537,6 @@ static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_HA
   _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 *
@@ -2615,7 +2658,25 @@ _eina_model_interface_properties_struct_names_list(const Eina_Model *model)
 }
 #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 */
@@ -2626,21 +2687,6 @@ static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_ST
   _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)        \
@@ -2788,7 +2834,25 @@ _eina_model_interface_children_inarray_sort(Eina_Model *model, Eina_Compare_Cb c
 }
 #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 */
@@ -2801,108 +2865,35 @@ static const Eina_Model_Interface_Children _EINA_MODEL_INTERFACE_CHILDREN_INARRA
   _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);
 
 /**
  */
@@ -2985,10 +2976,10 @@ eina_model_init(void)
    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;
@@ -4681,6 +4672,40 @@ eina_model_type_private_data_get(const Eina_Model *model, const Eina_Model_Type
    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
@@ -4804,6 +4829,15 @@ eina_model_interface_deep_copy(const Eina_Model_Interface *iface, const Eina_Mod
    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 ************************************/
 
@@ -4818,7 +4852,7 @@ eina_model_interface_properties_compare(const Eina_Model_Interface *iface, const
    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);
@@ -4831,7 +4865,7 @@ eina_model_interface_properties_load(const Eina_Model_Interface *iface, Eina_Mod
 
    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);
@@ -4844,7 +4878,7 @@ eina_model_interface_properties_unload(const Eina_Model_Interface *iface, Eina_M
 
    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);
@@ -4859,7 +4893,7 @@ eina_model_interface_properties_get(const Eina_Model_Interface *iface, const Ein
    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);
@@ -4875,7 +4909,7 @@ eina_model_interface_properties_set(const Eina_Model_Interface *iface, Eina_Mode
    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);
@@ -4889,7 +4923,7 @@ eina_model_interface_properties_del(const Eina_Model_Interface *iface, Eina_Mode
    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);
@@ -4902,7 +4936,7 @@ eina_model_interface_properties_names_list_get(const Eina_Model_Interface *iface
 
    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);
@@ -4922,7 +4956,7 @@ eina_model_interface_children_compare(const Eina_Model_Interface *iface, const E
    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);
@@ -4935,7 +4969,7 @@ eina_model_interface_children_load(const Eina_Model_Interface *iface, Eina_Model
 
    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);
@@ -4948,7 +4982,7 @@ eina_model_interface_children_unload(const Eina_Model_Interface *iface, Eina_Mod
 
    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);
@@ -4961,7 +4995,7 @@ eina_model_interface_children_count(const Eina_Model_Interface *iface, const Ein
 
    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);
@@ -4974,7 +5008,7 @@ eina_model_interface_children_get(const Eina_Model_Interface *iface, const Eina_
 
    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);
@@ -4987,7 +5021,7 @@ EAPI Eina_Bool eina_model_interface_children_set(const Eina_Model_Interface *ifa
    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);
@@ -5000,7 +5034,7 @@ eina_model_interface_children_del(const Eina_Model_Interface *iface, Eina_Model
 
    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);
@@ -5015,7 +5049,7 @@ eina_model_interface_children_insert_at(const Eina_Model_Interface *iface, Eina_
    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);
@@ -5029,7 +5063,7 @@ eina_model_interface_children_sort(const Eina_Model_Interface *iface, Eina_Model
    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);
@@ -5040,7 +5074,7 @@ _eina_model_struct_set(Eina_Model *m, const Eina_Value_Struct_Desc *desc, void *
 {
    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);
 }
 
@@ -5071,7 +5105,7 @@ eina_model_struct_set(Eina_Model *model, const Eina_Value_Struct_Desc *desc, voi
    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);
 }
@@ -5088,10 +5122,10 @@ eina_model_struct_get(const Eina_Model *model, const Eina_Value_Struct_Desc **p_
    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);