felipealmeida pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=2b12114777cc9e0b7db3894f37dd71f6b5b073b4
commit 2b12114777cc9e0b7db3894f37dd71f6b5b073b4 Author: Larry Jr <larry....@gmail.com> Date: Tue Aug 26 15:54:28 2014 -0300 allow C++ user create new classes inheriting from Eolian generated Classes --- src/Makefile.am | 2 +- src/Makefile_Eolian_Cxx.am | 13 ++++- src/bindings/eo_cxx/eo_private.hh | 17 ++++++ src/examples/eolian_cxx/eolian_cxx_inherit_01.cc | 24 +++++++- .../grammar/inheritance_base_generator.hh | 67 +++++++++++++++++++++- src/tests/eolian_cxx/eolian_cxx_suite.cc | 2 + .../eolian_cxx/eolian_cxx_test_inheritance.cc | 44 ++++++++++++++ src/tests/eolian_cxx/simple.c | 38 ++++++++++++ src/tests/eolian_cxx/simple.eo | 19 ++++++ 9 files changed, 221 insertions(+), 5 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 57b56b7..b0b4884 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in CLEANFILES = BUILT_SOURCES = -EOLIAN_FLAGS = \ +EOLIAN_FLAGS = -I$(srcdir)\ -I$(srcdir)/lib/eo \ -I$(srcdir)/lib/evas/canvas \ -I$(srcdir)/lib/edje \ diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am index 88f1186..d0b8450 100644 --- a/src/Makefile_Eolian_Cxx.am +++ b/src/Makefile_Eolian_Cxx.am @@ -72,6 +72,8 @@ tests/eolian_cxx/d.c \ tests/eolian_cxx/eolian_cxx_test_callback.cc \ tests/eolian_cxx/eolian_cxx_test_address_of.cc \ tests/eolian_cxx/eolian_cxx_test_wrapper.cc \ +tests/eolian_cxx/simple.c \ +tests/eolian_cxx/eolian_cxx_test_inheritance.cc \ tests/eolian_cxx/eolian_cxx_test_generate.cc tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_callback.$(OBJEXT): tests/eolian_cxx/callback.eo.hh @@ -83,7 +85,15 @@ tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-b.$(OBJEXT): tests/eolian_cxx tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-c.$(OBJEXT): tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-d.$(OBJEXT): tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h -CLEANFILES += tests/eolian_cxx/callback.eo.hh tests/eolian_cxx/callback.eo.c tests/eolian_cxx/callback.eo.h \ +tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_inheritance.$(OBJEXT): tests/eolian_cxx/simple.eo.hh + +tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-simple.$(OBJEXT): tests/eolian_cxx/simple.eo.c tests/eolian_cxx/simple.eo.h + +CLEANFILES += tests/eolian_cxx/callback.eo.hh tests/eolian_cxx/callback.eo.c \ +tests/eolian_cxx/callback.eo.h \ +tests/eolian_cxx/simple.eo.c \ +tests/eolian_cxx/simple.eo.h \ +tests/eolian_cxx/simple.eo.hh \ tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \ tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \ tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \ @@ -111,6 +121,7 @@ tests_eolian_cxx_eolian_cxx_suite_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@ endif EXTRA_DIST += tests/eolian_cxx/callback.eo \ +tests/eolian_cxx/simple.eo \ tests/eolian_cxx/a.eo \ tests/eolian_cxx/b.eo \ tests/eolian_cxx/c.eo \ diff --git a/src/bindings/eo_cxx/eo_private.hh b/src/bindings/eo_cxx/eo_private.hh index a227173..7640890 100644 --- a/src/bindings/eo_cxx/eo_private.hh +++ b/src/bindings/eo_cxx/eo_private.hh @@ -86,6 +86,9 @@ Eo_Class const* do_eo_class_new(Eo_Class_Description& class_desc) template <typename T> struct operation_description_class_size; +template<> +struct operation_description_class_size<efl::eo::base> { static const int value = 0; }; + /// @internal /// /// @brief Provides the operator to convert @p T to @p D. @@ -130,6 +133,9 @@ namespace detail { /// template <typename T> struct operations; +template <> +struct operations<efl::eo::base> { template <typename T> struct type {}; }; + /// @internal /// /// @brief Provides the operations of an extension as well as its @@ -153,6 +159,17 @@ struct Inherit_Private_Data void* this_; }; +} } } // namespace efl { namespace eo { namespace detail { + +namespace efl { namespace eo { namespace detail { +template <typename T> +int initialize_operation_description(efl::eo::detail::tag<efl::eo::base> + , Eo_Op_Description* ops) +{ + (void)ops; + return 0; +} + /// @} } } } // namespace efl { namespace eo { namespace detail { diff --git a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc index b258f05..0e6fce9 100644 --- a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc +++ b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc @@ -30,7 +30,7 @@ struct ColourableCircle } }; - +/* struct ColourableFoo : efl::eo::inherit<ColourableFoo, ::colourable, @@ -40,6 +40,24 @@ struct ColourableFoo : inherit_base(efl::eo::args<::colourable>(size) , efl::eo::args<::colourablesquare>(rgb)) {} +};*/ + +struct ColourableBar + : efl::eo::inherit<ColourableBar, ::colourablesquare> +{ + ColourableBar() + : inherit_base(efl::eo::args<::colourablesquare>(0)) + {} + + int colour_get() + { + int rgb = 0; + eo_do_super(_eo_ptr(), _eo_class(), rgb = ::colourable_colour_get()); + std::cout << "ColourableBar::colour_get(" << this << ") ==> " + << std::hex << rgb << std::endl; + return rgb; + } + }; int @@ -55,6 +73,10 @@ main() int r, g, b; obj2.composite_colour_get(&r, &g, &b); + + ColourableBar obj3; + obj3.composite_colour_get(&r, &g, &b); + assert(r == 0xc0); assert(g == 0xff); assert(b == 0xee); diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh index 9ed55d4..9e10e50 100644 --- a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh +++ b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh @@ -65,6 +65,12 @@ struct inheritance_operations_description inline std::ostream& operator<<(std::ostream& out, inheritance_operations_description const& x) { + extensions_container_type::const_iterator it, first, last; + std::string s; + + first = x._cls.extensions.begin(); + last = x._cls.extensions.end(); + out << "template <typename T>" << endl << "int initialize_operation_description(::efl::eo::detail::tag<" << full_name(x._cls) << ">" << endl @@ -77,6 +83,24 @@ operator<<(std::ostream& out, inheritance_operations_description const& x) { out << inheritance_operation(x._cls, i); } + + out << tab(1) + << "initialize_operation_description<T>(efl::eo::detail::tag<" + << x._cls.parent + << ">(), &ops[" + << x._cls.functions.size() << "]);" << endl; + + s += " + operation_description_class_size<" + x._cls.parent + ">::value"; + + for (it = first; it != last; ++it) + { + out << tab(1) + << "initialize_operation_description<T>(efl::eo::detail::tag<" + << *it << ">(), &ops[" << x._cls.functions.size() << s << "]);" << endl; + + s += " + operation_description_class_size< " + *it + ">::value"; + } + out << tab(1) << "return 0;" << endl << "}" << endl; @@ -144,18 +168,57 @@ struct inheritance_base_operations_size inline std::ostream& operator<<(std::ostream& out, inheritance_base_operations_size const& x) { + extensions_container_type::const_iterator it, first = x._cls.extensions.begin(); + extensions_container_type::const_iterator last = x._cls.extensions.end(); + first = x._cls.extensions.begin(); + out << "template<>" << endl << "struct operation_description_class_size< " << full_name(x._cls) << " >" << endl << "{" << endl << tab(1) << "static const int value = " << x._cls.functions.size() - << ";" << endl + << " + operation_description_class_size<" << class_name(x._cls.parent) << ">::value"; + + for (it = first; it != last; ++it) + { + out << " + operation_description_class_size< " << *it << " >::value"; + } + + out << ";" << endl << "};" << endl << endl; + return out; } + +struct inheritance_base_operations_extensions +{ + eo_class const& _cls; + inheritance_base_operations_extensions(eo_class const& cls) + : _cls(cls) + {} +}; + +inline std::ostream& +operator<<(std::ostream& out, inheritance_base_operations_extensions const& x) +{ + eo_class const& cls = x._cls; + extensions_container_type::const_iterator it, first = cls.extensions.begin(); + extensions_container_type::const_iterator last = cls.extensions.end(); + + out << endl << tab(3) << ": operations< " << class_name(cls.parent) << " >::template type<T>"; + for (it = first; it != last; ++it) + { + out << "," << endl << tab(3) + << "operations< " << *it + << " >::template type<T>"; + } + + return out << endl; +} + struct inheritance_base_operations_function { eo_class const& _cls; @@ -212,7 +275,7 @@ operator<<(std::ostream& out, inheritance_base_operations const& x) << full_name(x._cls) << " >" << endl << "{" << endl << tab(1) << "template <typename T>" << endl - << tab(1) << "struct type" << endl + << tab(1) << "struct type" << inheritance_base_operations_extensions(x._cls) << tab(1) << "{" << endl; functions_container_type::const_iterator it, first = x._cls.functions.begin(), diff --git a/src/tests/eolian_cxx/eolian_cxx_suite.cc b/src/tests/eolian_cxx/eolian_cxx_suite.cc index 56bc99a..7af2de8 100644 --- a/src/tests/eolian_cxx/eolian_cxx_suite.cc +++ b/src/tests/eolian_cxx/eolian_cxx_suite.cc @@ -8,6 +8,7 @@ void eolian_cxx_test_wrapper(TCase* tc); void eolian_cxx_test_generate(TCase* tc); void eolian_cxx_test_callback(TCase* tc); void eolian_cxx_test_address_of(TCase* tc); +void eolian_cxx_test_inheritance(TCase* tc); typedef struct _Eolian_Cxx_Test_Case Eolian_Cxx_Test_Case; struct _Eolian_Cxx_Test_Case @@ -22,6 +23,7 @@ static const Eolian_Cxx_Test_Case etc[] = { { "Eolian-Cxx Generation", eolian_cxx_test_generate }, { "Eolian-Cxx Callback", eolian_cxx_test_callback }, { "Eolian-Cxx Address_of", eolian_cxx_test_address_of }, + { "Eolian-Cxx Inheritance", eolian_cxx_test_inheritance }, { NULL, NULL } }; diff --git a/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc b/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc new file mode 100644 index 0000000..1930717 --- /dev/null +++ b/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc @@ -0,0 +1,44 @@ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <Eo.h> +#include <Ecore.h> + +#include <simple.eo.hh> + +#include <check.h> + +struct bar +: efl::eo::inherit<bar, simple> +{ + bar() + : inherit_base() + {} + + bool simple_get() + { + printf("calling bar::%s\n", __FUNCTION__); + return false; + } +}; + +void foo(simple is) +{ + fail_if(is.simple_get()); +} + +START_TEST(eolian_cxx_test_inheritance_simple) +{ + efl::eo::eo_init i; + bar b; + foo(b); +} +END_TEST + +void +eolian_cxx_test_inheritance(TCase* tc) +{ + tcase_add_test(tc, eolian_cxx_test_inheritance_simple); +} diff --git a/src/tests/eolian_cxx/simple.c b/src/tests/eolian_cxx/simple.c new file mode 100644 index 0000000..c78073c --- /dev/null +++ b/src/tests/eolian_cxx/simple.c @@ -0,0 +1,38 @@ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <Eo.h> +#include <Ecore.h> + +#include <stdlib.h> + +#include "simple.eo.h" + +#define MY_CLASS SIMPLE_CLASS + +static void _simple_eo_base_constructor(Eo *obj, void *pd EINA_UNUSED) +{ + eo_do_super(obj, MY_CLASS, eo_constructor()); +} + +static Eina_Bool _simple_simple_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED) +{ + printf("calling %s\n", __FUNCTION__); + + return EINA_TRUE; +} + +static Eina_Bool _simple_name_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char** name) +{ + static const char* _name= "simple_class"; + + printf("calling %s= simples class\n", __FUNCTION__); + *name = _name; + + return EINA_TRUE; +} + +#include "simple.eo.c" + diff --git a/src/tests/eolian_cxx/simple.eo b/src/tests/eolian_cxx/simple.eo new file mode 100644 index 0000000..764adb7 --- /dev/null +++ b/src/tests/eolian_cxx/simple.eo @@ -0,0 +1,19 @@ +class Simple (Eo.Base) +{ + legacy_prefix: null; + data: null; + methods { + simple_get { + return bool; + } + name_get { + params { + @out const(char)* name; + } + return bool; + } + } + implements { + Eo.Base.constructor; + } +} --