eo: Fix leak in eo_override and allow NULL to reset

eo_override would leak the vtable if called multiple times, this
fixes that. Also, it is now possible to revert back to the original
class' vtable by passing in { NULL, 0 }

I believe it is thus possible to incrementally override more
functions on an object. Absolutely not recommended, but should work.
But it is not possible to selectively revert back to the original
class implementation on a single method. Use eo_super for that,
or revert back the entire object overrides.

PS: Is it normal that we pass in a struct? We never do that in EFL...
This commit is contained in:
Jean-Philippe Andre 2016-07-18 17:44:51 +09:00
parent f18747e6dd
commit cae939e208
1 changed files with 17 additions and 3 deletions

View File

@ -1343,9 +1343,23 @@ eo_override(Eo *eo_id, Eo_Ops ops)
EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
EO_CLASS_POINTER_RETURN_VAL(EO_OVERRIDE_CLASS, klass, EINA_FALSE);
Eo_Vtable *previous = obj->vtable;
obj->vtable = calloc(1, sizeof(*obj->vtable));
_vtable_init(obj->vtable, previous->size);
_vtable_copy_all(obj->vtable, previous);
if (!ops.descs)
{
if (obj->vtable != &obj->klass->vtable)
{
free(obj->vtable);
obj->vtable = (Eo_Vtable *) &obj->klass->vtable;
}
return EINA_TRUE;
}
if (obj->vtable == &obj->klass->vtable)
{
obj->vtable = calloc(1, sizeof(*obj->vtable));
_vtable_init(obj->vtable, previous->size);
_vtable_copy_all(obj->vtable, previous);
}
if (!_eo_class_funcs_set(obj->vtable, &ops, obj->klass, klass, EINA_TRUE))
{