summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSavio Sena <savio@expertisesolutions.com.br>2014-05-03 00:55:51 +0200
committerCedric Bail <cedric.bail@free.fr>2014-05-03 00:56:32 +0200
commit46b6e8a563bd429690e7bffba4e98d06aa40798d (patch)
treeb7a2aebfc32bcc6d7a2600072a00d69a9f68d9a1 /src
parent64c6c63725d96f03baf34b660ca71e13b29078c1 (diff)
eolian_cxx: initial version of the EFL C++ Bindings Generator.
Summary: This patch adds 'eolian_cxx' -- a C++ bindings generator -- to the EFL tree. Eolian Cxx uses Eolian API to read .eo files and generate .eo.hh. It relies/depends on Eo Cxx and Eina Cxx (both non-generated bindings). src/bin/eolian_cxx: The eolian_cxx program. src/lib/eolian_cxx: A header-only library that implements the C++ code generation that binds the .eo classes. =Examples= src/examples/eolian_cxx/eolian_cxx_simple_01.cc: The simplest example, it just uses some "dummy" generated C++ classes. src/examples/eolian_cxx/eolian_cxx_inherit_01.cc: Illustrates how pure C++ classes inherit from .eo generated classes. src/examples/evas/evas_cxx_rectangle.cc: More realistic example using the generated bindings Evas Cxx. Still a bit shallow because we don't have full fledged .eo descriptions yet, but will be improved. =Important= The generated code is not supported and not a stable API/ABI. It is here to gather people interest and get review before we set things in stone for release 1.11. @feature Reviewers: cedric, smohanty, raster, stefan_schmidt CC: felipealmeida, JackDanielZ, cedric, stefan Differential Revision: https://phab.enlightenment.org/D805 Signed-off-by: Cedric Bail <cedric.bail@free.fr>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/Makefile_Ecore_Audio_Cxx.am58
-rw-r--r--src/Makefile_Ecore_Cxx.am48
-rw-r--r--src/Makefile_Edje_Cxx.am62
-rw-r--r--src/Makefile_Eet_Cxx.am4
-rw-r--r--src/Makefile_Eo_Cxx.am16
-rw-r--r--src/Makefile_Eolian_Cxx.am46
-rw-r--r--src/Makefile_Eolian_Cxx_Helper.am19
-rw-r--r--src/Makefile_Evas_Cxx.am76
-rw-r--r--src/bin/eolian_cxx/.gitignore1
-rw-r--r--src/bin/eolian_cxx/comments.cc110
-rw-r--r--src/bin/eolian_cxx/comments.hh29
-rw-r--r--src/bin/eolian_cxx/convert.cc304
-rw-r--r--src/bin/eolian_cxx/convert.hh9
-rw-r--r--src/bin/eolian_cxx/eo_read.h62
-rw-r--r--src/bin/eolian_cxx/eolian_cxx.cc337
-rw-r--r--src/bin/eolian_cxx/safe_strings.hh28
-rw-r--r--src/bindings/ecore_cxx/Ecore.hh4
-rw-r--r--src/bindings/eo_cxx/Eo.hh9
-rw-r--r--src/bindings/eo_cxx/eo_base.hh229
-rw-r--r--src/bindings/eo_cxx/eo_inherit.hh137
-rw-r--r--src/bindings/eo_cxx/eo_inherit_bindings.hh347
-rw-r--r--src/bindings/eo_cxx/eo_init.hh38
-rw-r--r--src/bindings/eo_cxx/eo_ops.hh141
-rw-r--r--src/bindings/eo_cxx/eo_private.hh160
-rw-r--r--src/bindings/eo_cxx/eo_wref.hh126
-rw-r--r--src/examples/eolian_cxx/.gitignore3
-rw-r--r--src/examples/eolian_cxx/Makefile.am114
-rw-r--r--src/examples/eolian_cxx/colourable.c165
-rw-r--r--src/examples/eolian_cxx/colourable.eo63
-rw-r--r--src/examples/eolian_cxx/colourablesquare.c91
-rw-r--r--src/examples/eolian_cxx/colourablesquare.eo23
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_inherit_01.cc69
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_simple_01.cc35
-rw-r--r--src/examples/evas/Makefile.am15
-rw-r--r--src/examples/evas/evas_cxx_rectangle.cc56
-rw-r--r--src/lib/.gitignore5
-rw-r--r--src/lib/eolian_cxx/Eolian_Cxx.hh37
-rw-r--r--src/lib/eolian_cxx/eo_generate.hh20
-rw-r--r--src/lib/eolian_cxx/eo_types.hh89
-rw-r--r--src/lib/eolian_cxx/eo_validate.hh91
-rw-r--r--src/lib/eolian_cxx/grammar/comment.hh42
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh200
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_events.generator.hh95
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh84
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_generator.hh52
-rw-r--r--src/lib/eolian_cxx/grammar/eo_header_generator.hh120
-rw-r--r--src/lib/eolian_cxx/grammar/inheritance_base_generator.hh382
-rw-r--r--src/lib/eolian_cxx/grammar/parameters_generator.hh82
-rw-r--r--src/lib/eolian_cxx/grammar/tab.hh52
-rw-r--r--src/tests/.gitignore1
-rw-r--r--src/tests/ecore_audio_cxx/cxx_compile_test.cc14
-rw-r--r--src/tests/ecore_cxx/cxx_compile_test.cc13
-rw-r--r--src/tests/edje_cxx/cxx_compile_test.cc14
-rw-r--r--src/tests/evas_cxx/cxx_compile_test.cc15
55 files changed, 4442 insertions, 8 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 60d4b3d40e..2e9a133900 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,7 +56,9 @@ include Makefile_Ecore_IMF.am
56include Makefile_Ecore_IMF_Evas.am 56include Makefile_Ecore_IMF_Evas.am
57include Makefile_Ecore_Evas.am 57include Makefile_Ecore_Evas.am
58include Makefile_Ecore_Audio.am 58include Makefile_Ecore_Audio.am
59include Makefile_Ecore_Audio_Cxx.am
59include Makefile_Ecore_Avahi.am 60include Makefile_Ecore_Avahi.am
61include Makefile_Evas_Cxx.am
60include Makefile_Embryo.am 62include Makefile_Embryo.am
61include Makefile_Eio.am 63include Makefile_Eio.am
62include Makefile_Eldbus.am 64include Makefile_Eldbus.am
@@ -68,7 +70,10 @@ include Makefile_Emotion.am
68include Makefile_Ethumb.am 70include Makefile_Ethumb.am
69include Makefile_Ethumb_Client.am 71include Makefile_Ethumb_Client.am
70 72
73include Makefile_Eolian_Cxx.am
71include Makefile_Eina_Cxx.am 74include Makefile_Eina_Cxx.am
75include Makefile_Eo_Cxx.am
76include Makefile_Edje_Cxx.am
72 77
73.PHONY: benchmark examples 78.PHONY: benchmark examples
74 79
@@ -97,7 +102,8 @@ examples/eldbus \
97examples/ephysics \ 102examples/ephysics \
98examples/edje \ 103examples/edje \
99examples/emotion \ 104examples/emotion \
100examples/ethumb_client 105examples/ethumb_client \
106examples/eolian_cxx
101if ALWAYS_BUILD_EXAMPLES 107if ALWAYS_BUILD_EXAMPLES
102SUBDIRS += . $(EXAMPLES_SUBDIRS) 108SUBDIRS += . $(EXAMPLES_SUBDIRS)
103endif 109endif
diff --git a/src/Makefile_Ecore_Audio_Cxx.am b/src/Makefile_Ecore_Audio_Cxx.am
new file mode 100644
index 0000000000..edf23a9500
--- /dev/null
+++ b/src/Makefile_Ecore_Audio_Cxx.am
@@ -0,0 +1,58 @@
1
2if HAVE_CXX11
3
4### Generated headers
5
6generated_ecore_audio_cxx_bindings = \
7lib/ecore_audio/ecore_audio.eo.hh \
8lib/ecore_audio/ecore_audio_in.eo.hh \
9lib/ecore_audio/ecore_audio_out.eo.hh \
10lib/ecore_audio/ecore_audio_in_sndfile.eo.hh \
11lib/ecore_audio/ecore_audio_out_sndfile.eo.hh \
12lib/ecore_audio/ecore_audio_out_pulse.eo.hh \
13lib/ecore_audio/ecore_audio_in_tone.eo.hh
14
15BUILT_SOURCES += \
16lib/ecore_audio/Ecore_Audio.hh \
17$(generated_ecore_audio_cxx_bindings)
18
19lib/ecore_audio/Ecore_Audio.hh:
20 @echo -e "#ifndef EFL_CXX_ECORE_AUDIO_HH\n#define EFL_CXX_ECORE_AUDIO_HH\n" > $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh
21 @echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh
22 @for i in $(generated_ecore_audio_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh; done
23 @echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh
24
25installed_ecoreaudiocxxmainheadersdir = $(includedir)/ecore-audio-cxx-@VMAJ@
26dist_installed_ecoreaudiocxxmainheaders_DATA = \
27lib/ecore_audio/Ecore_Audio.hh \
28$(generated_ecore_audio_cxx_bindings)
29
30### Unit tests
31
32if EFL_ENABLE_TESTS
33
34check_PROGRAMS += tests/ecore_audio_cxx/cxx_compile_test
35TESTS += tests/ecore_audio_cxx/cxx_compile_test
36
37tests_ecore_audio_cxx_cxx_compile_test_SOURCES = tests/ecore_audio_cxx/cxx_compile_test.cc
38tests_ecore_audio_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
39-I$(top_srcdir)/src/lib/ecore_audio \
40-I$(top_builddir)/src/lib/ecore_audio \
41-I$(top_srcdir)/src/lib/ecore \
42-I$(top_builddir)/src/lib/ecore \
43-I$(top_srcdir)/src/lib/eo \
44-I$(top_builddir)/src/lib/eo \
45-I$(top_srcdir)/src/bindings/eo_cxx \
46-I$(top_builddir)/src/bindings/eo_cxx \
47-I$(top_srcdir)/src/bindings/ecore_cxx \
48-I$(top_builddir)/src/bindings/ecore_cxx \
49-I$(top_srcdir)/src/bindings/eina_cxx \
50-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_audio_cxx\" \
51-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_audio_cxx\" \
52@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
53tests_ecore_audio_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
54tests_ecore_audio_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
55
56endif
57
58endif
diff --git a/src/Makefile_Ecore_Cxx.am b/src/Makefile_Ecore_Cxx.am
index ff8efdca86..ec2b64a4c2 100644
--- a/src/Makefile_Ecore_Cxx.am
+++ b/src/Makefile_Ecore_Cxx.am
@@ -1,17 +1,43 @@
1 1
2### Library 2### Library
3 3
4installed_ecorecxxmainheadersdir = $(includedir)/ecore_cxx-@VMAJ@ 4installed_ecorecxxmainheadersdir = $(includedir)/ecore-cxx-@VMAJ@
5dist_installed_ecorecxxmainheaders_DATA = \ 5dist_installed_ecorecxxmainheaders_DATA = bindings/ecore_cxx/Ecore.hh
6bindings/ecore_cxx/Ecore.hh 6
7if HAVE_CXX11
8
9generated_ecore_cxx_bindings = \
10lib/ecore/ecore_poll.eo.hh \
11lib/ecore/ecore_job.eo.hh \
12lib/ecore/ecore_idler.eo.hh \
13lib/ecore/ecore_idle_exiter.eo.hh \
14lib/ecore/ecore_animator.eo.hh \
15lib/ecore/ecore_parent.eo.hh
16
17BUILT_SOURCES += \
18lib/ecore/Ecore.eo.hh \
19$(generated_ecore_cxx_bindings)
20
21installed_ecorecxxheadersdir = $(includedir)/ecore-cxx-@VMAJ@
22dist_installed_ecorecxxheaders_DATA = \
23lib/ecore/Ecore.eo.hh \
24$(generated_ecore_cxx_bindings)
25
26lib/ecore/Ecore.eo.hh:
27 @echo -e "#ifndef EFL_CXX_ECORE_HH\n#define EFL_CXX_ECORE_HH\n" > $(top_builddir)/src/lib/ecore/Ecore.eo.hh
28 @echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh
29 @for i in $(generated_ecore_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh; done
30 @echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh
31
32endif
7 33
8### Unit tests 34### Unit tests
9 35
10if EFL_ENABLE_TESTS 36if EFL_ENABLE_TESTS
11if HAVE_CXX11 37if HAVE_CXX11
12 38
13check_PROGRAMS += tests/ecore_cxx/ecore_cxx_suite 39check_PROGRAMS += tests/ecore_cxx/ecore_cxx_suite tests/ecore_cxx/cxx_compile_test
14TESTS += tests/ecore_cxx/ecore_cxx_suite 40TESTS += tests/ecore_cxx/ecore_cxx_suite tests/ecore_cxx/cxx_compile_test
15 41
16tests_ecore_cxx_ecore_cxx_suite_SOURCES = \ 42tests_ecore_cxx_ecore_cxx_suite_SOURCES = \
17tests/ecore_cxx/ecore_cxx_suite.cc \ 43tests/ecore_cxx/ecore_cxx_suite.cc \
@@ -20,6 +46,7 @@ tests/ecore_cxx/ecore_cxx_test_safe_call.cc
20tests_ecore_cxx_ecore_cxx_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ 46tests_ecore_cxx_ecore_cxx_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
21-I$(top_srcdir)/src/bindings/ecore_cxx \ 47-I$(top_srcdir)/src/bindings/ecore_cxx \
22-I$(top_srcdir)/src/bindings/eina_cxx \ 48-I$(top_srcdir)/src/bindings/eina_cxx \
49-I$(top_srcdir)/src/bindings/eo_cxx \
23-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_cxx\" \ 50-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_cxx\" \
24-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_cxx\" \ 51-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_cxx\" \
25@CHECK_CFLAGS@ \ 52@CHECK_CFLAGS@ \
@@ -32,5 +59,16 @@ tests_ecore_cxx_ecore_cxx_suite_LDADD = \
32tests_ecore_cxx_ecore_cxx_suite_DEPENDENCIES = \ 59tests_ecore_cxx_ecore_cxx_suite_DEPENDENCIES = \
33@USE_ECORE_INTERNAL_LIBS@ 60@USE_ECORE_INTERNAL_LIBS@
34 61
62tests_ecore_cxx_cxx_compile_test_SOURCES = tests/ecore_cxx/cxx_compile_test.cc
63tests_ecore_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
64-I$(top_srcdir)/src/bindings/ecore_cxx \
65-I$(top_srcdir)/src/bindings/eina_cxx \
66-I$(top_srcdir)/src/bindings/eo_cxx \
67-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_cxx\" \
68-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_cxx\" \
69@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
70tests_ecore_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
71tests_ecore_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
72
35endif 73endif
36endif 74endif
diff --git a/src/Makefile_Edje_Cxx.am b/src/Makefile_Edje_Cxx.am
new file mode 100644
index 0000000000..094855dbb7
--- /dev/null
+++ b/src/Makefile_Edje_Cxx.am
@@ -0,0 +1,62 @@
1
2if HAVE_CXX11
3
4### Generated headers
5
6generated_edje_cxx_bindings = \
7lib/edje/edje.eo.hh \
8lib/edje/edje_edit.eo.hh
9
10BUILT_SOURCES += \
11lib/edje/Edje.hh \
12$(generated_edje_cxx_bindings)
13
14EXTRA_DIST += \
15lib/edje/Edje.hh \
16$(edje_cxx_bindngs)
17
18installed_edjecxxmainheadersdir = $(includedir)/edje-cxx-@VMAJ@/
19
20dist_installed_edjecxxmainheaders_DATA = \
21lib/edje/Edje.hh \
22$(generated_edje_cxx_bindings)
23
24lib/edje/Edje.hh:
25 @echo -e "#ifndef EFL_CXX_EDJE_HH\n#define EFL_CXX_EDJE_HH\n" > $(top_builddir)/src/lib/edje/Edje.hh
26 @echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/edje/Edje.hh
27 @for i in $(generated_edje_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/edje/Edje.hh; done
28 @echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/edje/Edje.hh
29
30### Unit tests
31
32if EFL_ENABLE_TESTS
33
34check_PROGRAMS += tests/edje_cxx/cxx_compile_test
35TESTS += tests/edje_cxx/cxx_compile_test
36
37tests_edje_cxx_cxx_compile_test_SOURCES = tests/edje_cxx/cxx_compile_test.cc
38tests_edje_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
39-I$(top_srcdir)/src/lib/edje \
40-I$(top_builddir)/src/lib/edje \
41-I$(top_srcdir)/src/lib/evas \
42-I$(top_builddir)/src/lib/evas \
43-I$(top_srcdir)/src/lib/evas/canvas \
44-I$(top_builddir)/src/lib/evas/canvas \
45-I$(top_srcdir)/src/lib/ecore \
46-I$(top_builddir)/src/lib/ecore \
47-I$(top_srcdir)/src/lib/eo \
48-I$(top_builddir)/src/lib/eo \
49-I$(top_srcdir)/src/bindings/eo_cxx \
50-I$(top_builddir)/src/bindings/eo_cxx \
51-I$(top_srcdir)/src/bindings/ecore_cxx \
52-I$(top_builddir)/src/bindings/ecore_cxx \
53-I$(top_srcdir)/src/bindings/eina_cxx \
54-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/edje_cxx\" \
55-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/edje_cxx\" \
56@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
57tests_edje_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
58tests_edje_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
59
60endif
61
62endif
diff --git a/src/Makefile_Eet_Cxx.am b/src/Makefile_Eet_Cxx.am
index b2381aaeda..4686de6c4e 100644
--- a/src/Makefile_Eet_Cxx.am
+++ b/src/Makefile_Eet_Cxx.am
@@ -1,10 +1,10 @@
1 1
2### Library 2### Library
3 3
4installed_eetcxxmainheadersdir = $(includedir)/eet_cxx-@VMAJ@ 4installed_eetcxxmainheadersdir = $(includedir)/eet-cxx-@VMAJ@
5dist_installed_eetcxxmainheaders_DATA = bindings/eet_cxx/Eet.hh 5dist_installed_eetcxxmainheaders_DATA = bindings/eet_cxx/Eet.hh
6 6
7installed_eetcxxheadersdir = $(includedir)/eet_cxx-@VMAJ@/eet_cxx 7installed_eetcxxheadersdir = $(includedir)/eet-cxx-@VMAJ@/eet-cxx
8dist_installed_eetcxxheaders_DATA = \ 8dist_installed_eetcxxheaders_DATA = \
9bindings/eet_cxx/eet_composite.hh \ 9bindings/eet_cxx/eet_composite.hh \
10bindings/eet_cxx/eet_fold.hh \ 10bindings/eet_cxx/eet_fold.hh \
diff --git a/src/Makefile_Eo_Cxx.am b/src/Makefile_Eo_Cxx.am
new file mode 100644
index 0000000000..d33c77c901
--- /dev/null
+++ b/src/Makefile_Eo_Cxx.am
@@ -0,0 +1,16 @@
1
2### Library
3
4installed_eocxxmainheadersdir = $(includedir)/eo-cxx-@VMAJ@/
5dist_installed_eocxxmainheaders_DATA = \
6bindings/eo_cxx/Eo.hh
7
8installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@/
9dist_installed_eocxxheaders_DATA = \
10bindings/eo_cxx/eo_base.hh \
11bindings/eo_cxx/eo_init.hh \
12bindings/eo_cxx/eo_wref.hh \
13bindings/eo_cxx/eo_inherit.hh \
14bindings/eo_cxx/eo_ops.hh \
15bindings/eo_cxx/eo_private.hh \
16bindings/eo_cxx/eo_inherit_bindings.hh
diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am
new file mode 100644
index 0000000000..301f051ebb
--- /dev/null
+++ b/src/Makefile_Eolian_Cxx.am
@@ -0,0 +1,46 @@
1
2### Binary
3
4bin_PROGRAMS += \
5 bin/eolian_cxx/eolian_cxx
6
7bin_eolian_cxx_eolian_cxx_SOURCES = \
8 bin/eolian_cxx/comments.cc \
9 bin/eolian_cxx/comments.hh \
10 bin/eolian_cxx/convert.cc \
11 bin/eolian_cxx/convert.hh \
12 bin/eolian_cxx/eo_read.h \
13 bin/eolian_cxx/safe_strings.hh \
14 bin/eolian_cxx/eolian_cxx.cc
15
16bin_eolian_cxx_eolian_cxx_CFLAGS = \
17 -I$(top_builddir)/src/lib/efl \
18 -I$(top_builddir)/src/lib/eo \
19 -I$(top_srcdir)/src/lib/eo \
20 -I$(top_builddir)/src/lib/eina \
21 -I$(top_srcdir)/src/lib/eina \
22 -I$(top_builddir)/src/lib/eolian \
23 -I$(top_srcdir)/src/lib/eolian
24
25bin_eolian_cxx_eolian_cxx_CXXFLAGS = \
26 -I$(top_builddir)/src/lib/efl \
27 -I$(top_builddir)/src/lib/eo \
28 -I$(top_srcdir)/src/lib/eo \
29 -I$(top_builddir)/src/lib/eina \
30 -I$(top_srcdir)/src/lib/eina \
31 -I$(top_builddir)/src/lib/eolian \
32 -I$(top_srcdir)/src/lib/eolian \
33 -I$(top_builddir)/src/bindings/eina_cxx \
34 -I$(top_srcdir)/src/bindings/eina_cxx \
35 -I$(top_builddir)/src/lib/eolian_cxx \
36 -I$(top_srcdir)/src/lib/eolian_cxx
37
38bin_eolian_cxx_eolian_cxx_LDADD = \
39 @USE_EOLIAN_LIBS@
40
41bin_eolian_cxx_eolian_cxx_DEPENDENCIES = \
42 @USE_EOLIAN_INTERNAL_LIBS@
43
44include Makefile_Eolian_Cxx_Helper.am
45
46CLEANFILES += $(BUILT_SOURCES)
diff --git a/src/Makefile_Eolian_Cxx_Helper.am b/src/Makefile_Eolian_Cxx_Helper.am
new file mode 100644
index 0000000000..3c85669074
--- /dev/null
+++ b/src/Makefile_Eolian_Cxx_Helper.am
@@ -0,0 +1,19 @@
1
2if HAVE_EOLIAN_CXX
3EOLIAN_CXX = @eolian_cxx@
4_EOLIAN_CXX_DEP = @eolian_cxx@
5else
6EOLIAN_CXX = EFL_RUN_IN_TREE=1 $(top_builddir)/src/bin/eolian_cxx/eolian_cxx${EXEEXT}
7_EOLIAN_CXX_DEP = bin/eolian_cxx/eolian_cxx${EXEEXT}
8endif
9
10AM_V_EOLCXX = $(am__v_EOLCXX_@AM_V@)
11am__v_EOLCXX_ = $(am__v_EOLCXX_@AM_DEFAULT_V@)
12am__v_EOLCXX_0 = @echo " EOLCXX " $@;
13
14SUFFIXES += .eo.hh
15
16%.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
17 $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I./$< -o $@
18
19CLEANFILES += $(BUILT_SOURCES)
diff --git a/src/Makefile_Evas_Cxx.am b/src/Makefile_Evas_Cxx.am
new file mode 100644
index 0000000000..5938223a45
--- /dev/null
+++ b/src/Makefile_Evas_Cxx.am
@@ -0,0 +1,76 @@
1
2if HAVE_CXX11
3
4### Generated headers
5
6generated_evas_canvas_cxx_bindings = \
7lib/evas/canvas/evas_line.eo.hh \
8lib/evas/canvas/evas_polygon.eo.hh \
9lib/evas/canvas/evas_rectangle.eo.hh \
10lib/evas/canvas/evas_text.eo.hh \
11lib/evas/canvas/evas_textblock.eo.hh \
12lib/evas/canvas/evas_textgrid.eo.hh \
13lib/evas/canvas/evas_signal_interface.eo.hh \
14lib/evas/canvas/evas_smart.eo.hh \
15lib/evas/canvas/evas_smart_clipped.eo.hh \
16lib/evas/canvas/evas_table.eo.hh \
17lib/evas/canvas/evas_common_interface.eo.hh \
18lib/evas/canvas/evas_object.eo.hh \
19lib/evas/canvas/evas.eo.hh \
20lib/evas/canvas/evas_grid.eo.hh \
21lib/evas/canvas/evas_image.eo.hh \
22lib/evas/canvas/evas_out.eo.hh \
23lib/evas/canvas/evas_draggable_interface.eo.hh \
24lib/evas/canvas/evas_clickable_interface.eo.hh \
25lib/evas/canvas/evas_scrollable_interface.eo.hh \
26lib/evas/canvas/evas_selectable_interface.eo.hh \
27lib/evas/canvas/evas_zoomable_interface.eo.hh \
28lib/evas/canvas/evas_box.eo.hh
29
30BUILT_SOURCES += lib/evas/Evas.hh $(generated_evas_canvas_cxx_bindings)
31
32installed_evascanvasmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/
33dist_installed_evascanvasmainheaders_DATA = lib/evas/Evas.hh
34
35installed_evascanvasmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas
36dist_installed_evascanvasmainheaders_DATA = $(generated_evas_canvas_cxx_bindings)
37
38lib/evas/Evas.hh:
39 @echo -e "#ifndef EFL_CXX_EVAS_HH\n#define EFL_CXX_EVAS_HH\n" > $(top_builddir)/src/lib/evas/Evas.hh
40 @echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/evas/Evas.hh
41 @for i in $(generated_evas_canvas_cxx_bindings); do echo "#include <canvas/$$(basename $$i)>" >> $(top_builddir)/src/lib/evas/Evas.hh; done
42 @echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh
43
44### Unit tests
45
46if EFL_ENABLE_TESTS
47
48check_PROGRAMS += tests/evas_cxx/cxx_compile_test
49TESTS += tests/evas_cxx/cxx_compile_test
50
51tests_evas_cxx_cxx_compile_test_SOURCES = tests/evas_cxx/cxx_compile_test.cc
52tests_evas_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
53-I$(top_srcdir)/src/lib/edje \
54-I$(top_builddir)/src/lib/edje \
55-I$(top_srcdir)/src/lib/evas \
56-I$(top_builddir)/src/lib/evas \
57-I$(top_srcdir)/src/lib/evas/canvas \
58-I$(top_builddir)/src/lib/evas/canvas \
59-I$(top_srcdir)/src/lib/ecore \
60-I$(top_builddir)/src/lib/ecore \
61-I$(top_srcdir)/src/lib/eo \
62-I$(top_builddir)/src/lib/eo \
63-I$(top_srcdir)/src/bindings/eo_cxx \
64-I$(top_builddir)/src/bindings/eo_cxx \
65-I$(top_srcdir)/src/bindings/ecore_cxx \
66-I$(top_builddir)/src/bindings/ecore_cxx \
67-I$(top_srcdir)/src/bindings/eina_cxx \
68-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/evas_cxx\" \
69-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/evas_cxx\" \
70@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
71tests_evas_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
72tests_evas_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
73
74endif
75
76endif
diff --git a/src/bin/eolian_cxx/.gitignore b/src/bin/eolian_cxx/.gitignore
new file mode 100644
index 0000000000..cfe67763b0
--- /dev/null
+++ b/src/bin/eolian_cxx/.gitignore
@@ -0,0 +1 @@
/eolian_cxx
diff --git a/src/bin/eolian_cxx/comments.cc b/src/bin/eolian_cxx/comments.cc
new file mode 100644
index 0000000000..afe725f300
--- /dev/null
+++ b/src/bin/eolian_cxx/comments.cc
@@ -0,0 +1,110 @@
1
2#include "comments.hh"
3#include "safe_strings.hh"
4
5static std::string
6_comment_parameter(Eolian_Function_Parameter param)
7{
8 Eolian_Parameter_Dir direction;
9 Eina_Stringshare *description;
10
11 eolian_parameter_information_get
12 (param, &direction, NULL, NULL, &description);
13
14 std::string doc = "@param";
15 if (direction == EOLIAN_IN_PARAM) doc += " ";
16 else if (direction == EOLIAN_OUT_PARAM) doc += "[out] ";
17 else if (direction == EOLIAN_INOUT_PARAM) doc += "[inout] ";
18 else assert(false);
19
20 doc += safe_strshare(eolian_parameter_name_get(param));
21 doc += " ";
22 doc += safe_str(description);
23
24 return doc;
25}
26
27static std::string
28_comment_parameters_list(const Eina_List *params)
29{
30 std::string doc = "";
31 const Eina_List *it;
32 void *curr;
33 EINA_LIST_FOREACH (params, it, curr)
34 {
35 doc += _comment_parameter
36 (static_cast<Eolian_Function_Parameter>(curr)) + "\n";
37 }
38 return doc;
39}
40
41static std::string
42_comment_brief_and_params(Eolian_Function function,
43 const char *key = EOLIAN_COMMENT)
44{
45 std::string doc = "";
46 std::string func = safe_str(eolian_function_description_get(function, key));
47 if (func != "")
48 {
49 doc += "@brief " + func + "\n\n";
50 }
51 std::string params = _comment_parameters_list(eolian_parameters_list_get(function));
52 if (params != "")
53 {
54 doc += params + "\n";
55 }
56 return doc;
57}
58
59static std::string
60_comment_return(Eolian_Function function,
61 Eolian_Function_Type rettype)
62{
63 std::string doc = "";
64 std::string ret = safe_str(eolian_function_return_type_get(function, rettype));
65 std::string comment = safe_str(eolian_function_return_comment_get(function, rettype));
66 if (ret != "void" && ret != "" && comment != "")
67 {
68 doc = "@return " + comment;
69 }
70 return doc;
71}
72
73namespace detail {
74
75std::string
76eolian_class_comment(const char *classname)
77{
78 return safe_str(eolian_class_description_get(classname));
79}
80
81std::string
82eolian_constructor_comment(Eolian_Function constructor)
83{
84 return _comment_brief_and_params(constructor);
85}
86
87std::string eolian_function_comment(Eolian_Function function)
88{
89 std::string doc = _comment_brief_and_params(function);
90 doc += _comment_return(function, EOLIAN_METHOD);
91 return doc;
92}
93
94std::string eolian_property_getter_comment(Eolian_Function property)
95{
96 std::string doc = _comment_brief_and_params
97 (property, EOLIAN_COMMENT_GET);
98 doc += _comment_return(property, EOLIAN_PROP_GET);
99 return doc;
100}
101
102std::string eolian_property_setter_comment(Eolian_Function property)
103{
104 std::string doc = _comment_brief_and_params
105 (property, EOLIAN_COMMENT_SET);
106 doc += _comment_return(property, EOLIAN_PROP_SET);
107 return doc;
108}
109
110} // namespace detail
diff --git a/src/bin/eolian_cxx/comments.hh b/src/bin/eolian_cxx/comments.hh
new file mode 100644
index 0000000000..3aaf7562ce
--- /dev/null
+++ b/src/bin/eolian_cxx/comments.hh
@@ -0,0 +1,29 @@
1
2#ifndef EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
3#define EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
4
5#include <string>
6
7extern "C"
8{
9#include <Eina.h>
10#include <Eolian.h>
11}
12
13#include <Eolian_Cxx.hh>
14
15namespace detail {
16
17std::string eolian_class_comment(const char *classname);
18
19std::string eolian_constructor_comment(Eolian_Function constructor);
20
21std::string eolian_function_comment(Eolian_Function function);
22
23std::string eolian_property_getter_comment(Eolian_Function function);
24
25std::string eolian_property_setter_comment(Eolian_Function function);
26
27}
28
29#endif // EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc
new file mode 100644
index 0000000000..6672daa54f
--- /dev/null
+++ b/src/bin/eolian_cxx/convert.cc
@@ -0,0 +1,304 @@
1#include <vector>
2#include <algorithm>
3#include <cassert>
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif
8
9#include <Eina.h>
10#include <Eina.hh>
11#include <Eo.h>
12#include <Eolian.h>
13
14#include "eo_types.hh"
15#include "safe_strings.hh"
16#include "comments.hh"
17
18static std::string
19_resolve_param_type(Eolian_Function_Parameter id, bool is_get)
20{
21 Eolian_Parameter_Dir dir;
22 const char *type;
23 bool is_const;
24 std::string res;
25
26 eolian_parameter_information_get(id, &dir, &type, NULL, NULL);
27 is_const = eolian_parameter_const_attribute_get(id, is_get);
28 res = safe_str(type);
29 assert(res != "");
30 if (is_const) res = std::string("const ") + res;
31 if (dir == EOLIAN_OUT_PARAM || dir == EOLIAN_INOUT_PARAM) res += "*";
32 return res;
33}
34
35static efl::eolian::parameters_container_type
36_get_params(const Eina_List *eolian_params, bool is_get = false)
37{
38 const Eina_List *it;
39 void *curr;
40 if (eolian_params == NULL)
41 {
42 return efl::eolian::parameters_container_type();
43 }
44 efl::eolian::parameters_container_type list;
45 EINA_LIST_FOREACH (eolian_params, it, curr)
46 {
47 Eolian_Function_Parameter id =
48 (static_cast<Eolian_Function_Parameter>(curr));
49 list.push_back({
50 _resolve_param_type(id, is_get),
51 safe_strshare(eolian_parameter_name_get(id))
52 });
53 }
54 return list;
55}
56
57static efl::eolian::functions_container_type
58_get_properties(const char *classname)
59{
60 efl::eolian::functions_container_type container;
61
62 std::string cxx_classname = classname;
63 std::transform(cxx_classname.begin(), cxx_classname.end(),
64 cxx_classname.begin(), ::tolower);
65
66 const Eina_List *properties;
67 properties = eolian_class_functions_list_get(classname, EOLIAN_PROPERTY);
68
69 const Eina_List *it;
70 void *curr;
71 std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
72 EINA_LIST_FOREACH (properties, it, curr)
73 {
74 Eolian_Function property = static_cast<Eolian_Function>(curr);
75 Eolian_Function_Type type = eolian_function_type_get(property);
76 std::string name = safe_str(eolian_function_name_get(property));
77 if (type == EOLIAN_PROP_GET || type == EOLIAN_PROPERTY)
78 {
79 const Eina_List *keys_ = eolian_property_keys_list_get(property);
80 efl::eolian::parameters_container_type params = _get_params
81 (eolian_parameters_list_get(property), true);
82 efl::eolian::eo_function getter;
83 getter.type = efl::eolian::eo_function::regular_;
84 getter.name = name + "_get";
85 getter.impl = (prefix != "" ? prefix : cxx_classname) + "_" + getter.name;
86 std::string ret = safe_str
87 (eolian_function_return_type_get(property, EOLIAN_PROP_GET));
88 if (ret == "") ret = "void";
89
90 // if the getter has a single parameter and void return
91 // we translate it to a getter with no parameters that
92 // returns its type.
93 if ((ret == "void") && params.size() == 1)
94 {
95 getter.ret = params[0].type;
96 getter.params.clear();
97 }
98 else // otherwise just create the described getter
99 {
100 getter.ret = ret;
101 getter.params = params;
102 std::transform
103 (params.begin(), params.end(), getter.params.begin(),
104 [](efl::eolian::eo_parameter const& param)
105 {
106 return efl::eolian::eo_parameter
107 { param.type + "*", param.name };
108 });
109 }
110 if (eina_list_count(keys_) > 0)
111 {
112 efl::eolian::parameters_container_type keys = _get_params(keys_, true);
113 keys.reserve(keys.size() + getter.params.size());
114 keys.insert(keys.end(), getter.params.begin(), getter.params.end());
115 getter.params = keys;
116 }
117 getter.comment = detail::eolian_property_getter_comment(property);
118 container.push_back(getter);
119 }
120 if (type == EOLIAN_PROP_SET || type == EOLIAN_PROPERTY)
121 {
122 const Eina_List *keys_ = eolian_property_keys_list_get(property);
123 const Eina_List *args_ = eolian_parameters_list_get(property);
124 Eina_List *params_ = eina_list_merge(eina_list_clone(keys_), eina_list_clone(args_));
125 efl::eolian::parameters_container_type params = _get_params(params_);
126 eina_list_free(params_);
127 efl::eolian::eo_function setter;
128 setter.type = efl::eolian::eo_function::regular_;
129 setter.name = name + "_set";
130 setter.impl = (prefix != "" ? prefix : cxx_classname) + "_" + setter.name;
131 setter.params = params;
132 setter.ret = safe_str(eolian_function_return_type_get
133 (property, EOLIAN_PROP_SET));
134 if (setter.ret == "") setter.ret = "void";
135 setter.comment = detail::eolian_property_setter_comment(property);
136 container.push_back(setter);
137 }
138 }
139 return container;
140}
141
142namespace detail {
143
144void
145convert_eolian_inheritances(efl::eolian::eo_class& cls, const char *classname)
146{
147 const Eina_List *inheritances = eolian_class_inherits_list_get(classname);
148 const Eina_List *it;
149 void *curr;
150
151 if (eina_list_count(inheritances) == 0
152 || eina_list_data_get(inheritances) == NULL)
153 {
154 cls.parent = "efl::eo::base";
155 return;
156 }
157 else
158 {
159 std::string parent =
160 static_cast<const char*>(eina_list_data_get(inheritances));
161 std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
162 // "eo_base" is the Eolian name for EO_BASE_CLASS.
163 cls.parent = (parent == "eo_base" || parent == "") ? "efl::eo::base" : parent;
164 }
165
166 inheritances = eina_list_next(inheritances);
167 EINA_LIST_FOREACH (inheritances, it, curr)
168 {
169 std::string extension = static_cast<const char*>(curr);
170 std::transform
171 (extension.begin(), extension.end(), extension.begin(), ::tolower);
172 cls.extensions.push_back(extension);
173 }
174}
175
176void
177convert_eolian_implements(efl::eolian::eo_class& cls, const char *classname)
178{
179 const Eina_List *it;
180 void *curr;
181 std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
182 const Eina_List *implements = eolian_class_implements_list_get(classname);
183 Eolian_Implement impl_desc;
184 void *impl_desc_;
185 EINA_LIST_FOREACH(eolian_class_implements_list_get(classname), it, impl_desc_)
186 {
187 Eolian_Implement impl_desc = static_cast<Eolian_Implement>(impl_desc_);
188 Eolian_Function_Type func_type;
189 const char *func_name;
190 const char *impl_class;
191 eolian_implement_information_get
192 (impl_desc, &impl_class, &func_name, &func_type);
193#if 1 // XXX only due to a bug in Eolian we have to double-check
194 if(func_type == EOLIAN_UNRESOLVED &&
195 eolian_class_function_find_by_name(impl_class, func_name, EOLIAN_CTOR) != NULL)
196 func_type = EOLIAN_CTOR;
197#endif
198 if (func_type == EOLIAN_CTOR)
199 {
200 efl::eolian::eo_constructor constructor;
201 Eolian_Function eolian_constructor = eolian_class_function_find_by_name
202 (impl_class, func_name, func_type);
203 assert(eolian_constructor != NULL);
204 std::string parent = safe_str(impl_class);
205 if(parent == "Eo_Base") parent = "eo";
206 else std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
207 constructor.name = parent + "_" + safe_str(func_name);
208 constructor.params = _get_params
209 (eolian_parameters_list_get(eolian_constructor));
210 constructor.comment = detail::eolian_constructor_comment
211 (eolian_constructor);
212 cls.constructors.push_back(constructor);
213 }
214 }
215}
216
217void
218convert_eolian_constructors(efl::eolian::eo_class& cls, const char *classname)
219{
220 const Eina_List *it;
221 void *curr;
222 std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
223 const Eina_List *constructors =
224 eolian_class_functions_list_get(classname, EOLIAN_CTOR);
225 EINA_LIST_FOREACH (constructors, it, curr)
226 {
227 Eolian_Function eolian_constructor = static_cast<Eolian_Function>(curr);
228 efl::eolian::eo_constructor constructor;
229 constructor.name = (prefix != "" ? prefix : cls.name) + "_" + safe_str
230 (eolian_function_name_get(eolian_constructor));
231 constructor.params = _get_params
232 (eolian_parameters_list_get(eolian_constructor));
233 constructor.comment = detail::eolian_constructor_comment
234 (eolian_constructor);
235 cls.constructors.push_back(constructor);
236 }
237}
238
239void
240convert_eolian_functions(efl::eolian::eo_class& cls, const char *classname)
241{
242 const Eina_List *it;
243 void *curr;
244
245 const Eina_List *eolian_functions =
246 eolian_class_functions_list_get(classname, EOLIAN_METHOD);
247 EINA_LIST_FOREACH (eolian_functions, it, curr)
248 {
249 efl::eolian::eo_function function;
250 Eolian_Function eolian_function = static_cast<Eolian_Function>(curr);
251 std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
252 // XXX Eolian only provides regular methods so far
253 function.type = efl::eolian::eo_function::regular_;
254 function.name = safe_str(eolian_function_name_get(eolian_function));
255 function.impl = ( prefix != "" ? prefix : cls.name ) + "_" + function.name;
256 function.ret = safe_str(eolian_function_return_type_get
257 (eolian_function, EOLIAN_METHOD));
258 if(function.ret == "") function.ret = "void";
259 function.params = _get_params(eolian_parameters_list_get(eolian_function));
260 function.comment = detail::eolian_function_comment(eolian_function);
261 cls.functions.push_back(function);
262 }
263}
264
265void
266convert_eolian_properties(efl::eolian::eo_class& cls, const char *classname)
267{
268 efl::eolian::functions_container_type properties = _get_properties(classname);
269 cls.functions.insert(cls.functions.end(), properties.begin(), properties.end());
270}
271
272} // namespace detail {
273
274efl::eolian::eo_class
275_cxx_new(const char *classname)
276{
277 using namespace efl::eolian;
278 eo_class cls;
279 Eolian_Class_Type cls_type = ::eolian_class_type_get(classname);
280 if (cls_type == EOLIAN_CLASS_REGULAR) cls.type = eo_class::regular_;
281 else if (cls_type == EOLIAN_CLASS_ABSTRACT) cls.type = eo_class::regular_noninst_;
282 else if (cls_type == EOLIAN_CLASS_MIXIN) cls.type = eo_class::mixin_;
283 else if (cls_type == EOLIAN_CLASS_INTERFACE) cls.type = eo_class::interface_;
284 else { assert(false); }
285 std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
286 cls.name = classname;
287 cls.eo_name = (prefix != "" ? prefix : cls.name) + "_CLASS";
288 cls.comment = detail::eolian_class_comment(classname);
289 std::transform(cls.name.begin(), cls.name.end(), cls.name.begin(), ::tolower);
290 std::transform(cls.eo_name.begin(), cls.eo_name.end(), cls.eo_name.begin(), ::toupper);
291 return cls;
292}
293
294efl::eolian::eo_class
295c_to_cxx(const char *classname)
296{
297 efl::eolian::eo_class cls(_cxx_new(classname));
298 detail::convert_eolian_inheritances(cls, classname);
299 detail::convert_eolian_implements(cls, classname);
300 detail::convert_eolian_constructors(cls, classname);
301 detail::convert_eolian_functions(cls, classname);
302 detail::convert_eolian_properties(cls, classname);
303 return cls;
304}
diff --git a/src/bin/eolian_cxx/convert.hh b/src/bin/eolian_cxx/convert.hh
new file mode 100644
index 0000000000..910d3a5dd8
--- /dev/null
+++ b/src/bin/eolian_cxx/convert.hh
@@ -0,0 +1,9 @@
1
2#ifndef EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
3#define EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
4
5#include "eo_types.hh"
6
7efl::eolian::eo_class c_to_cxx(const char *classname);
8
9#endif // EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
diff --git a/src/bin/eolian_cxx/eo_read.h b/src/bin/eolian_cxx/eo_read.h
new file mode 100644
index 0000000000..2ad332f410
--- /dev/null
+++ b/src/bin/eolian_cxx/eo_read.h
@@ -0,0 +1,62 @@
1
2#ifndef EOLIAN_CXX_EOLIAN_HELPER_H
3#define EOLIAN_CXX_EOLIAN_HELPER_H
4
5#include <Eina.h>
6#include <Eolian.h>
7#include <assert.h>
8
9#define EO_SUFFIX ".eo"
10
11inline Eina_List*
12_list_dir(const char *dir, const char *suffix, Eina_Bool recurse)
13{
14 Eina_List *files = NULL;
15 Eina_Iterator *ls;
16 Eina_File_Direct_Info *info;
17
18 ls = eina_file_direct_ls(dir);
19 if(ls == NULL) return NULL;
20
21 EINA_ITERATOR_FOREACH (ls, info)
22 {
23 assert(info && info->path);
24 if (info->type == EINA_FILE_DIR && recurse)
25 {
26 files = eina_list_merge
27 (files, _list_dir(info->path, suffix, recurse));
28 }
29 else if (eina_str_has_suffix(&info->path[info->name_start], suffix))
30 {
31 files = eina_list_append(files, strdup(info->path));
32 }
33 }
34 eina_iterator_free(ls);
35 return eina_list_sort
36 (files, eina_list_count(files), EINA_COMPARE_CB(strcoll));
37}
38
39inline Eina_List*
40eolian_read_from_fs(const char *path, Eina_Bool recurse)
41{
42 if (eina_str_has_suffix(path, EO_SUFFIX))
43 {
44 if(!eolian_eo_file_parse(path))
45 {
46 /* XXX: fprintf? */
47 fprintf(stderr, "Couldn't load input file: %s\n", path);
48 return NULL;
49 }
50 }
51 else
52 {
53 if (!eolian_directory_scan(path))
54 {
55 /* XXX: fprintf? */
56 fprintf(stderr, "Error scanning directory: %s\n", path);
57 }
58 }
59 return eina_list_clone(eolian_class_names_list_get());
60}
61
62#endif /* EOLIAN_CXX_EOLIAN_HELPER_H */
diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc
new file mode 100644
index 0000000000..c6d146205f
--- /dev/null
+++ b/src/bin/eolian_cxx/eolian_cxx.cc
@@ -0,0 +1,337 @@
1
2#include <iostream>
3#include <fstream>
4
5#include <stdlib.h>
6#include <unistd.h>
7#include <getopt.h>
8
9#include <string>
10#include <algorithm>
11#include <stdexcept>
12#include <iosfwd>
13#include <type_traits>
14#include <cassert>
15
16extern "C"
17{
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <Eina.h>
23#include <Eo.h>
24#include <Eolian.h>
25}
26
27#include <Eina.hh>
28#include <Eolian_Cxx.hh>
29
30#include "eo_read.h"
31#include "convert.hh"
32#include "safe_strings.hh"
33
34namespace {
35
36// Program options.
37struct options_type
38{
39 std::vector<std::string> in_srcs;
40 std::string out_file;
41 std::string out_dir;
42 std::string classname;
43 std::string name_space;
44 bool recurse;
45 bool generate_all;
46
47 options_type()
48 : in_srcs()
49 , out_file("")
50 , out_dir("")
51 , classname("")
52 , name_space("")
53 , recurse(false)
54 , generate_all(false)
55 {}
56};
57
58efl::eina::log_domain domain("eolian_cxx");
59
60}
61
62static void
63_opt_error(std::string message)
64{
65 EINA_CXX_DOM_LOG_ERR(::domain) << message << std::endl;
66 exit(EXIT_FAILURE);
67}
68
69static void
70_assert_not_dup(std::string option, std::string value)
71{
72 if (value != "")
73 {
74 _opt_error("Option -" + option + " already set (" + value + ")");
75 }
76}
77
78// Try to guess classname from input filenames.
79// Precondition: Input sources must be loaded into Eolian Database
80// otherwise we can't infer the classname from the .eo files.
81// Precondition: Input options must have opts.classname == "".
82static std::string
83_guess_classname_from_sources(::options_type& opts)
84{
85 for (auto filename : opts.in_srcs)
86 {
87 if (const char *cls = eolian_class_find_by_file(filename.c_str()))
88 {
89 return cls;
90 }
91 }
92 return "";
93}
94
95efl::eolian::eo_generator_options
96_resolve_includes(std::string const& classname, ::options_type const& opts)
97{
98 efl::eolian::eo_generator_options gen_opts;
99
100 std::string cls_name = classname;
101 std::transform(cls_name.begin(), cls_name.end(), cls_name.begin(), ::tolower);
102
103 std::string eo_file = safe_str(eolian_class_file_get(classname.c_str()));
104 const size_t last = eo_file.rfind("/");
105 if (last != std::string::npos) eo_file.erase(0, last+1);
106 gen_opts.c_headers.push_back(eo_file + ".h");
107
108 void *cur = NULL;
109 const Eina_List *itr, *inheritances = eolian_class_inherits_list_get(classname.c_str());
110 EINA_LIST_FOREACH(inheritances, itr, cur)
111 {
112 const char *ext = static_cast<const char*>(cur);
113 std::string eo_parent_file = safe_str(eolian_class_file_get(ext));
114 if (!eo_parent_file.empty())
115 {
116 const size_t last = eo_parent_file.rfind("/");
117 if (last != std::string::npos) eo_parent_file.erase(0, last+1);
118 if (eo_parent_file != "eo_base.eo") // we have our own eo_base.hh
119 {
120 gen_opts.cxx_headers.push_back(eo_parent_file + ".hh");
121 }
122 }
123 else
124 {
125 EINA_CXX_DOM_LOG_WARN(::domain)
126 << "Couldn't find source file for class '" << ext << "'";
127 }
128 }
129 return gen_opts;
130}
131
132static void
133_generate(const std::string classname, ::options_type const& opts)
134{
135 efl::eolian::eo_class cls = ::c_to_cxx(classname.c_str());
136 cls.name_space = opts.name_space;
137 efl::eolian::eo_class_validate(cls);
138 efl::eolian::eo_generator_options gen_opts = _resolve_includes(classname, opts);
139 std::string outname = (opts.out_file == "") ? (cls.name + ".eo.hh") : opts.out_file;
140
141 if (opts.out_dir != "")
142 {
143 outname = opts.out_dir + "/" + outname;
144 }
145 if(opts.out_file == "-")
146 {
147 efl::eolian::generate(std::cout, cls, gen_opts);
148 }
149 else
150 {
151 std::ofstream outfile;
152 outfile.open(outname);
153 assert(outfile.good());
154 efl::eolian::generate(outfile, cls, gen_opts);
155 outfile.close();
156 }
157}
158
159static void
160_run(options_type const& opts)
161{
162 if (opts.classname != "")
163 {
164 _generate(opts.classname.c_str(), opts);
165 }
166 else
167 {
168 efl::eina::range_ptr_list<const char* const>
169 classes(eolian_class_names_list_get());
170 for (auto cls : classes)
171 {
172 if (opts.classname == "" || opts.classname == cls)
173 {
174 _generate(cls, opts);
175 }
176 }
177 }
178}
179
180static void
181_print_version()
182{
183 std::cerr
184 << "Eolian C++ Binding Generator (EFL "
185 << PACKAGE_VERSION << ")" << std::endl;
186}
187
188static void
189_validate_options(::options_type const& opts)
190{
191 if (opts.in_srcs.size() == 0)
192 {
193 _opt_error("You must provide at least one input source (-I). "
194 "Either an .eo file or a directory of .eo files.");
195 }
196 else if (opts.out_file != "" && opts.generate_all)
197 {
198 _opt_error("Options -a and -o can't be used together.");
199 }
200 else if (!opts.generate_all && opts.classname == "")
201 {
202 _opt_error("Neither -a nor -c provided. "
203 "Don't know what to generate.");
204 }
205}
206
207static void
208_resolve_classname(options_type& opts)
209{
210 if (opts.classname == "")
211 {
212 std::string cls = _guess_classname_from_sources(opts);
213 opts.classname = cls;
214 }
215 if (opts.classname == "" && opts.out_file != "")
216 {
217 EINA_CXX_DOM_LOG_ERR(::domain)
218 << "Unknown output class for " << opts.out_file
219 << " : Missing '-c' option?";
220 std::abort();
221 }
222}
223
224static void
225_load_classes(options_type const& opts)
226{
227 for (auto src : opts.in_srcs)
228 {
229 if (eolian_read_from_fs(src.c_str(), opts.recurse) == NULL)
230 {
231 EINA_CXX_DOM_LOG_WARN(::domain)
232 << "Couldn't load eolian file: " << src;
233 }
234 }
235}
236
237static void
238_usage(const char *progname)
239{
240 std::cerr
241 << progname
242 << " [options]" << std::endl
243 << "Options:" << std::endl
244 << " -a, --all Generate bindings for all Eo classes." << std::endl
245 << " -c, --class <name> The Eo class name to generate code for." << std::endl
246 << " -D, --out-dir <dir> Output directory where generated code will be written." << std::endl
247 << " -I, --in <file/dir> The source containing the .eo descriptions." << std::endl
248 << " -o, --out-file <file> The output file name. [default: <classname>.eo.hh]" << std::endl
249 << " -n, --namespace <ns> Wrap generated code in a namespace. [Eg: efl::ecore::file]" << std::endl
250 << " -r, --recurse Recurse input directories loading .eo files." << std::endl
251 << " -v, --version Print the version." << std::endl
252 << " -h, --help Print this help." << std::endl;
253 exit(EXIT_FAILURE);
254}
255
256static ::options_type
257_read_options(int argc, char **argv)
258{
259 ::options_type opts;
260
261 const struct option long_options[] =
262 {
263 { "in", required_argument, 0, 'I' },
264 { "out-dir", required_argument, 0, 'D' },
265 { "out-file", required_argument, 0, 'o' },
266 { "class", required_argument, 0, 'c' },
267 { "namespace", required_argument, 0, 'n' },
268 { "all", no_argument, 0, 'a' },
269 { "recurse", no_argument, 0, 'r' },
270 { "version", no_argument, 0, 'v' },
271 { "help", no_argument, 0, 'h' },
272 { 0, 0, 0, 0 }
273 };
274 const char* options = "I:D:o:c:n:arvh";
275
276 int c, idx;
277 while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
278 {
279 if (c == 'I')
280 {
281 opts.in_srcs.push_back(optarg);
282 }
283 else if (c == 'D')
284 {
285 _assert_not_dup("D", opts.out_dir);
286 opts.out_dir = optarg;
287 }
288 else if (c == 'o')
289 {
290 _assert_not_dup("o", opts.out_file);
291 opts.out_file = optarg;
292 }
293 else if (c == 'c')
294 {
295 _assert_not_dup("c", opts.classname);
296 opts.classname = optarg;
297 }
298 else if (c == 'n')
299 {
300 _assert_not_dup("n", opts.name_space);
301 opts.name_space = optarg;
302 }
303 else if (c == 'a')
304 {
305 opts.generate_all = true;
306 }
307 else if (c == 'r')
308 {
309 opts.recurse = true;
310 }
311 else if (c == 'h')
312 {
313 _usage(argv[0]);
314 }
315 else if (c == 'v')
316 {
317 _print_version();
318 if (argc == 2) exit(EXIT_SUCCESS);
319 }
320 }
321 return opts;
322}
323
324int main(int argc, char **argv)
325{
326 efl::eina::eina_init eina_init;
327 efl::eolian::eolian_init eolian_init;
328#if DEBUG
329 domain.set_level(efl::eina::log_level::debug);
330#endif
331 options_type opts = _read_options(argc, argv);
332 _load_classes(opts);
333 _resolve_classname(opts);
334 _validate_options(opts);
335 _run(opts);
336 return 0;
337}
diff --git a/src/bin/eolian_cxx/safe_strings.hh b/src/bin/eolian_cxx/safe_strings.hh
new file mode 100644
index 0000000000..61f7f9b58f
--- /dev/null
+++ b/src/bin/eolian_cxx/safe_strings.hh
@@ -0,0 +1,28 @@
1
2#ifndef EOLIAN_CXX_BIN_SAFE_STRINGS_HH
3#define EOLIAN_CXX_BIN_SAFE_STRINGS_HH
4
5#include <string>
6
7extern "C"
8{
9#include <Eina.h>
10}
11
12/// @brief Safely convert an const char* to std::string.
13inline std::string
14safe_str(const char* str)
15{
16 return (str != NULL) ? str : "";
17}
18
19/// @brief Safely convert an Eina_Stringshare to std::string.
20inline std::string
21safe_strshare(Eina_Stringshare* strsh)
22{
23 std::string ret = strsh != NULL ? strsh : "";
24 eina_stringshare_del(strsh);
25 return ret;
26}
27
28#endif // EOLIAN_CXX_BIN_SAFE_STRINGS_HH
diff --git a/src/bindings/ecore_cxx/Ecore.hh b/src/bindings/ecore_cxx/Ecore.hh
index ad9dcabbc4..81f1ac2873 100644
--- a/src/bindings/ecore_cxx/Ecore.hh
+++ b/src/bindings/ecore_cxx/Ecore.hh
@@ -10,6 +10,10 @@
10#include <memory> 10#include <memory>
11#include <cstring> 11#include <cstring>
12 12
13#ifdef EFL_BETA_API_SUPPORT
14#include <Ecore.eo.hh>
15#endif
16
13namespace efl { namespace ecore { 17namespace efl { namespace ecore {
14 18
15template <typename T> 19template <typename T>
diff --git a/src/bindings/eo_cxx/Eo.hh b/src/bindings/eo_cxx/Eo.hh
new file mode 100644
index 0000000000..a324e1c43c
--- /dev/null
+++ b/src/bindings/eo_cxx/Eo.hh
@@ -0,0 +1,9 @@
1#ifndef EFL_CXX_EO_HH
2#define EFL_CXX_EO_HH
3
4#include <eo_base.hh>
5#include <eo_init.hh>
6#include <eo_wref.hh>
7#include <eo_inherit.hh>
8
9#endif // EFL_CXX_EO_HH
diff --git a/src/bindings/eo_cxx/eo_base.hh b/src/bindings/eo_cxx/eo_base.hh
new file mode 100644
index 0000000000..00b660efc1
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_base.hh
@@ -0,0 +1,229 @@
1
2///
3/// @file eo_base.hh
4///
5
6#ifndef EFL_CXX_EO_BASE_HH
7#define EFL_CXX_EO_BASE_HH
8
9#include <cassert>
10#include <stdexcept>
11#include <cstddef>
12#include <eina_optional.hh>
13
14#include "eo_ops.hh"
15
16
17namespace efl { namespace eo {
18
19/// @addtogroup Efl_Cxx_API
20/// @{
21
22/// @brief A binding to the <em>EO Base Class</em>.
23///
24/// This class implements C++ wrappers to all the <em>EO Base</em>
25/// operations.
26///
27struct base
28{
29 /// @brief Class constructor.
30 ///
31 /// @param eo The <em>EO Object</em>.
32 ///
33 /// efl::eo::base constructors semantics are that of stealing the
34 /// <em>EO Object</em> lifecycle management. Its constructors do not
35 /// increment the <em>EO</em> reference counter but the destructors
36 /// do decrement.
37 ///
38 explicit base(Eo* eo) : _eo_raw(eo)
39 {
40 assert(eo != 0);
41 }
42
43 /// @brief Class destructor.
44 ///
45 ~base()
46 {
47 detail::unref(_eo_raw);
48 }
49
50 /// @brief Assignment operator.
51 ///
52 base& operator=(base const& other)
53 {
54 _eo_raw = detail::ref(other._eo_ptr());
55 return *this;
56 }
57
58 /// @brief Return a pointer to the <em>EO Object</em> stored in this
59 /// instance.
60 ///
61 /// @return A pointer to the opaque <em>EO Object</em>.
62 ///
63 Eo* _eo_ptr() const { return _eo_raw; }
64
65 /// @brief Get the reference count of this object.
66 ///
67 /// @return The referencer count of this object.
68 ///
69 int ref_get() const { return detail::ref_get(_eo_raw); }
70
71 /// @brief Set the parent of this object.
72 ///
73 /// @param parent The new parent.
74 ///
75 void parent_set(base parent)
76 {
77 detail::parent_set(_eo_raw, parent._eo_ptr());
78 }
79
80 /// @brief Get the parent of this object.
81 ///
82 /// @return An @ref efl::eo::base instance that binds the parent
83 /// object. Returns NULL if there is no parent.
84 ///
85 eina::optional<base> parent_get()
86 {
87 Eo *r = detail::parent_get(_eo_raw);
88 if(!r) return nullptr;
89 else
90 {
91 detail::ref(r); // XXX eo_parent_get does not call eo_ref so we may.
92 return base(r);
93 }
94 }
95
96 /// @brief Set generic data to object.
97 ///
98 /// @param key The key associated with the data.
99 /// @param data The data to set.
100 /// @param free_func A pointer to the function that frees the
101 /// data. @c (::eo_key_data_free_func*)0 is valid.
102 ///
103 void base_data_set(const char *key, const void *data, ::eo_key_data_free_func func)
104 {
105 detail::base_data_set(_eo_raw, key, data, func);
106 }
107
108 /// @brief Get generic data from object.
109 ///
110 /// @param key The key associated with desired data.
111 /// @return A void pointer to the data.
112 ///
113 void* base_data_get(const char *key)
114 {
115 return detail::base_data_get(_eo_raw, key);
116 }
117
118 /// @brief Delete generic data from object.
119 ///
120 /// @param key The key associated with the data.
121 ///
122 void base_data_del(const char *key)
123 {
124 detail::base_data_del(_eo_raw, key);
125 }
126
127 /// @brief Freeze any event directed to this object.
128 ///
129 /// Prevents event callbacks from being called for this object.
130 ///
131 void event_freeze()
132 {
133 detail::event_freeze(_eo_raw);
134 }
135
136 /// @brief Thaw the events of this object.
137 ///
138 /// Let event callbacks be called for this object.
139 ///
140 void event_thaw()
141 {
142 detail::event_thaw(_eo_raw);
143 }
144
145 /// @brief Get the event freeze count for this object.
146 ///
147 /// @return The event freeze count for this object.
148 ///
149 int event_freeze_get()
150 {
151 return detail::event_freeze_get(_eo_raw);
152 }
153
154 /// @brief Get debug information of this object.
155 ///
156 /// @return The root node of the debug information tree.
157 ///
158 Eo_Dbg_Info dbg_info_get()
159 {
160 Eo_Dbg_Info info;
161 detail::dbg_info_get(_eo_raw, &info);
162 return info;
163 }
164
165 protected:
166 Eo* _eo_raw; ///< The opaque <em>EO Object</em>.
167};
168
169/// @brief Downcast @p U to @p T.
170///
171/// @param T An <em>EO C++ Class</em>.
172/// @param U An <em>EO C++ Class</em>.
173///
174/// @param object The target object.
175/// @return This function returns a new instance of @p T if the
176/// downcast is successful --- otherwise it raises a @c
177/// std::runtime_error.
178///
179template <typename T, typename U>
180T downcast(U object)
181{
182 Eo *eo = object._eo_ptr();
183
184 if(detail::isa(eo, T::_eo_class()))
185 {
186 return T(detail::ref(eo));
187 }
188 else
189 {
190 throw std::runtime_error("Invalid cast");
191 }
192}
193
194///
195/// @brief Type used to hold the parent passed to base Eo C++
196/// constructors.
197///
198struct parent_type
199{
200 Eo* _eo_raw;
201};
202
203///
204/// @brief The expression type declaring the assignment operator used
205/// in the parent argument of the base Eo C++ class.
206///
207struct parent_expr
208{
209 parent_type operator=(efl::eo::base const& parent)
210 {
211 return { parent._eo_ptr() };
212 }
213
214 parent_type operator=(std::nullptr_t)
215 {
216 return { NULL };
217 }
218};
219
220///
221/// @brief Placeholder for the parent argument.
222///
223parent_expr parent = {};
224
225/// @}
226
227} } // namespace efl { namespace eo {
228
229#endif // EFL_CXX_EO_BASE_HH
diff --git a/src/bindings/eo_cxx/eo_inherit.hh b/src/bindings/eo_cxx/eo_inherit.hh
new file mode 100644
index 0000000000..66de0869e5
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_inherit.hh
@@ -0,0 +1,137 @@
1
2///
3/// @file eo_inherit.hh
4///
5
6#ifndef EFL_CXX_EO_INHERIT_HH
7#define EFL_CXX_EO_INHERIT_HH
8
9#include <tuple>
10#include <cassert>
11
12#include <eina_integer_sequence.hh>
13
14#include "eo_ops.hh"
15#include "eo_private.hh"
16
17namespace efl { namespace eo {
18
19namespace detail {
20
21template <typename D, typename Args, typename... E, std::size_t... S>
22Eo_Class const* create_class(eina::index_sequence<S...>);
23
24template <typename Args, typename ... E>
25void inherit_constructor(void* this_, Args args);
26
27}
28
29/// @addtogroup Efl_Cxx_API
30/// @{
31
32/// @brief Template-class that allows client code to inherit from
33/// <em>EO C++ Classes</em> without the need to make explicit calls to
34/// <em>EO</em> methods --- that would naturally be necessary to
35/// register itself in the <em>EO Subsystem</em>.
36///
37/// @param D The derived class
38/// @param O The parent class
39/// @param E Class extensions (either mixins or interfaces)
40///
41/// The derived class @p D will inherit all EO operations and event
42/// callbacks from the parent class @p P, as well as from the <c>Base
43/// Class</c> (@ref efl::eo::base) since every EO C++ Class must
44/// inherit from it.
45///
46/// efl::eo::inherit makes use of meta-template elements to build (in
47/// compile-time) code capable of registering @p D as an <em>EO
48/// Class</em> within <em>EO Subsystem</em>. Each class is registered
49/// only once upon instantiation of an object of its type.
50///
51/// @note Function overriding is currently not supported.
52///
53template <typename D, typename... E>
54struct inherit;
55
56/// @}
57
58/// @addtogroup Efl_Cxx_API
59/// @{
60
61template <typename D, typename... E>
62struct inherit
63 : detail::operations<E>::template type<inherit<D, E...> > ...
64 , detail::conversion_operator<inherit<D, E...>, E>...
65{
66 /// @typedef inherit_base
67 ///
68 typedef inherit<D, E...> inherit_base;
69
70 /// @brief Class constructor.
71 ///
72 /// @ref inherit has a "variadic" constructor implementation that
73 /// allows from zero to EFL_MAX_ARGS heterogeneous parameters.
74 ///
75 template<typename... Args>
76 inherit(Args&& ... args)
77 {
78 typedef std::tuple<typename std::remove_reference<Args>::type...> tuple_type;
79 _eo_cls = detail::create_class<D, tuple_type, E...> (eina::make_index_sequence<sizeof...(E)>());
80 _eo_raw = eo_add_custom
81 (_eo_cls, NULL,
82 detail::inherit_constructor
83 <tuple_type, E...>
84 (static_cast<void*>(this), tuple_type(std::move(args)...)));
85 }
86
87 /// @brief Class destructor.
88 ///
89 ~inherit()
90 {
91 detail::unref(_eo_raw);
92 }
93
94 /// @brief Gets the <em>EO Object</em> corresponding to this <em>EO
95 /// C++ Object</em>.
96 ///
97 /// @return A pointer to the <em>EO Object</em>.
98 ///
99 Eo* _eo_ptr() const { return _eo_raw; }
100
101 /// @brief Gets the <em>EO Class</em> corresponding to this <em>EO
102 /// C++ Class</em>.
103 ///
104 /// @return A pointer to the <em>EO Class</em>.
105 ///
106 Eo_Class const* _eo_class() const { return _eo_cls; }
107
108protected:
109 /// @brief Copy constructor.
110 ///
111 inherit(inherit const& other)
112 : _eo_cls(other._eo_cls)
113 , _eo_raw(other._eo_raw)
114 { detail::ref(_eo_raw); }
115
116 /// @brief Assignment Operator
117 ///
118 inherit& operator=(inherit const& other)
119 {
120 _eo_cls = other._eo_cls;
121 _eo_raw = other._eo_raw;
122 detail::ref(_eo_raw);
123 return *this;
124 }
125
126private:
127 Eo_Class const* _eo_cls; ///< The <em>EO Class</em>.
128 Eo* _eo_raw; ///< The <em>EO Object</em>.
129};
130
131/// @}
132
133} } // namespace efl { namespace eo {
134
135#include "eo_inherit_bindings.hh"
136
137#endif // EFL_CXX_INHERIT_HH
diff --git a/src/bindings/eo_cxx/eo_inherit_bindings.hh b/src/bindings/eo_cxx/eo_inherit_bindings.hh
new file mode 100644
index 0000000000..cffaa4d588
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_inherit_bindings.hh
@@ -0,0 +1,347 @@
1
2#ifndef EFL_CXX_DETAIL_INHERIT_BINDINGS_HH
3#define EFL_CXX_DETAIL_INHERIT_BINDINGS_HH
4
5#include <typeinfo>
6#include <eina_integer_sequence.hh>
7
8namespace efl { namespace eo { namespace detail {
9
10/// @addtogroup Efl_Cxx_Detail
11/// @{
12
13/// @internal
14///
15/// @brief Invokes the <em>EO C Constructor</em> that corresponds to the
16/// binded <em>EO C++ Class</em>.
17///
18/// @param T The corresponding <em>EO C++ Class</em>
19/// @param Args An heterogeneous list of constructor arguments
20///
21/// @param tag Used to instruct the compiler during compile-time which
22/// of the overloads should be invoked.
23/// @param eo A pointer to the <em>EO C Object</em> to be constructed.
24/// @param cls Unused.
25/// @param args An heterogenous vector containing the constructor
26/// arguments, in the correct order.
27///
28/// To ensure full reciprocity of the C++ binding there must exist one
29/// (and only one) implementation of @ref efl::eo::detail::call_constructor
30/// for each available <em>EO C++ Class</em> --- the implementations
31/// are differentiated by this unique specialization of
32/// @ref efl::eo::detail::tag for the first argument of
33/// @ref efl::eo::detail::call_constructor.
34///
35/// For example this is how the overload for @ref eo_simple is
36/// written as follows:
37///
38/// @dontinclude eo_simple.hh
39/// @skip call_constructor
40/// @until }
41///
42/// As you can see @c ::simple_constructor is called with a single
43/// argument in this case. Each EO Class has its own constructor
44/// prototype -- which can have different argument types as well as
45/// distinct number of arguments, etc. -- hence the need to specify a
46/// choice for every known <em>EO C++ Class</em>.
47///
48/// @see efl::eo::detail::tag
49///
50template <typename T, typename Args>
51void call_constructor(efl::eo::detail::tag<T> tag, Eo* eo, Eo_Class const* cls, Args args);
52
53/// @internal
54///
55/// @brief Sums up the number of <em>EO Operations</em> of each class
56/// passed as argument to the template.
57///
58/// @see efl::eo::detail::operation_description_class_size
59///
60template <typename... E>
61struct operation_description_size;
62
63template <typename E0, typename... E>
64struct operation_description_size<E0, E...>
65{
66 static const int value = operation_description_class_size<E0>::value +
67 operation_description_size<E...>::value;
68};
69
70template <>
71struct operation_description_size<>
72{
73 static const int value = 0;
74};
75
76template <typename T>
77struct is_args_class : std::false_type
78{
79};
80
81template <typename T, typename Tuple>
82struct is_args_class<args_class<T, Tuple> >
83 : std::true_type
84{
85};
86
87template <typename Tuple>
88struct are_args_class;
89
90template <>
91struct are_args_class<std::tuple<> >
92 : std::true_type
93{
94};
95
96template <typename T0, typename... T>
97struct are_args_class<std::tuple<T0, T...> >
98 : std::integral_constant
99 <bool
100 , is_args_class<T0>::value
101 && are_args_class<std::tuple<T...> >::value
102 >
103{
104};
105
106template <typename T, typename Tuple>
107struct has_args_class : std::false_type
108{
109 typedef std::integral_constant<std::size_t, 0u> index;
110};
111
112template <typename T, typename Tuple, typename... Args>
113struct has_args_class<T, std::tuple<detail::args_class<T, Tuple>, Args...> >
114 : std::true_type
115{
116 typedef detail::args_class<T, Tuple> type;
117 typedef std::integral_constant<std::size_t, 0u> index;
118};
119
120template <typename T, typename T0, typename... Args>
121struct has_args_class<T, std::tuple<T0, Args...> >
122 : has_args_class<T, std::tuple<Args...> >
123{
124 typedef has_args_class<T, std::tuple<Args...> > base_type;
125 typedef std::integral_constant
126 <std::size_t, 1u + base_type::index::value> index;
127};
128
129/// @internal
130///
131/// @brief An auxiliary template-class used to select the correct
132/// implementation of @ref efl::eo::call_constructor for @p T with
133/// proper parameters and variadic size.
134///
135/// @param T An <em>EO C++ Class</em>.
136///
137template <typename T, std::size_t N>
138struct call_constructor_aux
139{
140 template <typename Args, typename P>
141 static void do_(Args const&, Eo* eo, Eo_Class const* cls
142 , P, typename std::enable_if<!P::value>::type* = 0)
143 {
144 call_constructor(tag<T>(), eo, cls, args_class<T, std::tuple<> >(std::tuple<>()));
145 }
146
147 template <typename Args, typename P>
148 static void do_(Args const& args, Eo* eo, Eo_Class const* cls
149 , P, typename std::enable_if<P::value>::type* = 0)
150 {
151 call_constructor(tag<T>(), eo, cls, std::get<P::index::value>(args));
152 }
153
154 /// @internal
155 ///
156 /// @brief Invoke @def efl::eo::detail::call_constructor
157 /// implementation for the parent and each available extension.
158 ///
159 /// @param args An heterogenous sequence of arguments.
160 /// @param eo The opaque <em>EO Object</em>.
161 /// @param cls The opaque <em>EO Class</em>.
162 ///
163 template <typename Args>
164 static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
165 {
166 static_assert(std::tuple_size<Args>::value <= N, "");
167 static_assert(are_args_class<Args>::value, "");
168 do_(args, eo, cls, has_args_class<T, Args>());
169 return 0;
170 }
171};
172
173template <typename T>
174struct call_constructor_aux<T, 1u>
175{
176 template <typename Args>
177 static void do_(Args const& args, Eo* eo, Eo_Class const* cls
178 , std::true_type)
179 {
180 static_assert(std::tuple_size<Args>::value == 1, "");
181 static_assert(std::is_same
182 <typename std::tuple_element<0u, Args>::type::class_type
183 , T>::value, "");
184 call_constructor(tag<T>(), eo, cls, std::get<0u>(args));
185 }
186
187 template <typename Args>
188 static void do_(Args const& args, Eo* eo, Eo_Class const* cls
189 , std::false_type)
190 {
191 call_constructor(tag<T>(), eo, cls, args_class<T, Args>(args));
192 }
193
194 template <typename Args>
195 static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
196 {
197 do_(args, eo, cls, has_args_class<T, Args>());
198 return 0;
199 }
200};
201
202template <typename... Args>
203void call_varargs(Args...)
204{
205}
206
207/// @internal
208///
209/// @brief The procedure that actually is invoked when the constructor
210/// of @c D is sought from the <em>EO Subsystem</em>.
211///
212/// @param obj The opaque <em>EO Object</em>.
213/// @param self A pointer to @p obj's private data.
214/// @param this_ A void pointer to the opaque <em>EO Class</em> ---
215/// passed as <em>user data</em>.
216/// @param args The arguments for the underlying constructor.
217///
218template <typename D, typename Args, typename... E>
219void inherit_constructor_impl(Eo* obj, Inherit_Private_Data* self, void* this_, Args args)
220{
221 self->this_ = this_;
222 Eo_Class const* cls = static_cast<inherit<D, E...>*>(this_)->_eo_class();
223 detail::call_varargs(detail::call_constructor_aux<E, sizeof...(E)>::do_(args, obj, cls) ...);
224}
225
226/// @internal
227///
228/// @brief Find the correct function for the <em>"constructor"</em>
229/// operation and invoke it.
230///
231/// @param this_ The <em>user data</em> to be passed to the resolved function.
232/// @param args An heterogeneous sequence of arguments.
233///
234template <typename Args, typename... E>
235EAPI void inherit_constructor(void* this_, Args args)
236{
237 typedef void (*func_t)(Eo *, void *, void*, Args);
238 Eo_Op_Call_Data call;
239 static Eo_Op op = EO_NOOP;
240 if ( op == EO_NOOP )
241 op = _eo_api_op_id_get
242 (reinterpret_cast<void*>
243 (static_cast<void(*)(void*, Args)>(&detail::inherit_constructor<Args, E...>)),
244 __FILE__, __LINE__);
245 if (!_eo_call_resolve("detail::inherit_constructor", op, &call, __FILE__, __LINE__))
246 {
247 assert(_eo_call_resolve("detail::inherit_constructor", op, &call, __FILE__, __LINE__));
248 return;
249 }
250 func_t func = (func_t) call.func;
251 EO_HOOK_CALL_PREPARE(eo_hook_call_pre);
252 func(call.obj, call.data, this_, args);
253 EO_HOOK_CALL_PREPARE(eo_hook_call_post);
254}
255
256template <typename T>
257int initialize_operation_description(detail::tag<void>, void*);
258
259template <std::size_t I, typename... E>
260struct
261operation_description_index
262{
263 typedef std::tuple<E...> tuple_type;
264 static const std::size_t value =
265 detail::operation_description_size
266 < typename std::tuple_element
267 <I-1, tuple_type>::type >::value +
268 operation_description_index<I-1, E...>::value;
269};
270template <typename... E>
271struct
272operation_description_index<0u, E...>
273{
274 static const std::size_t value = 0u;
275};
276
277/// @internal
278///
279/// @brief This function is responsible for declaring a new <em>EO C
280/// Class</em> representing @p D within <em>EO Subsystem</em>.
281///
282/// @param D The derived class
283/// @param P The parent class
284/// @param En Class extensions (either mixins or interfaces)
285/// @param Args An heterogeneous list of arguments to be passed to the
286/// constructor of this class.
287///
288/// @see efl::eo::inherit::inherit
289///
290template <typename D, typename TupleArgs, typename... E, std::size_t ... S>
291Eo_Class const* create_class(eina::index_sequence<S...>)
292{
293 static const Eo_Class* my_class = NULL;
294 static Eo_Op_Description op_descs
295 [ detail::operation_description_size<E...>::value + 2 ];
296
297 op_descs[detail::operation_description_size<E...>::value].func =
298 reinterpret_cast<void*>
299 (
300 static_cast<void(*)(Eo*, Inherit_Private_Data*, void*, TupleArgs)>
301 (&detail::inherit_constructor_impl<D, TupleArgs, E...>)
302 );
303 op_descs[detail::operation_description_size<E...>::value].api_func =
304 reinterpret_cast<void*>
305 (
306 static_cast<void(*)(void*, TupleArgs)>
307 (&detail::inherit_constructor<TupleArgs, E...>)
308 );
309 op_descs[detail::operation_description_size<E...>::value].op = EO_NOOP;
310 op_descs[detail::operation_description_size<E...>::value].op_type = EO_OP_TYPE_REGULAR;
311 op_descs[detail::operation_description_size<E...>::value].doc = NULL;
312
313 op_descs[detail::operation_description_size<E...>::value+1].func = 0;
314 op_descs[detail::operation_description_size<E...>::value+1].api_func = 0;
315 op_descs[detail::operation_description_size<E...>::value+1].op = 0;
316 op_descs[detail::operation_description_size<E...>::value+1].op_type = EO_OP_TYPE_INVALID;
317 op_descs[detail::operation_description_size<E...>::value+1].doc = NULL;
318
319 typedef inherit<D, E...> inherit_type;
320 using namespace detail;
321 call_varargs(
322 initialize_operation_description<inherit_type>
323 (detail::tag<E>(),
324 &op_descs[operation_description_index<S, E...>::value]) ...
325 );
326
327 //locks
328 if(!my_class)
329 {
330 static Eo_Class_Description class_desc = {
331 EO_VERSION,
332 "Eo C++ Class",
333 EO_CLASS_TYPE_REGULAR,
334 EO_CLASS_DESCRIPTION_OPS(op_descs),
335 NULL,
336 sizeof(detail::Inherit_Private_Data),
337 NULL,
338 NULL
339 };
340 my_class = detail::do_eo_class_new<E...>(class_desc);
341 }
342 return my_class;
343}
344
345} } } // namespace efl { namespace eo { namespace detail {
346
347#endif // EFL_CXX_DETAIL_INHERIT_BINDINGS_HH
diff --git a/src/bindings/eo_cxx/eo_init.hh b/src/bindings/eo_cxx/eo_init.hh
new file mode 100644
index 0000000000..a1cb3c2aaa
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_init.hh
@@ -0,0 +1,38 @@
1
2///
3/// @file eo_init.hh
4///
5
6#ifndef EFL_CXX_EO_INIT_HH
7#define EFL_CXX_EO_INIT_HH
8
9#include "eo_ops.hh"
10
11namespace efl { namespace eo {
12
13/// @addtogroup Efl_Cxx_API
14/// @{
15
16/// @brief A simple RAII implementation to initialize and terminate
17/// the <em>EO Subsystem</em>.
18///
19struct eo_init
20{
21 /// @brief Default constructor.
22 ///
23 /// Invokes @c ::eo_init().
24 ///
25 eo_init() { detail::init(); }
26
27 /// @brief Class destructor.
28 ///
29 /// Invokes @c ::eo_shutdown().
30 ///
31 ~eo_init() { detail::shutdown(); }
32};
33
34/// @}
35
36} }
37
38#endif // EFL_CXX_EO_INIT_HH
diff --git a/src/bindings/eo_cxx/eo_ops.hh b/src/bindings/eo_cxx/eo_ops.hh
new file mode 100644
index 0000000000..091c725099
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_ops.hh
@@ -0,0 +1,141 @@
1
2#ifndef EFL_CXX_DETAIL_EO_OPS_HH
3#define EFL_CXX_DETAIL_EO_OPS_HH
4
5extern "C"
6{
7#include <Eo.h>
8}
9
10#define eo_macro_add_custom(klass, parent, ...) ({ \
11 eo_add_custom(klass, parent, __VA_ARGS__); \
12 })
13
14namespace efl { namespace eo { namespace detail {
15
16inline void
17init()
18{
19 ::eo_init();
20}
21
22inline void
23shutdown()
24{
25 ::eo_shutdown();
26}
27
28inline Eo*
29ref(const Eo *obj)
30{
31 return ::eo_ref(obj);
32}
33
34inline void
35unref(const Eo *obj)
36{
37 ::eo_unref(obj);
38}
39
40inline int
41ref_get(const Eo *obj)
42{
43 return ::eo_ref_get(obj);
44}
45
46inline void
47del(const Eo *obj)
48{
49 ::eo_del(obj);
50}
51
52inline Eina_Bool
53isa(const Eo *obj, const Eo_Class *klass)
54{
55 return eo_isa(obj, klass);
56}
57
58inline Eo*
59add(const Eo_Class *klass, Eo *parent = NULL)
60{
61 Eo *eo = eo_add(klass, parent);
62 return eo;
63}
64
65inline void
66dbg_info_get(const Eo *obj, Eo_Dbg_Info *info)
67{
68 eo_do(obj, eo_dbg_info_get(info));
69}
70
71inline void
72base_data_set(const Eo *obj, const char *key, const void *data,
73 eo_key_data_free_func free_func = NULL)
74{
75 eo_do(obj, eo_key_data_set(key, data, free_func));
76}
77
78inline void*
79base_data_get(const Eo *obj, const char *key)
80{
81 void *data;
82 eo_do(obj, data = eo_key_data_get(key));
83 return data;
84}
85
86inline void
87base_data_del(const Eo *obj, const char *key)
88{
89 eo_do(obj, eo_key_data_del(key));
90}
91
92inline void
93parent_set(const Eo *obj, Eo *parent)
94{
95 eo_do(obj, eo_parent_set(parent));
96}
97
98inline Eo*
99parent_get(const Eo *obj)
100{
101 Eo *parent;
102 eo_do(obj, parent = eo_parent_get());
103 return parent;
104}
105
106inline void
107event_freeze(const Eo *obj)
108{
109 eo_do(obj, eo_event_freeze());
110}
111
112inline void
113event_thaw(const Eo *obj)
114{
115 eo_do(obj, eo_event_thaw());
116}
117
118inline int
119event_freeze_get(const Eo *obj)
120{
121 int count = -1;
122 eo_do(obj, count = eo_event_freeze_get());
123 return count;
124}
125
126inline void
127wref_add(const Eo *obj, Eo **wref)
128{
129 eo_do(obj, eo_wref_add(wref));
130}
131
132inline void
133wref_del(const Eo *obj, Eo **wref)
134{
135 eo_do(obj, eo_wref_del(wref));
136}
137
138} } }
139
140
141#endif // EFL_CXX_DETAIL_EO_OPS_HH
diff --git a/src/bindings/eo_cxx/eo_private.hh b/src/bindings/eo_cxx/eo_private.hh
new file mode 100644
index 0000000000..a2271733b3
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_private.hh
@@ -0,0 +1,160 @@
1
2///
3/// @file eo_private.hh
4///
5
6#ifndef EFL_CXX_EO_PRIVATE_HH
7#define EFL_CXX_EO_PRIVATE_HH
8
9#include "eo_ops.hh"
10
11namespace efl { namespace eo { namespace detail {
12
13/// @addtogroup Efl_Cxx_Detail
14/// @{
15
16/// @internal
17///
18/// @brief Provides a getter for an heterogeous sequence of arguments.
19///
20/// @param T An <em>EO C++ Class</em>
21/// @param Seq An heterogenous sequence of arguments.
22///
23template <typename T, typename Tuple>
24struct args_class
25{
26 typedef T class_type;
27
28 /// @internal
29 ///
30 /// @brief Class constructor.
31 ///
32 /// @param tuple An heterogenous sequence of arguments.
33 ///
34 args_class(Tuple tuple) : _tuple(tuple) {}
35
36 /// @internal
37 ///
38 /// @brief Get the Nth element of the sequence.
39 ///
40 /// @param N The index of the argument to be retrieved.
41 ///
42 template <int N>
43 typename std::remove_reference
44 <
45 typename std::tuple_element<N, Tuple>::type
46 >::type get() const
47 {
48 return std::get<N>(_tuple);
49 }
50
51 ///
52 /// TODO document.
53 ///
54 constexpr std::size_t size() const
55 {
56 return std::tuple_size<Tuple>::value;
57 }
58
59 Tuple _tuple; ///< The sequence of arguments.
60};
61
62/// @internal
63///
64/// @brief A simple generic tag to help keeping track of a type.
65///
66/// @details
67/// Used to mimic what would be a "template specialization" of a
68/// function through the overload of an argument of type @ref
69/// efl::eo::detail::tag --- because @c C++0x does not implement
70/// template specialization of functions.
71///
72template <typename T> struct tag {};
73
74/// @internal
75///
76/// @brief Invokes the different implementations of @ref
77/// efl::eo::detail::eo_class_new for the parent and all extensions.
78///
79/// @see efl::eo::detail::eo_class_new
80///
81template <typename ... E>
82Eo_Class const* do_eo_class_new(Eo_Class_Description& class_desc)
83{
84 return eo_class_new(&class_desc, get_eo_class(tag<E>())..., (void*)NULL);
85}
86
87template <typename T> struct operation_description_class_size;
88
89/// @internal
90///
91/// @brief Provides the operator to convert @p T to @p D.
92///
93/// @param D The target (derived) class
94/// @param T An <em>EO C++ Class</em>
95///
96template <typename D, typename T>
97struct conversion_operator
98{
99 operator T() const
100 {
101 detail::ref(static_cast<D const*>(this)->_eo_ptr());
102 return T(static_cast<D const*>(this)->_eo_ptr());
103 }
104};
105
106/// @}
107
108} // namespace detail {
109
110template <typename T, typename... A>
111detail::args_class<T, std::tuple< A... > >
112args(A... arg)
113{
114 return detail::args_class<T, std::tuple<A...> >(std::tuple<A...>(arg...));
115}
116
117namespace detail {
118
119/// @addtogroup Efl_Cxx_Detail
120/// @{
121
122/// @internal
123///
124/// @brief Provides all operations of type @p T.
125///
126/// @param T An <em>EO C++ Class</em>
127///
128/// There must be an unique specialization of this class for each
129/// declared <em>EO C++ Class</em>.
130///
131template <typename T> struct operations;
132
133/// @internal
134///
135/// @brief Provides the operations of an extension as well as its
136/// conversion operator.
137///
138/// @param T The <em>EO C++ Extension</em>
139///
140/// There must be an unique specialization of @ref
141/// efl::eo::detail::extension_inheritance for each known <em>EO C++
142/// Extension</em> -- i.e., @em Interfaces and @em Mixins.
143///
144template <typename T>
145struct extension_inheritance {};
146
147/// @internal
148///
149/// @brief efl::eo::inherit's private data.
150///
151struct Inherit_Private_Data
152{
153 void* this_;
154};
155
156/// @}
157
158} } } // namespace efl { namespace eo { namespace detail {
159
160#endif
diff --git a/src/bindings/eo_cxx/eo_wref.hh b/src/bindings/eo_cxx/eo_wref.hh
new file mode 100644
index 0000000000..4e2385f2d3
--- /dev/null
+++ b/src/bindings/eo_cxx/eo_wref.hh
@@ -0,0 +1,126 @@
1
2///
3/// @file eo_wref.hh
4///
5
6#ifndef EFL_CXX_WREF_HH
7#define EFL_CXX_WREF_HH
8
9#include <eina_optional.hh>
10
11#include "eo_ops.hh"
12
13namespace efl { namespace eo {
14
15/// @addtogroup Efl_Cxx_API
16/// @{
17
18/// @brief Weak references to an <em>EO Object</em>.
19///
20template<typename T>
21struct wref {
22
23 /// @brief Class constructor.
24 ///
25 /// @param obj The <em>EO Object</em> to be referenced.
26 ///
27 /// Create a weak reference to @p obj.
28 ///
29 explicit wref(Eo* obj) : _eo_wref(obj)
30 {
31 _add();
32 }
33
34 /// @brief Class constructor.
35 ///
36 /// @param obj The <em>EO C++ Object</em> to be referenced.
37 ///
38 /// Create a weak reference to @p obj.
39 ///
40 wref(T obj) : _eo_wref(obj._eo_ptr())
41 {
42 _add();
43 }
44
45 /// @brief Class destructor.
46 ///
47 ~wref()
48 {
49 if(eina::optional<T> p = lock())
50 _del();
51 }
52
53 /// @brief Try to acquire a strong reference to the underlying
54 /// <em>EO Object</em>.
55 ///
56 /// This function checks whether the weak reference still points to
57 /// a valid <em>EO Object</em>. If the reference is still valid it
58 /// increments the reference counter of the object and returns a
59 /// pointer to it.
60 ///
61 /// @return If the lock was successfully acquired it returns a
62 /// strong reference to the <em>EO Object</em>. Otherwise it returns
63 /// an empty eina::optional.
64 ///
65 eina::optional<T> lock()
66 {
67 if(_eo_wref) // XXX eo_ref() should work on multi-threaded environments
68 {
69 detail::ref(_eo_wref);
70 }
71 else
72 {
73 return nullptr;
74 }
75 return T(_eo_wref);
76 }
77
78 /// @brief Copy constructor.
79 ///
80 wref(wref const& other)
81 : _eo_wref(other._eo_wref)
82 {
83 if(eina::optional<T> p = lock())
84 {
85 _add();
86 }
87 else
88 {
89 _eo_wref = 0;
90 }
91 }
92
93 /// @brief Assignment operator.
94 ///
95 wref& operator=(wref const& other)
96 {
97 _eo_wref = other._eo_wref;
98 if(eina::optional<T> p = lock())
99 {
100 _add();
101 }
102 else
103 {
104 _eo_wref = 0;
105 }
106 }
107
108private:
109 void _add()
110 {
111 detail::wref_add(_eo_wref, &_eo_wref);
112 }
113
114 void _del()
115 {
116 detail::wref_del(_eo_wref, &_eo_wref);
117 }
118
119 Eo* _eo_wref; ///< The weak reference.
120};
121
122/// @}
123
124} } // namespace efl { namespace eo {
125
126#endif // EFL_CXX_WREF_HH
diff --git a/src/examples/eolian_cxx/.gitignore b/src/examples/eolian_cxx/.gitignore
new file mode 100644
index 0000000000..6ae19365d7
--- /dev/null
+++ b/src/examples/eolian_cxx/.gitignore
@@ -0,0 +1,3 @@
1/eolian_cxx_simple_01
2/eolian_cxx_inherit_01
3/eolian_cxx_evas_images
diff --git a/src/examples/eolian_cxx/Makefile.am b/src/examples/eolian_cxx/Makefile.am
new file mode 100644
index 0000000000..eec68a6a7f
--- /dev/null
+++ b/src/examples/eolian_cxx/Makefile.am
@@ -0,0 +1,114 @@
1
2AUTOMAKE_OPTIONS = subdir-objects
3
4MAINTAINERCLEANFILES = Makefile.in
5
6AM_CXXFLAGS = \
7 -I. \
8 -I$(top_builddir)/src/lib/efl \
9 -I$(top_srcdir)/src/lib/eina \
10 -I$(top_builddir)/src/lib/eina \
11 -I$(top_srcdir)/src/lib/eo \
12 -I$(top_builddir)/src/lib/eo \
13 -I$(top_srcdir)/src/bindings/eo_cxx \
14 -I$(top_builddir)/src/bindings/eo_cxx \
15 -I$(top_srcdir)/src/bindings/eina_cxx \
16 -I$(top_builddir)/src/bindings/eina_cxx \
17 -I$(top_srcdir)/src/lib/evas/ \
18 -I$(top_builddir)/src/lib/evas/ \
19 -I$(top_srcdir)/src/lib/evas/common \
20 -I$(top_builddir)/src/lib/evas/common \
21 -I$(top_srcdir)/src/lib/evas/canvas \
22 -I$(top_builddir)/src/lib/evas/canvas \
23 -I$(top_srcdir)/src/lib/ecore \
24 -I$(top_builddir)/src/lib/ecore \
25 -I$(top_srcdir)/src/lib/ecore_evas \
26 -I$(top_builddir)/src/lib/ecore_evas
27
28AM_CFLAGS = $(AM_CXXFLAGS)
29
30AM_LDFLAGS = \
31 -L$(top_builddir)/src/lib/efl \
32 -L$(top_builddir)/src/lib/eina \
33 -L$(top_builddir)/src/lib/eo \
34 -L$(top_builddir)/src/lib/evas \
35 -L$(top_builddir)/src/lib/ecore \
36 -L$(top_builddir)/src/lib/ecore_evas \
37 -leina -levas -leo -lecore -lecore_evas
38
39LDADD = \
40 $(top_builddir)/src/lib/eo/libeo.la \
41 $(top_builddir)/src/lib/eina/libeina.la \
42 $(top_builddir)/src/lib/evas/libevas.la \
43 $(top_builddir)/src/lib/ecore_evas/libecore_evas.la
44
45GENERATED = \
46 colourable.eo.c \
47 colourable.eo.h \
48 colourable.eo.hh \
49 colourablesquare.eo.c \
50 colourablesquare.eo.h \
51 colourablesquare.eo.hh
52
53EOS = \
54 colourable.eo \
55 colourablesquare.eo
56
57SRCS = \
58 eolian_cxx_simple_01.cc \
59 eolian_cxx_inherit_01.cc
60
61EXTRA_PROGRAMS = \
62 eolian_cxx_simple_01 \
63 eolian_cxx_inherit_01
64
65DATA_FILES = Makefile.examples
66CLEANFILES =
67
68eolian_cxx_simple_01_SOURCES = \
69 eolian_cxx_simple_01.cc \
70 colourable.c \
71 colourablesquare.c
72
73eolian_cxx_inherit_01_SOURCES = \
74 eolian_cxx_inherit_01.cc \
75 colourable.c \
76 colourablesquare.c
77
78EOLIAN_GEN = $(top_builddir)/src/bin/eolian/eolian_gen${EXEEXT}
79EOLIAN_CXX = $(top_builddir)/src/bin/eolian_cxx/eolian_cxx${EXEEXT}
80EOLIAN_FLAGS = \
81-I. \
82-I$(top_builddir)/src/lib/eo \
83-I$(top_builddir)/src/lib/evas/canvas \
84-I$(top_builddir)/src/lib/edje \
85-I$(top_builddir)/src/lib/ecore_audio
86
87SUFFIXES = .eo .eo.c .eo.h .eo.hh
88
89%.eo.hh: %.eo $(EOLIAN_CXX)
90 $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I./$< -o $@
91
92%.eo.c: %.eo $(EOLIAN_GEN)
93 $(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
94
95%.eo.h: %.eo $(EOLIAN_GEN)
96 $(AM_V_EOL)$(EOLIAN_GEN) --eo $(EOLIAN_FLAGS) --gh -o $@ $<
97
98examples: $(EOS) $(GENERATED) $(EXTRA_PROGRAMS)
99
100clean-local:
101 rm -f $(EXTRA_PROGRAMS) $(GENERATED)
102
103install-examples:
104 mkdir -p $(datadir)/eolian_cxx/examples
105 $(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eolian_cxx/examples
106
107uninstall-local:
108 for f in $(SRCS) $(DATA_FILES); do \
109 rm -f $(datadir)/eolian_cxx/examples/$$f ; \
110 done
111
112if ALWAYS_BUILD_EXAMPLES
113noinst_PROGRAMS = $(EXTRA_PROGRAMS)
114endif
diff --git a/src/examples/eolian_cxx/colourable.c b/src/examples/eolian_cxx/colourable.c
new file mode 100644
index 0000000000..3e289583dd
--- /dev/null
+++ b/src/examples/eolian_cxx/colourable.c
@@ -0,0 +1,165 @@
1#include <stdio.h>
2
3#ifdef HAVE_CONFIG_H
4# include <config.h>
5#endif
6
7#include "Eo.h"
8#include "Eina.h"
9#include "colourable.eo.h"
10
11#define MY_CLASS COLOURABLE_CLASS
12
13static int _colourable_impl_logdomain;
14
15#ifdef DBG
16#undef DBG
17#endif
18#define DBG(...) EINA_LOG_DOM_DBG(_colourable_impl_logdomain, __VA_ARGS__)
19
20#ifdef INFO
21#undef INFO
22#endif
23#define INFO(...) EINA_LOG_DOM_INFO(_colourable_impl_logdomain, __VA_ARGS__)
24
25#ifdef ERR
26#undef ERR
27#endif
28#define ERR(...) EINA_LOG_DOM_ERR(_colourable_impl_logdomain, __VA_ARGS__)
29
30struct _Colourable_Data
31{
32 int r;
33 int g;
34 int b;
35};
36
37typedef struct _Colourable_Data Colourable_Data;
38
39#define COLOURABLE_DATA_GET(o, wd) \
40 Colourable_Data *wd = eo_data_scope_get(o, MY_CLASS)
41
42void
43_colourable_constructor(Eo *obj, Colourable_Data *self)
44{
45 if(!_colourable_impl_logdomain)
46 {
47 _colourable_impl_logdomain
48 = eina_log_domain_register("colourable", EINA_COLOR_BLUE);
49 }
50 DBG("_colourable_constructor(%p, %p)\n", obj, MY_CLASS);
51 eo_do_super(obj, MY_CLASS, eo_constructor());
52}
53
54void
55_colourable_destructor(Eo *obj, Colourable_Data *self)
56{
57 if(_colourable_impl_logdomain)
58 {
59 eina_log_domain_unregister(_colourable_impl_logdomain);
60 _colourable_impl_logdomain = 0;
61 }
62 DBG("_colourable_destructor()\n");
63 eo_do_super(obj, MY_CLASS, eo_destructor());
64}
65
66void
67_colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b)
68{
69 if(!_colourable_impl_logdomain)
70 {
71 _colourable_impl_logdomain
72 = eina_log_domain_register("colourable", EINA_COLOR_BLUE);
73 }
74 self->r = r;
75 self->g = g;
76 self->b = b;
77 DBG("_colourable_rgb_composite_constructor(0x%2.x, %0x2.x, %0x2.x)\n",
78 (unsigned int)self->r,
79 (unsigned int)self->g,
80 (unsigned int)self->b);
81 eo_do_super(obj, MY_CLASS, eo_constructor());
82}
83
84void
85_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
86{
87 if(!_colourable_impl_logdomain)
88 {
89 _colourable_impl_logdomain
90 = eina_log_domain_register("colourable", EINA_COLOR_BLUE);
91 }
92
93 self->r = (rgb & 0x00ff0000) >> 16;
94 self->g = (rgb & 0x0000ff00) >> 8;
95 self->b = rgb & 0x000000ff;
96 DBG("_colourable_rgb_24bits_constructor(0x%.6x)\n", (int)rgb);
97 eo_do_super(obj, MY_CLASS, eo_constructor());
98}
99
100void
101_colourable_print_colour(Eo *obj, Colourable_Data *self)
102{
103 DBG("_colourable_print_colour() ==> 0x%2.x 0x%2.x 0x%2.x\n", self->r, self->g, self->b);
104}
105
106int
107_colourable_colour_mask(Eo *obj, Colourable_Data *self, int mask)
108{
109 int masked_rgb =
110 (((self->r << 16)& 0x00ff0000) |
111 ((self->g << 8) & 0x0000ff00) |
112 (self->b & 0x000000ff)) & mask;
113 DBG("_colourable_colour_mask() ==> 0x%2.x\n", (unsigned int)masked_rgb);
114 return masked_rgb;
115}
116
117void
118_colourable_composite_colour_get(Eo *obj, Colourable_Data *self, int* r, int* g, int* b)
119{
120 *r = self->r;
121 *g = self->g;
122 *b = self->b;
123 DBG("_colourable_composite_colour_get() ==> 0x%2.x 0x%2.x 0x%2.x\n", *r, *g, *b);
124 return;
125}
126
127void
128_colourable_composite_colour_set(Eo *obj, Colourable_Data *self, int r, int g, int b)
129{
130 self->r = r;
131 self->g = g;
132 self->b = b;
133 DBG("_colourable_composite_colour_set(0x%2.x, 0x%2.x, 0x%2.x)\n",
134 (int)self->r, (int)self->g, (int)self->b);
135 return;
136}
137
138int
139_colourable_colour_get(Eo *obj, Colourable_Data *self)
140{
141 int rgb =
142 ((self->r << 16)& 0x00ff0000) |
143 ((self->g << 8) & 0x0000ff00) |
144 (self->b & 0x000000ff);
145 DBG("_colourable_colour_get() ==> 0x%.6x\n", (unsigned int)rgb);
146 return rgb;
147}
148
149void
150_colourable_colour_set(Eo *obj, Colourable_Data *self, int rgb)
151{
152 self->r = (rgb & 0x00ff0000) >> 16;
153 self->g = (rgb & 0x0000ff00) >> 8;
154 self->b = rgb & 0x000000ff;
155 DBG("_colourable_colour_set(0x%.6x)\n", (unsigned int)rgb);
156 return;
157}
158
159static void
160_user_colourable_class_constructor(Eo_Class *klass)
161{
162 DBG("_colourable_class_constructor()\n");
163}
164
165#include "colourable.eo.c"
diff --git a/src/examples/eolian_cxx/colourable.eo b/src/examples/eolian_cxx/colourable.eo
new file mode 100644
index 0000000000..a708217a39
--- /dev/null
+++ b/src/examples/eolian_cxx/colourable.eo
@@ -0,0 +1,63 @@
1class Colourable (Eo_Base)
2{
3 /*@ Colourable class. */
4 legacy_prefix: legacy;
5 constructors {
6 constructor {
7 /*@ Default constructor. */
8 }
9 rgb_composite_constructor {
10 /*@ Composite RGB Constructor. */
11 params {
12 @in int r; /*@ The red component. */
13 @in int g; /*@ The green component. */
14 @in int b; /*@ The blue component. */
15 };
16 };
17 rgb_24bits_constructor {
18 /*@ RGB Constructor. */
19 params {
20 @in int rgb; /*@ 24-bit RGB Component. */
21 };
22 };
23 };
24 methods {
25 print_colour { /*@ Print the RGB colour. */ };
26 colour_mask {
27 /*@ The masked RGB value. */
28 return int;
29 params {
30 @in int mask; /*@ The colour mask to be applied to current RGB value. */
31 };
32 };
33 };
34 properties {
35 colour {
36 set {
37 /*@ Sets a 24-bit RGB colour. */
38 };
39 get {
40 /*@ Gets the 24-bit RGB colour. */
41 };
42 values {
43 int rgb; /*@ The RGB colour value. */
44 };
45 };
46 composite_colour {
47 set {
48 /*@ Sets a composite RGB colour. */
49 };
50 get {
51 /*@ Gets the composite RGB colour. */
52 };
53 values {
54 int r; /*@ The red component. */
55 int g; /*@ The green component. */
56 int b; /*@ The blue component. */
57 };
58 };
59 };
60 events {
61 colour_changed(int);
62 };
63};
diff --git a/src/examples/eolian_cxx/colourablesquare.c b/src/examples/eolian_cxx/colourablesquare.c
new file mode 100644
index 0000000000..1eb190cf85
--- /dev/null
+++ b/src/examples/eolian_cxx/colourablesquare.c
@@ -0,0 +1,91 @@
1#include <stdio.h>
2
3#ifdef HAVE_CONFIG_H
4# include <config.h>
5#endif
6
7#include "Eo.h"
8
9#include "colourable.eo.h"
10#include "colourablesquare.eo.h"
11
12#define MY_CLASS COLOURABLESQUARE_CLASS
13
14static int _colourablesquare_impl_logdomain;
15
16#ifdef DBG
17#undef DBG
18#endif
19#define DBG(...) EINA_LOG_DOM_DBG(_colourablesquare_impl_logdomain, __VA_ARGS__)
20
21#ifdef INFO
22#undef INFO
23#endif
24#define INFO(...) EINA_LOG_DOM_INFO(_colourablesquare_impl_logdomain, __VA_ARGS__)
25
26#ifdef ERR
27#undef ERR
28#endif
29#define ERR(...) EINA_LOG_DOM_ERR(_colourablesquare_impl_logdomain, __VA_ARGS__)
30
31struct _ColourableSquare_Data
32{
33 int size;
34};
35
36typedef struct _ColourableSquare_Data ColourableSquare_Data;
37
38#define COLOURABLESQUARE_DATA_GET(o, wd) \
39 ColourableSquare_Data *wd = eo_data_scope_get(o, MY_CLASS)
40
41static void
42_colourablesquare_size_constructor(Eo *obj, ColourableSquare_Data *self, int size)
43{
44 if(!_colourablesquare_impl_logdomain)
45 {
46 _colourablesquare_impl_logdomain
47 = eina_log_domain_register
48 ("colourablesquare", EINA_COLOR_LIGHTBLUE);
49 }
50 self->size = size;
51 DBG("_colourablesquare_constructor(%d)\n", size);
52 eo_do_super(obj, MY_CLASS, eo_constructor());
53}
54
55static void
56_colourablesquare_destructor(Eo *obj, ColourableSquare_Data *self)
57{
58 eo_do_super(obj, MY_CLASS, eo_destructor());
59 if(_colourablesquare_impl_logdomain)
60 {
61 eina_log_domain_unregister(_colourablesquare_impl_logdomain);
62 _colourablesquare_impl_logdomain = 0;
63 }
64}
65
66static int
67_colourablesquare_size_get(Eo *obj, ColourableSquare_Data *self)
68{
69 DBG("_colourablesquare_size_get() => %d\n", self->size);
70 return self->size;
71}
72
73static void
74_colourablesquare_size_print(Eo *obj, ColourableSquare_Data *self)
75{
76 DBG("_colourablesquare_size_print() ==> %d\n", self->size);
77}
78
79static void
80_colourablesquare_size_set(Eo *obj, ColourableSquare_Data *self, int size)
81{
82 DBG("_colourablesquare_size_set(%d)\n", size);
83}
84
85static void
86_user_colourablesquare_class_constructor(Eo_Class *klass)
87{
88 DBG("_colourablesquare_class_constructor()\n");
89}
90
91#include "colourablesquare.eo.c"
diff --git a/src/examples/eolian_cxx/colourablesquare.eo b/src/examples/eolian_cxx/colourablesquare.eo
new file mode 100644
index 0000000000..d254151152
--- /dev/null
+++ b/src/examples/eolian_cxx/colourablesquare.eo
@@ -0,0 +1,23 @@
1class ColourableSquare (Colourable)
2{
3 constructors {
4 size_constructor { params { @in int size; } }
5 };
6 legacy_prefix: legacy;
7 properties {
8 size {
9 values {
10 int size;
11 };
12 set {
13 /*@ Sets size. */
14 };
15 get {
16 /*@ Gets size. */
17 };
18 };
19 };
20 methods {
21 size_print { /*@ Show the square. */ };
22 };
23};
diff --git a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
new file mode 100644
index 0000000000..798b3a8cf5
--- /dev/null
+++ b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
@@ -0,0 +1,69 @@
1
2#include <iostream>
3
4#ifdef HAVE_CONFIG_H
5# include <config.h>
6#endif
7
8#include "colourable.eo.hh"
9#include "colourablesquare.eo.hh"
10
11#include <eo_inherit.hh>
12
13using namespace efl;
14
15struct ColourableCircle
16 : efl::eo::inherit<ColourableCircle, ::colourable>
17{
18 ColourableCircle(int r, int g, int b)
19 : inherit_base(r, g, b)
20 {}
21
22 ColourableCircle(int rgb)
23 : inherit_base(efl::eo::args<::colourable>(rgb))
24 {}
25
26 int colour_get()
27 {
28 int rgb = 0;
29 eo_do_super(_eo_ptr(), _eo_class(), rgb = ::colourable_colour_get());
30 std::cout << "ColourableCircle::colour_get(" << this << ") ==> "
31 << std::hex << rgb << std::endl;
32 return rgb;
33 }
34};
35
36
37struct ColourableFoo
38 : efl::eo::inherit<ColourableFoo,
39 ::colourable,
40 ::colourablesquare>
41{
42 ColourableFoo(int size, int rgb)
43 : inherit_base(efl::eo::args<::colourable>(size)
44 , efl::eo::args<::colourablesquare>(rgb))
45 {}
46};
47
48int
49main()
50{
51 efl::eo::eo_init init;
52 eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG);
53
54 ColourableCircle obj1(0xc0, 0xff, 0xee);
55
56 ColourableCircle obj2(0xc0ffee);
57 int r, g, b;
58 obj2.composite_colour_get(&r, &g, &b);
59
60 assert(r == 0xc0);
61 assert(g == 0xff);
62 assert(b == 0xee);
63
64 assert(obj1.colour_get() == obj2.colour_get());
65
66 // ColourableFoo obj3(10, 0xc0ffee);
67
68 return 0;
69}
diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
new file mode 100644
index 0000000000..363073a259
--- /dev/null
+++ b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
@@ -0,0 +1,35 @@
1// EINA_LOG_LEVELS=colourable:4,colourablesquare:4 ./eolian_cxx_simple_01
2
3#include <iostream>
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif
8
9#include "colourable.eo.hh"
10#include "colourablesquare.eo.hh"
11
12int
13main()
14{
15 efl::eo::eo_init init;
16 eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG);
17 eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
18
19 int r, g, b;
20 ::colourable obj1(0x123456);
21 obj1.colour_set(0xc0ffee);
22 obj1.composite_colour_get(&r, &g, &b);
23
24 ::colourablesquare obj2(0x123456);
25 obj2.composite_colour_set(r, g, b);
26 obj2.size_set(11);
27 assert(obj1.colour_get() == obj2.colour_get());
28
29 efl::eo::wref<::colourable> ref = obj1;
30 efl::eina::optional<::colourable> obj3 = ref.lock();
31 assert(obj3);
32 obj3->colour_set(0x00);
33
34 return 0;
35}
diff --git a/src/examples/evas/Makefile.am b/src/examples/evas/Makefile.am
index eecd520d75..48fac12eeb 100644
--- a/src/examples/evas/Makefile.am
+++ b/src/examples/evas/Makefile.am
@@ -204,6 +204,21 @@ evas_aspect_hints_SOURCES = evas-aspect-hints.c
204evas_aspect_hints_CPPFLAGS = $(EDJE_COMMON_CPPFLAGS) 204evas_aspect_hints_CPPFLAGS = $(EDJE_COMMON_CPPFLAGS)
205evas_aspect_hints_LDADD = $(EDJE_COMMON_LDADD) 205evas_aspect_hints_LDADD = $(EDJE_COMMON_LDADD)
206 206
207EXTRA_PROGRAMS += evas_cxx_rectangle
208evas_cxx_rectangle_SOURCES = \
209evas_cxx_rectangle.cc \
210$(top_builddir)/src/lib/evas/canvas/evas_common_interface.eo.hh \
211$(top_builddir)/src/lib/evas/canvas/evas.eo.hh \
212$(top_builddir)/src/lib/evas/canvas/evas_object.eo.hh \
213$(top_builddir)/src/lib/evas/canvas/evas_image.eo.hh
214evas_cxx_rectangle_LDADD = $(ECORE_EVAS_COMMON_LDADD)
215evas_cxx_rectangle_CPPFLAGS = \
216-I$(top_srcdir)/src/bindings/eina_cxx \
217-I$(top_builddir)/src/bindings/eina_cxx \
218-I$(top_srcdir)/src/bindings/eo_cxx \
219-I$(top_builddir)/src/bindings/eo_cxx \
220$(ECORE_EVAS_COMMON_CPPFLAGS)
221
207EDJS = $(EDCS:%.edc=%.edj) 222EDJS = $(EDCS:%.edc=%.edj)
208 223
209SRCS = \ 224SRCS = \
diff --git a/src/examples/evas/evas_cxx_rectangle.cc b/src/examples/evas/evas_cxx_rectangle.cc
new file mode 100644
index 0000000000..3b01071ccd
--- /dev/null
+++ b/src/examples/evas/evas_cxx_rectangle.cc
@@ -0,0 +1,56 @@
1
2#include <iostream>
3
4#ifdef HAVE_CONFIG_H
5# include <config.h>
6#endif
7
8#include <Evas.h>
9#include <Ecore.h>
10#include <Ecore_Evas.h>
11
12#include <Eina.hh>
13#include <Eo.hh>
14
15#include "canvas/evas.eo.hh"
16#include "canvas/evas_image.eo.hh"
17#include "canvas/evas_rectangle.eo.hh"
18
19#define WIDTH (320)
20#define HEIGHT (240)
21
22int main()
23{
24 efl::eina::eina_init eina_init;
25 efl::eo::eo_init init;
26 if (!::ecore_evas_init()) return EXIT_FAILURE;
27 if (!::evas_init()) return EXIT_FAILURE;
28
29 Ecore_Evas *ee = ::ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
30 if (!ee)
31 {
32 fprintf(stderr,
33 "you got to have at least one evas engine built and linked"
34 " up to ecore-evas for this example to run properly.\n");
35 ::ecore_evas_free(ee);
36 return -1;
37 }
38
39 ecore_evas_show(ee);
40
41 {
42 ::evas canvas(::eo_ref(::ecore_evas_get(ee)));
43 ::evas_rectangle rect(efl::eo::parent = canvas);
44 rect.color_set(255, 0, 0, 255);
45 rect.position_set(10, 10);
46 rect.size_set(100, 100);
47 rect.visibility_set(true);
48 canvas.render();
49 }
50
51 ::ecore_main_loop_begin();
52
53 ::ecore_evas_free(ee);
54 ::ecore_evas_shutdown();
55 return 0;
56}
diff --git a/src/lib/.gitignore b/src/lib/.gitignore
index 62d9982fce..5ca060fe25 100644
--- a/src/lib/.gitignore
+++ b/src/lib/.gitignore
@@ -1,3 +1,8 @@
1/ecore_x/ecore_x_version.h 1/ecore_x/ecore_x_version.h
2/efl/Efl_Config.h 2/efl/Efl_Config.h
3/eina/eina_config.h 3/eina/eina_config.h
4/ecore_audio/Ecore_Audio.hh
5/ecore/Ecore.eo.hh
6/evas/Evas.hh
7/edje/Edje.hh
8/edje/Edje.eo.hh
diff --git a/src/lib/eolian_cxx/Eolian_Cxx.hh b/src/lib/eolian_cxx/Eolian_Cxx.hh
new file mode 100644
index 0000000000..c4fe6438a9
--- /dev/null
+++ b/src/lib/eolian_cxx/Eolian_Cxx.hh
@@ -0,0 +1,37 @@
1
2#ifndef EOLIAN_CXX_LIB_HH
3#define EOLIAN_CXX_LIB_HH
4
5extern "C"
6{
7#include <Eolian.h>
8#ifdef HAVE_CONFIG_H
9# include <config.h>
10#endif
11}
12
13namespace efl { namespace eolian {
14
15struct eolian_init
16{
17 eolian_init()
18 {
19 ::eolian_init();
20 }
21 ~eolian_init()
22 {
23 ::eolian_shutdown();
24 }
25};
26
27} }
28
29#ifdef EFL_BETA_API_SUPPORT
30
31#include "eo_types.hh"
32#include "eo_validate.hh"
33#include "eo_generate.hh"
34
35#endif
36
37#endif // EOLIAN_CXX_LIB_HH
diff --git a/src/lib/eolian_cxx/eo_generate.hh b/src/lib/eolian_cxx/eo_generate.hh
new file mode 100644
index 0000000000..477f263159
--- /dev/null
+++ b/src/lib/eolian_cxx/eo_generate.hh
@@ -0,0 +1,20 @@
1
2#ifndef EOLIAN_CXX_EO_GENERATE_HH
3#define EOLIAN_CXX_EO_GENERATE_HH
4
5#include "eo_types.hh"
6
7#include <iosfwd>
8#include "grammar/eo_header_generator.hh"
9
10namespace efl { namespace eolian {
11
12inline void
13generate(std::ostream& out, eo_class cls, eo_generator_options const& opts)
14{
15 grammar::eo_header_generator(out, cls, opts);
16}
17
18} }
19
20#endif // EOLIAN_CXX_EO_GENERATE_HH
diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh
new file mode 100644
index 0000000000..1d04fd04b6
--- /dev/null
+++ b/src/lib/eolian_cxx/eo_types.hh
@@ -0,0 +1,89 @@
1
2#ifndef EOLIAN_CXX_EO_TYPES_HH
3#define EOLIAN_CXX_EO_TYPES_HH
4
5#include <string>
6#include <vector>
7
8namespace efl { namespace eolian {
9
10struct eo_constructor;
11struct eo_parameter;
12struct eo_function;
13struct eo_event;
14
15typedef std::vector<std::string> extensions_container_type;
16typedef std::vector<eo_constructor> constructors_container_type;
17typedef std::vector<eo_function> functions_container_type;
18typedef std::vector<eo_parameter> parameters_container_type;
19typedef std::vector<eo_event> events_container_type;
20
21struct eo_generator_options
22{
23 std::vector<std::string> cxx_headers;
24 std::vector<std::string> c_headers;
25};
26
27struct eo_class
28{
29 enum eo_class_type
30 {
31 regular_, regular_noninst_, interface_, mixin_
32 };
33
34 eo_class_type type;
35 std::string name;
36 std::string eo_name;
37 std::string parent;
38 extensions_container_type extensions;
39 constructors_container_type constructors;
40 functions_container_type functions;
41 events_container_type events;
42 std::string comment;
43 std::string name_space;
44};
45
46struct eo_parameter
47{
48 std::string type;
49 std::string name;
50};
51
52struct eo_constructor
53{
54 std::string name;
55 parameters_container_type params;
56 std::string comment;
57};
58
59struct eo_function
60{
61 enum eo_function_type
62 {
63 regular_, class_
64 };
65 eo_function_type type;
66 std::string name;
67 std::string impl;
68 std::string ret;
69 parameters_container_type params;
70 std::string comment;
71};
72
73inline bool
74function_is_void(eo_function const& func)
75{
76 return func.ret == "void" || func.ret == "";
77}
78
79struct eo_event
80{
81 std::string name;
82 parameters_container_type params;
83 bool is_hot;
84 std::string comment;
85};
86
87} }
88
89#endif // EFL_EOLIAN_CXX_EO_TYPES_HH
diff --git a/src/lib/eolian_cxx/eo_validate.hh b/src/lib/eolian_cxx/eo_validate.hh
new file mode 100644
index 0000000000..9e5342d55d
--- /dev/null
+++ b/src/lib/eolian_cxx/eo_validate.hh
@@ -0,0 +1,91 @@
1
2#ifndef EOLIAN_CXX_EO_CLASS_VALIDATE_HH
3#define EOLIAN_CXX_EO_CLASS_VALIDATE_HH
4
5#include <string>
6#include <cassert>
7
8#ifdef DEBUG
9#include <iostream>
10#endif
11
12#include "eo_types.hh"
13
14namespace efl { namespace eolian {
15
16inline bool
17_isvalid(const std::string& name)
18{
19 return name.size() > 0 and isalpha(name[0]);
20}
21
22inline void
23_dbg(const std::string& msg)
24{
25#ifdef DEBUG
26 std::cerr << "eo_validate() - " << msg << std::endl;
27#endif
28}
29
30inline void
31eo_class_validate(const eo_class& cls)
32{
33 _dbg("class name... " + cls.name);
34 assert(_isvalid(cls.name));
35
36 _dbg("class type... " + cls.type);
37 assert(cls.type != eo_class::regular_ ||
38 cls.type != eo_class::regular_noninst_ ||
39 cls.type != eo_class::interface_ ||
40 cls.type != eo_class::mixin_);
41
42 {
43 constructors_container_type::const_iterator it,
44 first = cls.constructors.begin(),
45 last = cls.constructors.end();
46 for (it = first; it != last; ++it)
47 {
48 parameters_container_type::const_iterator
49 param = (*it).params.begin(),
50 last_param = (*it).params.end();
51 _dbg("constructor... " + (*it).name);
52 assert(_isvalid((*it).name));
53 for (; param != last_param; ++param)
54 {
55 _dbg("constructor parameter... " + (*param).name);
56 assert(_isvalid((*param).name));
57 _dbg("constructor parameter type... " + (*param).type);
58 assert(_isvalid((*param).type));
59 }
60 }
61 }
62
63 {
64 functions_container_type::const_iterator it,
65 first = cls.functions.begin(),
66 last = cls.functions.end();
67 for (it = first; it != last; ++it)
68 {
69 _dbg("function... " + (*it).name);
70 assert(_isvalid((*it).name));
71 _dbg("function api... " + (*it).impl);
72 assert(_isvalid((*it).impl));
73 _dbg("function return... " + (*it).ret);
74 assert(_isvalid((*it).ret));
75 parameters_container_type::const_iterator
76 param = (*it).params.begin(),
77 last_param = (*it).params.end();
78 for (; param != last_param; ++param)
79 {
80 _dbg("function parameter... " + (*param).name);
81 assert(_isvalid((*param).name));
82 _dbg("function parameter type... " + (*param).type);
83 assert(_isvalid((*param).type));
84 }
85 }
86 }
87}
88
89} } // namespace efl { namespace eolian {
90
91#endif // EOLIAN_CXX_EO_CLASS_VALIDATE_HH
diff --git a/src/lib/eolian_cxx/grammar/comment.hh b/src/lib/eolian_cxx/grammar/comment.hh
new file mode 100644
index 0000000000..f9853fb8c3
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/comment.hh
@@ -0,0 +1,42 @@
1
2#ifndef EOLIAN_CXX_STD_COMMENT_HH
3#define EOLIAN_CXX_STD_COMMENT_HH
4
5#include <iosfwd>
6#include <ostream>
7#include <sstream>
8
9#include "tab.hh"
10
11namespace efl { namespace eolian { namespace grammar {
12
13using std::endl;
14
15const std::string comment_prefix("///");
16
17struct comment
18{
19 std::string _doc;
20 int _tab;
21 comment(std::string const& doc, int tab = 0)
22 : _doc(doc), _tab(tab)
23 {}
24};
25
26inline std::ostream&
27operator<<(std::ostream& out, comment const& x)
28{
29 std::istringstream ss(x._doc);
30 std::string line;
31 while(std::getline(ss, line))
32 {
33 out << tab(x._tab) << comment_prefix
34 << (line.size() ? (" " + line) : "")
35 << endl;
36 }
37 return out;
38}
39
40} } } // namespace efl { namespace eolian { namespace grammar {
41
42#endif // EOLIAN_CXX_STD_COMMENT_HH
diff --git a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
new file mode 100644
index 0000000000..f434c560d0
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
@@ -0,0 +1,200 @@
1
2#ifndef EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
3#define EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
4
5#include <iosfwd>
6#include <string>
7
8#include "eo_types.hh"
9#include "tab.hh"
10#include "comment.hh"
11#include "parameters_generator.hh"
12
13namespace efl { namespace eolian { namespace grammar {
14
15struct class_name
16{
17 std::string _name;
18 class_name(std::string name)
19 : _name(name)
20 {}
21};
22
23inline std::ostream&
24operator<<(std::ostream& out, class_name const& x)
25{
26 out << x._name;
27 return out;
28}
29
30struct class_extensions
31{
32 eo_class const& _cls;
33 class_extensions(eo_class const& cls)
34 : _cls(cls)
35 {}
36};
37
38inline std::ostream&
39operator<<(std::ostream& out, class_extensions const& x)
40{
41 eo_class const& cls = x._cls;
42 extensions_container_type::const_iterator it, first = cls.extensions.begin();
43 extensions_container_type::const_iterator last = cls.extensions.end();
44 for (it = first; it != last; ++it)
45 {
46 if (it != first) out << ",";
47 out << tab(2)
48 << "efl::eo::detail::extension_inheritance<"
49 << *it << ">::type<"
50 << cls.name << ">";
51 }
52 out << endl;
53 return out;
54}
55
56struct class_inheritance
57{
58 eo_class const& _cls;
59 class_inheritance(eo_class const& cls)
60 : _cls(cls)
61 {}
62};
63
64inline std::ostream&
65operator<<(std::ostream& out, class_inheritance const& x)
66{
67 eo_class const& cls = x._cls;
68
69 out << class_name(cls.parent);
70 if (cls.extensions.size() > 0)
71 {
72 out << "," << endl << class_extensions(cls);
73 }
74 out << endl;
75 return out;
76}
77
78struct constructor_eo
79{
80 eo_class const& _cls;
81 constructor_eo(eo_class const& cls)
82 : _cls(cls)
83 {}
84};
85
86inline std::ostream&
87operator<<(std::ostream& out, constructor_eo const& x)
88{
89 std::string doc = "@brief Eo Constructor.\n\n"
90 "Constructs the object from an Eo* pointer stealing its ownership.\n\n"
91 "@param eo The Eo object pointer.\n\n";
92 out << comment(doc, 1)
93 << tab(1)
94 << "explicit " << x._cls.name << "(Eo* eo)" << endl
95 << tab(2) << ": " << class_name(x._cls.parent) << "(eo)" << endl
96 << tab(1) << "{}" << endl << endl;
97 return out;
98}
99
100struct constructors
101{
102 eo_class const& _cls;
103 constructors(eo_class const& cls)
104 : _cls(cls)
105 {}
106};
107
108inline std::ostream&
109operator<<(std::ostream& out, constructors const& x)
110{
111 constructors_container_type::const_iterator it,
112 first = x._cls.constructors.cbegin(),
113 last = x._cls.constructors.cend();
114 for (it = first; it != last; ++it)
115 {
116 eo_constructor const& ctor = *it;
117 out << comment(ctor.comment, 1)
118 << tab(1)
119 << x._cls.name
120 << '(' << parameters_declaration(ctor.params)
121 << (ctor.params.size() > 0 ? ", " : "")
122 << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
123 << tab(2) << ": " << class_name(x._cls.name)
124 << "(_c" << (it - first) << "(" << parameters_list(ctor.params)
125 << (ctor.params.size() > 0 ? ", " : "")
126 << "_p))" << endl
127 << tab(1) << "{}" << endl << endl;
128 }
129 return out;
130}
131
132struct copy_constructor
133{
134 eo_class const& _cls;
135 copy_constructor(eo_class const& cls)
136 : _cls(cls)
137 {}
138};
139
140inline std::ostream&
141operator<<(std::ostream& out, copy_constructor const& x)
142{
143 std::string doc = "@brief Copy Constructor.\n\n";
144 out << comment(doc, 1)
145 << tab(1)
146 << x._cls.name << "(" << x._cls.name << " const& other)" << endl
147 << tab(2) << ": " << class_name(x._cls.parent)
148 << "(eo_ref(other._eo_ptr()))" << endl
149 << tab(1) << "{}" << endl << endl;
150 return out;
151}
152
153struct destructor
154{
155 eo_class const& _cls;
156 destructor(eo_class const& cls)
157 : _cls(cls)
158 {}
159};
160
161inline std::ostream&
162operator<<(std::ostream& out, destructor const& x)
163{
164 out << tab(1)
165 << '~' << x._cls.name << "() {}" << endl << endl;
166 return out;
167}
168
169struct eo_class_constructors
170{
171 eo_class const& _cls;
172 eo_class_constructors(eo_class const& cls) : _cls(cls) {}
173};
174
175inline std::ostream&
176operator<<(std::ostream& out, eo_class_constructors const& x)
177{
178 constructors_container_type::const_iterator it,
179 first = x._cls.constructors.begin(),
180 last = x._cls.constructors.end();
181 for (it = first; it != last; ++it)
182 {
183 out << tab(1)
184 << "static Eo* _c" << (it - first) << "("
185 << parameters_declaration((*it).params)
186 << ((*it).params.size() > 0 ? ", " : "")
187 << "efl::eo::parent_type _p"
188 << ')' << endl
189 << tab(1) << "{" << endl
190 << tab(2) << "return eo_add_custom("
191 << x._cls.eo_name << ", _p._eo_raw, " << (*it).name
192 << "(" << parameters_list((*it).params) << "));" << endl
193 << tab(1) << "}" << endl << endl;
194 }
195 return out;
196}
197
198} } } // namespace efl { namespace eolian { namespace grammar {
199
200#endif // EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
diff --git a/src/lib/eolian_cxx/grammar/eo_class_events.generator.hh b/src/lib/eolian_cxx/grammar/eo_class_events.generator.hh
new file mode 100644
index 0000000000..fdb3a317b7
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/eo_class_events.generator.hh
@@ -0,0 +1,95 @@
1
2#ifndef EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
3#define EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
4
5#include <iosfwd>
6
7#include <algorithm> // std::transform()
8#include <ctype.h> // ::toupper()
9
10#include "eo_types.hh"
11#include "tab.hh"
12#include "comment.hh"
13#include "parameters_generator.hh"
14
15namespace efl { namespace eolian { namespace grammar {
16
17struct event_callback_add
18{
19 eo_event const& _event;
20 std::string const& _ev_name;
21 event_callback_add(eo_event const& event, std::string const& ev_name)
22 : _event(event),
23 _ev_name(ev_name)
24 {}
25};
26
27inline std::ostream&
28operator<<(std::ostream& out, event_callback_add const& x)
29{
30 // TODO implement
31 return out;
32}
33
34struct event_callback_del
35{
36 eo_event const& _event;
37 std::string const& _ev_name;
38 event_callback_del(eo_event const& event, std::string const& ev_name)
39 : _event(event),
40 _ev_name(ev_name)
41 {}
42