eolian: allow extending eolian-generated classes from within C

If you define either the macro MY_CLASS_EXTRA_OPS for normal
methods/properties or MY_CLASS_EXTRA_CLASS_OPS for class methods
or properties, which contains a comma-delimited list of ops defs
(i.e. EFL_OBJECT_OP_FUNC(...), ...) right before including the
generated my_class.eo.c file, the definitions from these will
be included in the actual class. This can be used to override
certain things in a class internally without exposing it to
Eolian, or for testing/debugging.
This commit is contained in:
Daniel Kolesa 2017-04-13 15:56:15 +02:00
parent 8b95b78dee
commit 53fef30db0
3 changed files with 65 additions and 22 deletions

View File

@ -532,12 +532,13 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
}
eina_iterator_free(itr);
char *cnamel = NULL;
eo_gen_class_names_get(cl, NULL, NULL, &cnamel);
char *cnamel = NULL, *cnameu = NULL;
eo_gen_class_names_get(cl, NULL, &cnameu, &cnamel);
eina_strbuf_append(buf, "\nstatic Eina_Bool\n_");
eina_strbuf_append(buf, cnamel);
eina_strbuf_append(buf, "_class_initializer(Efl_Class *klass)\n{\n");
eina_strbuf_append(buf, " const Efl_Object_Ops *opsp = NULL, *copsp = NULL;\n\n");
Eina_Strbuf *ops = eina_strbuf_new(), *cops = eina_strbuf_new();
@ -584,37 +585,51 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
}
eina_iterator_free(itr);
/* strip the final comma before appending */
if (eina_strbuf_length_get(ops))
{
eina_strbuf_remove(ops, eina_strbuf_length_get(ops) - 2,
eina_strbuf_length_get(ops));
eina_strbuf_append(ops, "\n );\n");
/* make sure the extras are defined */
eina_strbuf_append_printf(buf, "#ifndef %s_EXTRA_OPS\n", cnameu);
eina_strbuf_append_printf(buf, "#define %s_EXTRA_OPS\n", cnameu);
eina_strbuf_append(buf, "#endif\n\n");
eina_strbuf_append_printf(ops, " %s_EXTRA_OPS\n );\n", cnameu);
eina_strbuf_append(buf, eina_strbuf_string_get(ops));
eina_strbuf_append(buf, " opsp = &ops;\n\n");
}
else
{
/* no predefined, but if custom ones are required define it anyway */
eina_strbuf_append_printf(buf, "#ifdef %s_EXTRA_OPS\n", cnameu);
eina_strbuf_append_printf(buf, " EFL_OPS_DEFINE(ops, %s_EXTRA_OPS);\n", cnameu);
eina_strbuf_append(buf, " opsp = &ops;\n");
eina_strbuf_append(buf, "#endif\n\n");
}
if (eina_strbuf_length_get(cops))
{
eina_strbuf_remove(cops, eina_strbuf_length_get(cops) - 2,
eina_strbuf_length_get(cops));
eina_strbuf_append(cops, "\n );\n");
eina_strbuf_append_printf(buf, "#ifndef %s_EXTRA_CLASS_OPS\n", cnameu);
eina_strbuf_append_printf(buf, "#define %s_EXTRA_CLASS_OPS\n", cnameu);
eina_strbuf_append(buf, "#endif\n\n");
eina_strbuf_append_printf(cops, " %s_EXTRA_CLASS_OPS\n );\n", cnameu);
eina_strbuf_append(buf, eina_strbuf_string_get(cops));
eina_strbuf_append(buf, " copsp = &cops;\n\n");
}
else
{
eina_strbuf_append_printf(buf, "#ifdef %s_EXTRA_CLASS_OPS\n", cnameu);
eina_strbuf_append_printf(buf, " EFL_OPS_DEFINE(cops, %s_EXTRA_CLASS_OPS);\n", cnameu);
eina_strbuf_append(buf, " copsp = &cops;\n");
eina_strbuf_append(buf, "#endif\n\n");
}
eina_strbuf_append(buf, " return efl_class_functions_set(klass, ");
if (eina_strbuf_length_get(ops))
eina_strbuf_append(buf, "&ops, ");
else
eina_strbuf_append(buf, "NULL, ");
if (eina_strbuf_length_get(cops))
eina_strbuf_append(buf, "&cops);\n");
else
eina_strbuf_append(buf, "NULL);\n");
eina_strbuf_append(buf, " return efl_class_functions_set(klass, opsp, copsp);\n");
eina_strbuf_free(ops);
eina_strbuf_free(cops);
eina_strbuf_append(buf, "}\n\n");
free(cnameu);
free(cnamel);
return EINA_TRUE;

View File

@ -29,14 +29,28 @@ EOAPI EFL_FUNC_BODYV(efl_canvas_object_simple_bar, int *, NULL, EFL_FUNC_CALL(x)
static Eina_Bool
_class_simple_class_initializer(Efl_Class *klass)
{
const Efl_Object_Ops *opsp = NULL, *copsp = NULL;
#ifndef CLASS_SIMPLE_EXTRA_OPS
#define CLASS_SIMPLE_EXTRA_OPS
#endif
EFL_OPS_DEFINE(ops,
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_set, _class_simple_a_set),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_get, _class_simple_a_get),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_b_set, _class_simple_b_set),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_foo, __eolian_class_simple_foo),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_bar, _class_simple_bar)
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_bar, _class_simple_bar),
CLASS_SIMPLE_EXTRA_OPS
);
return efl_class_functions_set(klass, &ops, NULL);
opsp = &ops;
#ifdef CLASS_SIMPLE_EXTRA_CLASS_OPS
EFL_OPS_DEFINE(cops, CLASS_SIMPLE_EXTRA_CLASS_OPS);
copsp = &cops;
#endif
return efl_class_functions_set(klass, opsp, copsp);
}
static const Efl_Class_Description _class_simple_class_desc = {

View File

@ -67,6 +67,12 @@ static void __eolian_override_base_z_get(Eo *obj EINA_UNUSED, Override_Data *pd,
static Eina_Bool
_override_class_initializer(Efl_Class *klass)
{
const Efl_Object_Ops *opsp = NULL, *copsp = NULL;
#ifndef OVERRIDE_EXTRA_OPS
#define OVERRIDE_EXTRA_OPS
#endif
EFL_OPS_DEFINE(ops,
EFL_OBJECT_OP_FUNC(override_a_set, NULL),
EFL_OBJECT_OP_FUNC(override_a_get, _override_a_get),
@ -78,9 +84,17 @@ _override_class_initializer(Efl_Class *klass)
EFL_OBJECT_OP_FUNC(override_bar, __eolian_override_bar),
EFL_OBJECT_OP_FUNC(base_constructor, _override_base_constructor),
EFL_OBJECT_OP_FUNC(base_z_set, __eolian_override_base_z_set),
EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get)
EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get),
OVERRIDE_EXTRA_OPS
);
return efl_class_functions_set(klass, &ops, NULL);
opsp = &ops;
#ifdef OVERRIDE_EXTRA_CLASS_OPS
EFL_OPS_DEFINE(cops, OVERRIDE_EXTRA_CLASS_OPS);
copsp = &cops;
#endif
return efl_class_functions_set(klass, opsp, copsp);
}
static const Efl_Class_Description _override_class_desc = {