From: tasn Date: Thu, 19 Apr 2012 08:52:25 +0000 (+0000) Subject: Eobj: Added mixin data support. X-Git-Tag: submit/2.0alpha-wayland/20121127.222020~187 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=89ad891a7531daffed60cc23fbbe24af32f79b0f;p=profile%2Fivi%2Feobj.git Eobj: Added mixin data support. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@70324 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/examples/mixin/main.c b/examples/mixin/main.c index 8063bc0..966e474 100644 --- a/examples/mixin/main.c +++ b/examples/mixin/main.c @@ -1,6 +1,8 @@ #include "Eobj.h" #include "simple.h" #include "mixin.h" +#include "mixin2.h" +#include "mixin3.h" #include "../eunit_tests.h" @@ -19,6 +21,14 @@ main(int argc, char *argv[]) eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b), MIXIN_AB_SUM_GET(&sum)); fail_if(sum != a + b + 2); /* 2 for the two mixins... */ + eobj_do(obj, MIXIN_AB_SUM_GET(&sum), MIXIN_AB_SUM_GET(&sum)); + + Mixin2_Public_Data *pd2 = eobj_data_get(obj, MIXIN2_CLASS); + fail_if(pd2->count != 6); + + Mixin3_Public_Data *pd3 = eobj_data_get(obj, MIXIN3_CLASS); + fail_if(pd3->count != 9); + eobj_unref(obj); eobj_shutdown(); return 0; diff --git a/examples/mixin/mixin2.c b/examples/mixin/mixin2.c index b3e2cfa..4250615 100644 --- a/examples/mixin/mixin2.c +++ b/examples/mixin/mixin2.c @@ -10,13 +10,15 @@ static const Eobj_Class *_my_class = NULL; static void -_ab_sum_get(Eobj *obj, void *class_data __UNUSED__, va_list *list) +_ab_sum_get(Eobj *obj, void *class_data, va_list *list) { + Mixin2_Public_Data *pd = class_data; int *sum = va_arg(*list, int *); printf("%s %s\n", eobj_class_name_get(_my_class), __func__); eobj_do_super(obj, MIXIN_AB_SUM_GET(sum)); ++*sum; + pd->count += 2; { int _a, _b; @@ -58,7 +60,7 @@ mixin2_class_get(void) EOBJ_CLASS_TYPE_MIXIN, EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), NULL, - 0, + sizeof(Mixin2_Public_Data), _constructor, _destructor, _class_constructor, diff --git a/examples/mixin/mixin2.h b/examples/mixin/mixin2.h index 26d22d2..1a73fd4 100644 --- a/examples/mixin/mixin2.h +++ b/examples/mixin/mixin2.h @@ -3,6 +3,11 @@ #include "Eobj.h" +typedef struct +{ + int count; +} Mixin2_Public_Data; + #define MIXIN2_CLASS mixin2_class_get() const Eobj_Class *mixin2_class_get(void) EINA_CONST; diff --git a/examples/mixin/mixin3.c b/examples/mixin/mixin3.c index a992cb9..802b024 100644 --- a/examples/mixin/mixin3.c +++ b/examples/mixin/mixin3.c @@ -12,11 +12,13 @@ static const Eobj_Class *_my_class = NULL; static void _ab_sum_get(Eobj *obj, void *class_data __UNUSED__, va_list *list) { + Mixin3_Public_Data *pd = class_data; int *sum = va_arg(*list, int *); printf("%s %s\n", eobj_class_name_get(_my_class), __func__); eobj_do_super(obj, MIXIN_AB_SUM_GET(sum)); ++*sum; + pd->count += 3; { int _a, _b; @@ -58,7 +60,7 @@ mixin3_class_get(void) EOBJ_CLASS_TYPE_MIXIN, EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), NULL, - 0, + sizeof(Mixin3_Public_Data), _constructor, _destructor, _class_constructor, diff --git a/examples/mixin/mixin3.h b/examples/mixin/mixin3.h index 12193fb..d2ce840 100644 --- a/examples/mixin/mixin3.h +++ b/examples/mixin/mixin3.h @@ -3,6 +3,11 @@ #include "Eobj.h" +typedef struct +{ + int count; +} Mixin3_Public_Data; + #define MIXIN3_CLASS mixin3_class_get() const Eobj_Class *mixin3_class_get(void) EINA_CONST; diff --git a/lib/eobj.c b/lib/eobj.c index aeae1bf..2eccaa7 100644 --- a/lib/eobj.c +++ b/lib/eobj.c @@ -63,6 +63,9 @@ struct _Eobj { }) #define OP_SUB_ID_GET(op) ((op) & 0xffff) +#define EOBJ_ALIGN_SIZE(size) \ + ((size) + (sizeof(void *) - ((size) % sizeof(void *)))) + /* Structure of Eobj_Op is: * 16bit: class * 16bit: op. @@ -91,6 +94,12 @@ typedef struct const Eobj_Class *klass; } Eobj_Extension_Node; +typedef struct +{ + const Eobj_Class *klass; + size_t offset; +} Eobj_Extension_Data_Offset; + struct _Eobj_Class { Eobj_Class_Id class_id; @@ -99,6 +108,9 @@ struct _Eobj_Class Dich_Chain1 chain[DICH_CHAIN1_SIZE]; Eina_Inlist *extensions; + Eobj_Extension_Data_Offset *extn_data_off; + size_t extn_data_size; + const Eobj_Class **mro; size_t data_offset; /* < Offset of the data within object data. */ @@ -600,7 +612,11 @@ eobj_class_free(Eobj_Class *klass) } } - free(klass->mro); + if (klass->mro) + free(klass->mro); + + if (klass->extn_data_off) + free(klass->extn_data_off); free(klass); } @@ -742,9 +758,7 @@ eobj_class_new(const Eobj_Class_Description *desc, const Eobj_Class *parent, ... /* Update the current offset. */ /* FIXME: Make sure this alignment is enough. */ klass->data_offset = klass->parent->data_offset + - klass->parent->desc->data_size + - (sizeof(void *) - - (klass->parent->desc->data_size % sizeof(void *))); + EOBJ_ALIGN_SIZE(klass->parent->desc->data_size); } if (!_eobj_class_check_op_descs(klass)) @@ -757,6 +771,47 @@ eobj_class_new(const Eobj_Class_Description *desc, const Eobj_Class *parent, ... goto cleanup; } + /* create MIXIN offset table. */ + { + const Eobj_Class **mro_itr = klass->mro; + Eobj_Extension_Data_Offset *extn_data_itr; + size_t extn_num = 0; + size_t extn_data_off = klass->data_offset + + EOBJ_ALIGN_SIZE(klass->desc->data_size); + + /* FIXME: Make faster... */ + while (*mro_itr) + { + if (((*mro_itr)->desc->type == EOBJ_CLASS_TYPE_MIXIN) && + ((*mro_itr)->desc->data_size > 0)) + { + extn_num++; + } + mro_itr++; + } + + klass->extn_data_off = calloc(extn_num + 1, + sizeof(*klass->extn_data_off)); + + extn_data_itr = klass->extn_data_off; + mro_itr = klass->mro; + while (*mro_itr) + { + if (((*mro_itr)->desc->type == EOBJ_CLASS_TYPE_MIXIN) && + ((*mro_itr)->desc->data_size > 0)) + { + extn_data_itr->klass = *mro_itr; + extn_data_itr->offset = extn_data_off; + + extn_data_off += EOBJ_ALIGN_SIZE(extn_data_itr->klass->desc->data_size); + extn_data_itr++; + } + mro_itr++; + } + + klass->extn_data_size = extn_data_off; + } + klass->class_id = ++_eobj_classes_last_id; { /* FIXME: Handle errors. */ @@ -796,7 +851,8 @@ eobj_add(const Eobj_Class *klass, Eobj *parent) obj->refcount++; - obj->data_blob = calloc(1, klass->data_offset + klass->desc->data_size); + obj->data_blob = calloc(1, klass->data_offset + klass->desc->data_size + + klass->extn_data_size); _eobj_kls_itr_init(obj, EOBJ_NOOP); eobj_constructor_error_unset(obj); @@ -1089,9 +1145,29 @@ eobj_data_get(Eobj *obj, const Eobj_Class *klass) /* FIXME: Add a check that this is of the right klass and we don't seg. * Probably just return NULL. */ if (klass->desc->data_size > 0) - return ((char *) obj->data_blob) + klass->data_offset; - else - return NULL; + { + if (klass->desc->type == EOBJ_CLASS_TYPE_MIXIN) + { + Eobj_Extension_Data_Offset *doff_itr = + eobj_class_get(obj)->extn_data_off; + + if (!doff_itr) + return NULL; + + while (doff_itr->klass) + { + if (doff_itr->klass == klass) + return ((char *) obj->data_blob) + doff_itr->offset; + doff_itr++; + } + } + else + { + return ((char *) obj->data_blob) + klass->data_offset; + } + } + + return NULL; } EAPI Eina_Bool