summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2020-03-17 09:19:53 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-03-17 12:11:21 +0100
commit7b74a5deb5f93852570c8d53225b99d121be0d61 (patch)
treeb683e45421e4c7b946f56f0fe74e95be93e0fb2f
parentda5e3c2f7ef2db81627b470d4f9c12783e9ac812 (diff)
downloadefl-7b74a5deb5f93852570c8d53225b99d121be0d61.tar.gz
wip
-rw-r--r--src/lib/eo/eo.c68
-rw-r--r--src/lib/eo/eo_private.h2
-rw-r--r--src/tests/eo/suite/eo_test_general.c8
3 files changed, 61 insertions, 17 deletions
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 7b3772e2c5..6941528358 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -269,9 +269,9 @@ _eo_class_isa_func(Eo *eo_id EINA_UNUSED, void *class_data EINA_UNUSED)
}
static void
-_vtable_dump2(_Efl_Class *klass)
+_vtable_dump2(Eo_Vtable2 *vtable)
{
- const Eo_Vtable2 *vtable = &klass->vtable2;
+ //const Eo_Vtable2 *vtable = &klass->vtable2;
for (int i = 0; i < vtable->size; ++i)
{
Eo_Vtable_Node *node = &vtable->chain[i];
@@ -279,7 +279,7 @@ _vtable_dump2(_Efl_Class *klass)
printf("-> %s %p\n", _eo_classes[i]->desc->name, node->funcs);
for (int j = 0; j < node->count; ++j)
{
- printf(" %s;%p;%s\n", klass->desc->name, node->funcs[j].func, node->funcs[j].src ? node->funcs[j].src->desc->name : NULL);
+ printf(" %p;%s\n", node->funcs[j].func, node->funcs[j].src ? node->funcs[j].src->desc->name : NULL);
}
}
}
@@ -340,6 +340,18 @@ _vtable_init2(Eo_Vtable2 *vtable)
asdf_allocated_memory += vtable->size * sizeof(Eo_Vtable_Node);
}
+static void
+_vtable_copy_all2(Eo_Vtable2 *dest, const Eo_Vtable2 *src)
+{
+ for (int i = 0; i < dest->size; ++i)
+ {
+ if (src->chain[i].funcs)
+ {
+ dest->chain[i] = src->chain[i];
+ }
+ }
+}
+
/**
* Fills the node of the passed class id with a empty none NULL pointer.
* This is used to indicate that a specific node has a normal 0 size, but is set.
@@ -508,7 +520,8 @@ _vtable_func_set2(Eo_Vtable2 *vtable, const _Efl_Class *klass,
if (klass->parent && klass->parent->vtable2.size > class_id)
hirachy_node = &klass->parent->vtable2.chain[class_id];
-
+ if (hierarchy_klass)
+ hirachy_node = &hierarchy_klass->vtable2.chain[class_id];
node = &vtable->chain[class_id];
EINA_SAFETY_ON_NULL_RETURN_VAL(node->funcs, EINA_FALSE);
@@ -769,7 +782,7 @@ _efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Da
obj = _obj;
klass = _obj->klass;
- vtable = &klass->vtable2;
+ vtable = EO_VTABLE2(obj);
if (EINA_UNLIKELY(_obj->cur_klass != NULL))
{
// YES this is a goto with a label to return. this is a
@@ -1049,7 +1062,8 @@ _eo_class_funcs_set(Eo_Vtable *vtable, Eo_Vtable2 *vtable2, const Efl_Object_Ops
DBG("Set functions for class '%s':%p", klass->desc->name, klass);
- _vtable_insert_empty_funcs(vtable2, class_id);
+ if (!override_only)
+ _vtable_insert_empty_funcs(vtable2, class_id);
if (!op_descs || !ops->count)
return EINA_TRUE;
@@ -1090,8 +1104,11 @@ _eo_class_funcs_set(Eo_Vtable *vtable, Eo_Vtable2 *vtable2, const Efl_Object_Ops
}
}
- //Before setting any real functions, allocate the node that will contain all the functions
- _vtable_prepare_empty_node2(vtable2, number_of_new_functions, class_id);
+ if (!override_only)
+ {
+ //Before setting any real functions, allocate the node that will contain all the functions
+ _vtable_prepare_empty_node2(vtable2, number_of_new_functions, class_id);
+ }
for (i = 0, j = 0, op_desc = op_descs; i < ops->count; i++, op_desc++)
{
@@ -1143,7 +1160,6 @@ _eo_class_funcs_set(Eo_Vtable *vtable, Eo_Vtable2 *vtable2, const Efl_Object_Ops
if (!_vtable_func_set2(vtable2, klass, override_class, op2, op_desc->func, EINA_TRUE))
return EINA_FALSE;
}
-
return EINA_TRUE;
}
@@ -2148,6 +2164,7 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
if (ops)
{
Eo_Vtable *vtable = obj->opt->vtable;
+ Eo_Vtable2 *vtable2 = obj->opt->vtable2;
if (!vtable)
{
@@ -2155,20 +2172,44 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
_vtable_init(vtable, obj->klass->vtable.size);
_vtable_copy_all(vtable, &obj->klass->vtable);
}
+ if (!vtable2)
+ {
+ vtable2 = calloc(1, sizeof(*vtable2));
+ _vtable_init2(vtable2);
+ _vtable_copy_all2(vtable2, &obj->klass->vtable2);
+ }
- /* FIXME */
- if (!_eo_class_funcs_set(vtable, NULL, ops, obj->klass, klass, 0, EINA_TRUE, obj->klass->base_id2))
+ //copy all the vtable nodes that we are going to change later on
+ Eina_Bool hitmap[vtable2->size];
+ memset(hitmap, 0, sizeof(hitmap));
+ for (unsigned int i = 0; i < ops->count; i++)
+ {
+ Efl_Object_Op op = _efl_object_api_op_id_get_internal2(ops->descs[i].api_func);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(op != EFL_NOOP, EINA_FALSE);
+ short class_id = EFL_OBJECT_OP_CLASS_PART(op);
+ if (!hitmap[class_id])
+ {
+ //copy all the nodes that we need
+ const Eo_Vtable_Node node = vtable2->chain[class_id];
+ _vtable_copy_node2(&vtable2->chain[class_id], &node);
+ hitmap[class_id] = EINA_TRUE;
+ }
+ }
+ if (!_eo_class_funcs_set(vtable, vtable2, ops, obj->klass, klass, 0, EINA_TRUE, obj->klass->base_id2))
{
ERR("Failed to override functions for %s@%p. All previous "
"overrides have been reset.", obj->klass->desc->name, eo_id);
if (obj->opt->vtable == vtable)
- EO_OPTIONAL_COW_SET(obj, vtable, NULL);
+ {
+ EO_OPTIONAL_COW_SET(obj, vtable, NULL);
+ EO_OPTIONAL_COW_SET(obj, vtable2, NULL);
+ }
else
_vtable_free(vtable);
goto err;
}
-
EO_OPTIONAL_COW_SET(obj, vtable, vtable);
+ EO_OPTIONAL_COW_SET(obj, vtable2, vtable2);
}
else
{
@@ -2176,6 +2217,7 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
{
_vtable_free(obj->opt->vtable);
EO_OPTIONAL_COW_SET(obj, vtable, NULL);
+ EO_OPTIONAL_COW_SET(obj, vtable2, NULL);
}
}
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index c3bfcf8395..ec5a90bf8b 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -96,6 +96,7 @@ struct _Eo_Header
struct _Efl_Object_Optional
{
Eo_Vtable *vtable;
+ Eo_Vtable2 *vtable2;
Eina_List *composite_objects;
Efl_Del_Intercept del_intercept;
};
@@ -153,6 +154,7 @@ extern Eina_Cow *efl_object_optional_cow;
EO_OPTIONAL_COW_END(_obj##_cow, _obj); \
}} while (0)
#define EO_VTABLE(_obj) ((_obj)->opt->vtable ?: &((_obj)->klass->vtable))
+#define EO_VTABLE2(_obj) ((_obj)->opt->vtable2 ?: &((_obj)->klass->vtable2))
typedef void (*Eo_Op_Func_Type)(Eo *, void *class_data);
diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c
index ae026a27f4..7022714fcd 100644
--- a/src/tests/eo/suite/eo_test_general.c
+++ b/src/tests/eo/suite/eo_test_general.c
@@ -1849,10 +1849,10 @@ EFL_END_TEST
void eo_test_general(TCase *tc)
{
- tcase_add_test(tc, eo_simple);
- tcase_add_test(tc, eo_singleton);
+ /*tcase_add_test(tc, eo_simple);
+ tcase_add_test(tc, eo_singleton);*/
tcase_add_test(tc, efl_object_override_tests);
- tcase_add_test(tc, eo_test_class_replacement);
+ /*tcase_add_test(tc, eo_test_class_replacement);
tcase_add_test(tc, eo_signals);
tcase_add_test(tc, efl_data_fetch);
tcase_add_test(tc, efl_data_safe_fetch);
@@ -1876,5 +1876,5 @@ void eo_test_general(TCase *tc)
tcase_add_test(tc, efl_object_destruct_test);
tcase_add_test(tc, efl_object_auto_unref_test);
tcase_add_test(tc, efl_object_size);
- tcase_add_test(tc, eo_test_class_type);
+ tcase_add_test(tc, eo_test_class_type);*/
}