diff options
author | Felipe Magno de Almeida <felipe@expertisesolutions.com.br> | 2014-09-01 15:08:49 -0300 |
---|---|---|
committer | Felipe Magno de Almeida <felipe@expertisesolutions.com.br> | 2015-12-23 23:59:40 -0200 |
commit | a3db1dddd3ba67c81118f7f2c0bc753dc8aac551 (patch) | |
tree | 233ee1be7bfa299bff560207135d20940c4e411f /src | |
parent | 1a3cb45f1cc7fdf8d481879e6bd7349d9cb0b3fa (diff) |
efl-js: JavaScript Eolian binding
To configure efl sources with bindings to use in nodejs add ––with-js=nodejs in configure flags to generate node files
$ configure --with-js=nodejs
and compile normally with:
$ make
$ make install
To use, you have to require efl:
efl = require('efl')
The bindings is divided in two parts: generated and manually
written. The generation uses the Eolian library for parsing Eo files
and generate C++ code that is compiled against V8 interpreter library
to create a efl.node file that can be required in a node.js instance.
@feature
Diffstat (limited to '')
132 files changed, 19969 insertions, 135 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6ac8dc7580..248711bc34 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -15,6 +15,7 @@ check_PROGRAMS = | |||
15 | TESTS = | 15 | TESTS = |
16 | EXTRA_DIST = | 16 | EXTRA_DIST = |
17 | 17 | ||
18 | GENERATED_JS_BINDINGS = | ||
18 | 19 | ||
19 | EFL_INSTALL_EXEC_HOOK= | 20 | EFL_INSTALL_EXEC_HOOK= |
20 | 21 | ||
@@ -76,6 +77,21 @@ include Makefile_Eio_Cxx.am | |||
76 | include Makefile_Elua.am | 77 | include Makefile_Elua.am |
77 | include Makefile_Elocation.am | 78 | include Makefile_Elocation.am |
78 | 79 | ||
80 | if HAVE_JS | ||
81 | AM_V_CP = $(am__v_CP_@AM_V@) | ||
82 | am__v_CP_ = $(am__v_CP_@AM_DEFAULT_V@) | ||
83 | am__v_CP_0 = @echo " CP " $@; | ||
84 | CP = cp | ||
85 | if EFL_ENABLE_TESTS | ||
86 | if HAVE_NODEJS | ||
87 | AM_TESTS_ENVIRONMENT = NODE_PATH='$(abs_builddir)/lib/efl_js:$(abs_builddir)/tests/eolian_js:$(abs_builddir)/tests/efl_js'; export NODE_PATH; | ||
88 | endif | ||
89 | endif | ||
90 | endif | ||
91 | |||
92 | include Makefile_Eolian_Js.am | ||
93 | include Makefile_Efl_Js.am | ||
94 | |||
79 | .PHONY: benchmark examples | 95 | .PHONY: benchmark examples |
80 | 96 | ||
81 | BENCHMARK_SUBDIRS = \ | 97 | BENCHMARK_SUBDIRS = \ |
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am index b7e0b6b74d..13e5473a21 100644 --- a/src/Makefile_Ecore.am +++ b/src/Makefile_Ecore.am | |||
@@ -271,3 +271,13 @@ installed_ecoreluadir = $(datadir)/elua/modules/ecore | |||
271 | nodist_installed_ecorelua_DATA = $(generated_ecore_lua_all) | 271 | nodist_installed_ecorelua_DATA = $(generated_ecore_lua_all) |
272 | 272 | ||
273 | endif | 273 | endif |
274 | |||
275 | if HAVE_JS | ||
276 | |||
277 | generated_ecore_js_bindings = $(ecore_eolian_files:%.eo=%.eo.js.cc) | ||
278 | |||
279 | CLEANFILES += $(generated_ecore_js_bindings) | ||
280 | |||
281 | GENERATED_JS_BINDINGS += $(generated_ecore_js_bindings) | ||
282 | |||
283 | endif | ||
diff --git a/src/Makefile_Ecore_Audio.am b/src/Makefile_Ecore_Audio.am index ccce8f7fc0..b500118736 100644 --- a/src/Makefile_Ecore_Audio.am +++ b/src/Makefile_Ecore_Audio.am | |||
@@ -104,4 +104,15 @@ nodist_installed_ecoreaudiolua_DATA = $(generated_ecore_audio_lua_all) | |||
104 | 104 | ||
105 | endif | 105 | endif |
106 | 106 | ||
107 | if HAVE_JS | ||
108 | |||
109 | generated_ecore_audio_js_bindings = $(ecore_audio_eolian_files:%.eo=%.eo.js.cc) | ||
110 | |||
111 | CLEANFILES += $(generated_ecore_audio_js_bindings) | ||
112 | |||
113 | GENERATED_JS_BINDINGS += $(generated_ecore_audio_js_bindings) | ||
114 | |||
107 | endif | 115 | endif |
116 | |||
117 | endif | ||
118 | |||
diff --git a/src/Makefile_Ecore_Con.am b/src/Makefile_Ecore_Con.am index 87ad889b26..544e6d949f 100644 --- a/src/Makefile_Ecore_Con.am +++ b/src/Makefile_Ecore_Con.am | |||
@@ -143,3 +143,13 @@ installed_ecoreconluadir = $(datadir)/elua/modules/ecore_con | |||
143 | nodist_installed_ecoreconlua_DATA = $(generated_ecore_con_lua_all) | 143 | nodist_installed_ecoreconlua_DATA = $(generated_ecore_con_lua_all) |
144 | 144 | ||
145 | endif | 145 | endif |
146 | |||
147 | if HAVE_JS | ||
148 | |||
149 | generated_ecore_con_js_bindings = $(ecore_con_eolian_files:%.eo=%.eo.js.cc) | ||
150 | |||
151 | CLEANFILES += $(generated_ecore_con_js_bindings) | ||
152 | |||
153 | GENERATED_JS_BINDINGS += $(generated_ecore_con_js_bindings) | ||
154 | |||
155 | endif | ||
diff --git a/src/Makefile_Ecore_Js.am b/src/Makefile_Ecore_Js.am new file mode 100644 index 0000000000..df5ac2f5b1 --- /dev/null +++ b/src/Makefile_Ecore_Js.am | |||
@@ -0,0 +1,19 @@ | |||
1 | |||
2 | ### Library | ||
3 | |||
4 | if HAVE_JS | ||
5 | installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@ | ||
6 | dist_installed_ecorejsheaders_DATA = \ | ||
7 | bindings/js/ecore_js/Ecore_Js.hh \ | ||
8 | bindings/js/ecore_js/ecore_js_init.hh \ | ||
9 | bindings/js/ecore_js/ecore_js_mainloop.hh \ | ||
10 | bindings/js/ecore_js/ecore_js_timer.hh \ | ||
11 | bindings/js/ecore_js/ecore_js_event.hh \ | ||
12 | bindings/js/ecore_js/ecore_js_job.hh \ | ||
13 | bindings/js/ecore_js/ecore_js_idle.hh \ | ||
14 | bindings/js/ecore_js/ecore_js_animator.hh \ | ||
15 | bindings/js/ecore_js/ecore_js_poller.hh \ | ||
16 | bindings/js/ecore_js/ecore_js_throttle.hh \ | ||
17 | bindings/js/ecore_js/ecore_js_file.hh | ||
18 | endif | ||
19 | |||
diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am index ca0eefc463..4fa0ecf09f 100644 --- a/src/Makefile_Edje.am +++ b/src/Makefile_Edje.am | |||
@@ -130,7 +130,7 @@ if HAVE_WIN32 | |||
130 | USE_EDJE_BIN_LIBS = -L$(top_builddir)/src/lib/evil @USE_EDJE_LIBS@ | 130 | USE_EDJE_BIN_LIBS = -L$(top_builddir)/src/lib/evil @USE_EDJE_LIBS@ |
131 | else | 131 | else |
132 | USE_EDJE_BIN_LIBS = @USE_EDJE_LIBS@ | 132 | USE_EDJE_BIN_LIBS = @USE_EDJE_LIBS@ |
133 | endif | 133 | endif |
134 | 134 | ||
135 | bin_PROGRAMS += \ | 135 | bin_PROGRAMS += \ |
136 | bin/edje/edje_cc \ | 136 | bin/edje/edje_cc \ |
@@ -334,3 +334,13 @@ installed_edjeluadir = $(datadir)/elua/modules/edje | |||
334 | nodist_installed_edjelua_DATA = $(generated_edje_lua_all) | 334 | nodist_installed_edjelua_DATA = $(generated_edje_lua_all) |
335 | 335 | ||
336 | endif | 336 | endif |
337 | |||
338 | if HAVE_JS | ||
339 | |||
340 | generated_edje_js_bindings = $(edje_eolian_files:%.eo=%.eo.js.cc) | ||
341 | |||
342 | CLEANFILES += $(generated_edje_js_bindings) | ||
343 | |||
344 | GENERATED_JS_BINDINGS += $(generated_edje_js_bindings) | ||
345 | |||
346 | endif | ||
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am index f6b1c288c6..9e59bf22bf 100644 --- a/src/Makefile_Efl.am +++ b/src/Makefile_Efl.am | |||
@@ -80,6 +80,16 @@ nodist_installed_efllua_DATA = $(generated_efl_lua_all) | |||
80 | 80 | ||
81 | endif | 81 | endif |
82 | 82 | ||
83 | if HAVE_JS | ||
84 | |||
85 | generated_efl_js_bindings = $(efl_eolian_files:%.eo=%.eo.js.cc) | ||
86 | |||
87 | CLEANFILES += $(generated_efl_js_bindings) | ||
88 | |||
89 | GENERATED_JS_BINDINGS += $(generated_efl_js_bindings) | ||
90 | |||
91 | endif | ||
92 | |||
83 | ### Binary | 93 | ### Binary |
84 | 94 | ||
85 | bin_PROGRAMS += \ | 95 | bin_PROGRAMS += \ |
diff --git a/src/Makefile_Efl_Js.am b/src/Makefile_Efl_Js.am new file mode 100644 index 0000000000..e993120a64 --- /dev/null +++ b/src/Makefile_Efl_Js.am | |||
@@ -0,0 +1,333 @@ | |||
1 | if HAVE_JS | ||
2 | |||
3 | if HAVE_NODEJS | ||
4 | |||
5 | noinst_lib_LTLIBRARIES = lib/efl_js/libefl_node_js.la | ||
6 | noinst_libdir = $(libdir)/efl_js | ||
7 | |||
8 | $(top_builddir)/src/lib/efl_js/efl.node: lib/efl_js/libefl_node_js.la | ||
9 | $(AM_V_CP)$(CP) $(top_builddir)/src/lib/efl_js/.libs/libefl_node_js.so $(top_builddir)/src/lib/efl_js/efl.node | ||
10 | |||
11 | eflnodedir = $(libdir)/node_modules | ||
12 | eflnode_DATA = $(top_builddir)/src/lib/efl_js/efl.node | ||
13 | |||
14 | CLEANFILES += ${eflnodedir_DATA} | ||
15 | EXTRA_DIST += ${eflnodedir_DATA} | ||
16 | |||
17 | efljsmimedir = @XDG_DATA_HOME@/mime/packages | ||
18 | efljsmime_DATA = bin/efl_js/efljslaunch.xml | ||
19 | |||
20 | efljsdesktopdir = @XDG_DATA_HOME@/applications | ||
21 | efljsdesktop_DATA = bin/efl_js/efljslaunch.desktop | ||
22 | |||
23 | bin_SCRIPTS += \ | ||
24 | bin/efl_js/efljslaunch \ | ||
25 | bin/efl_js/efljspack | ||
26 | |||
27 | else | ||
28 | |||
29 | bin_PROGRAMS += bin/efl_js/eflv8js | ||
30 | |||
31 | bin_efl_js_eflv8js_SOURCES = \ | ||
32 | bin/efl_js/launcher_main.cc | ||
33 | |||
34 | bin_efl_js_eflv8js_CPPFLAGS = \ | ||
35 | -I$(top_builddir)/src/lib/efl \ | ||
36 | -I$(top_srcdir)/src/bindings/js/efl_js \ | ||
37 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
38 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
39 | @CHECK_CFLAGS@ \ | ||
40 | @EINA_CXX_CFLAGS@ \ | ||
41 | @EO_CXX_CFLAGS@ \ | ||
42 | @EMILE_CFLAGS@ \ | ||
43 | @ECORE_CFLAGS@ \ | ||
44 | @EET_CFLAGS@ \ | ||
45 | @EO_CFLAGS@ \ | ||
46 | @EFL_JS_CFLAGS@ \ | ||
47 | @EINA_JS_CFLAGS@ \ | ||
48 | @EO_JS_CFLAGS@ | ||
49 | |||
50 | bin_efl_js_eflv8js_LDFLAGS = \ | ||
51 | -lv8 \ | ||
52 | @USE_EFL_JS_INTERNAL_LIBS@ | ||
53 | |||
54 | bin_efl_js_eflv8js_LDADD = \ | ||
55 | @USE_EFL_JS_LIBS@ | ||
56 | |||
57 | endif | ||
58 | |||
59 | bindings/js/efl_js/eolian_js_bindings.cc: $(GENERATED_JS_BINDINGS) | ||
60 | @echo @ECHO_E@ "#ifdef HAVE_CONFIG_H" > $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
61 | @echo @ECHO_E@ "#include \"config.h\"" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
62 | @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
63 | @echo @ECHO_E@ "#include <Efl.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
64 | @echo @ECHO_E@ "#include <Efl_Config.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
65 | @echo @ECHO_E@ "#include <Ecore.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
66 | @echo @ECHO_E@ "#include <Eo.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
67 | @echo @ECHO_E@ "#include <Ecore_Con.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
68 | @echo @ECHO_E@ "#include <Ecore_Audio.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
69 | @echo @ECHO_E@ "#include <Evas.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
70 | @echo @ECHO_E@ "#include <Edje.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
71 | @echo @ECHO_E@ "#include <Ecore_Con_Eet.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
72 | @echo @ECHO_E@ "#include <Emotion.h>\n" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc | ||
73 | @for i in $(GENERATED_JS_BINDINGS); do echo "#include <$$i>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc; done | ||
74 | |||
75 | CLEANFILES += bindings/js/efl_js/eolian_js_bindings.cc | ||
76 | |||
77 | ## Install Ecore-JS headers | ||
78 | installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@ | ||
79 | dist_installed_ecorejsheaders_DATA = \ | ||
80 | bindings/js/ecore_js/Ecore_Js.hh | ||
81 | |||
82 | ## Install Eio-JS headers | ||
83 | installed_eiojsheadersdir = $(includedir)/eio-js-@VMAJ@ | ||
84 | dist_installed_eiojsheaders_DATA = \ | ||
85 | bindings/js/eio_js/Eio_Js.hh | ||
86 | |||
87 | ## Install Ethumb-JS headers | ||
88 | installed_ethumbjsheadersdir = $(includedir)/ethumb-js-@VMAJ@ | ||
89 | dist_installed_ethumbjsheaders_DATA = \ | ||
90 | bindings/js/ethumb_js/Ethumb_Js.hh | ||
91 | |||
92 | ## Install Eldbus-JS headers | ||
93 | installed_eldbusjsheadersdir = $(includedir)/eldbus-js-@VMAJ@ | ||
94 | dist_installed_eldbusjsheaders_DATA = \ | ||
95 | bindings/js/eldbus_js/Eldbus_Js.hh | ||
96 | |||
97 | ## Install Eo-JS headers | ||
98 | installed_eojsmainheadersdir = $(includedir)/eo-js-@VMAJ@ | ||
99 | dist_installed_eojsmainheaders_DATA = \ | ||
100 | bindings/js/eo_js/eo_js_call_function.hh \ | ||
101 | bindings/js/eo_js/eo_js_constructor.hh \ | ||
102 | bindings/js/eo_js/eo_js_direction.hh \ | ||
103 | bindings/js/eo_js/eo_js_event.hh \ | ||
104 | bindings/js/eo_js/eo_js_namespace.hh \ | ||
105 | bindings/js/eo_js/eo_js_struct.hh \ | ||
106 | bindings/js/eo_js/eo_js_construct_from_eo.hh \ | ||
107 | bindings/js/eo_js/Eo_Js.hh | ||
108 | |||
109 | ## Install Eina-JS headers | ||
110 | installed_einajsheadersdir = $(includedir)/eina-js-@VMAJ@ | ||
111 | dist_installed_einajsheaders_DATA = \ | ||
112 | bindings/js/eina_js/Eina_Js.hh \ | ||
113 | bindings/js/eina_js/eina_js_accessor.hh \ | ||
114 | bindings/js/eina_js/eina_js_array.hh \ | ||
115 | bindings/js/eina_js/eina_js_compatibility.hh \ | ||
116 | bindings/js/eina_js/eina_js_container.hh \ | ||
117 | bindings/js/eina_js/eina_js_error.hh \ | ||
118 | bindings/js/eina_js/eina_js_get_value_from_c.hh \ | ||
119 | bindings/js/eina_js/eina_js_get_value.hh \ | ||
120 | bindings/js/eina_js/eina_js_iterator.hh \ | ||
121 | bindings/js/eina_js/eina_js_list.hh \ | ||
122 | bindings/js/eina_js/eina_js_log.hh \ | ||
123 | bindings/js/eina_js/eina_js_node.hh \ | ||
124 | bindings/js/eina_js/eina_js_value.hh | ||
125 | |||
126 | installed_efljsheadersdir = $(includedir)/efl-js-@VMAJ@ | ||
127 | dist_installed_efljsheaders_DATA = \ | ||
128 | bindings/js/efl_js/Efl_Js.hh | ||
129 | |||
130 | lib_LTLIBRARIES += lib/efl_js/libefl_js.la | ||
131 | |||
132 | lib_efl_js_libefl_js_la_SOURCES = \ | ||
133 | bindings/js/eina_js/eina_js_container.cc \ | ||
134 | bindings/js/eina_js/eina_js_value.cc \ | ||
135 | bindings/js/eina_js/eina_js_error.cc \ | ||
136 | bindings/js/eina_js/eina_js_accessor.cc \ | ||
137 | bindings/js/eina_js/eina_js_log.cc \ | ||
138 | bindings/js/eina_js/eina_js_iterator.cc \ | ||
139 | bindings/js/eina_js/eina_js_compatibility.cc \ | ||
140 | bindings/js/ecore_js/ecore_js_init.cc \ | ||
141 | bindings/js/ecore_js/ecore_js_mainloop.cc \ | ||
142 | bindings/js/ecore_js/ecore_js_timer.cc \ | ||
143 | bindings/js/ecore_js/ecore_js_event.cc \ | ||
144 | bindings/js/ecore_js/ecore_js_job.cc \ | ||
145 | bindings/js/ecore_js/ecore_js_idle.cc \ | ||
146 | bindings/js/ecore_js/ecore_js_animator.cc \ | ||
147 | bindings/js/ecore_js/ecore_js_poller.cc \ | ||
148 | bindings/js/ecore_js/ecore_js_throttle.cc \ | ||
149 | bindings/js/eldbus_js/eldbus_js_core.cc \ | ||
150 | bindings/js/eldbus_js/eldbus_js_connection.cc \ | ||
151 | bindings/js/eldbus_js/eldbus_js_message.cc \ | ||
152 | bindings/js/eldbus_js/eldbus_js_object_mapper.cc \ | ||
153 | bindings/js/eio_js/eio_js.cc \ | ||
154 | bindings/js/ethumb_js/ethumb_js_client.cc | ||
155 | |||
156 | nodist_lib_efl_js_libefl_js_la_SOURCES = \ | ||
157 | bindings/js/efl_js/eolian_js_bindings.cc | ||
158 | |||
159 | bindings/js/efl_js/efl_js.cc $(lib_efl_js_libefl_js_la_SOURCES): $(generated_ecore_cxx_all) $(generated_eo_cxx_bindings) $(generated_efl_cxx_all) | ||
160 | |||
161 | lib_efl_js_libefl_js_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | ||
162 | -I$(top_srcdir)/src/lib/efl \ | ||
163 | -I$(top_builddir)/src/lib/efl/interfaces/ \ | ||
164 | -I$(top_builddir)/src/lib/evas/canvas/ \ | ||
165 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
166 | -I$(top_srcdir)/src/bindings/js/ecore_js \ | ||
167 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
168 | -I$(top_srcdir)/src/bindings/js/eldbus_js \ | ||
169 | -I$(top_srcdir)/src/bindings/js/eio_js \ | ||
170 | -I$(top_srcdir)/src/bindings/js/ethumb_js \ | ||
171 | @EFL_JS_CFLAGS@ \ | ||
172 | @EO_JS_CFLAGS@ \ | ||
173 | @ECORE_CXX_CFLAGS@ \ | ||
174 | @EO_CXX_CFLAGS@ \ | ||
175 | @ECORE_JS_CFLAGS@ \ | ||
176 | @EINA_JS_CFLAGS@ \ | ||
177 | @ELDBUS_JS_CFLAGS@ \ | ||
178 | @EIO_JS_CFLAGS@ \ | ||
179 | @ETHUMB_JS_CFLAGS@ \ | ||
180 | @EINA_CXX_CFLAGS@ | ||
181 | lib_efl_js_libefl_js_la_LIBADD = @EFL_JS_LIBS@ | ||
182 | lib_efl_js_libefl_js_la_DEPENDENCIES = @EFL_JS_INTERNAL_LIBS@ | ||
183 | lib_efl_js_libefl_js_la_LIBTOOLFLAGS = --tag=disable-static | ||
184 | lib_efl_js_libefl_js_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ | ||
185 | |||
186 | if HAVE_NODEJS | ||
187 | lib_efl_js_libefl_node_js_la_SOURCES = \ | ||
188 | bindings/js/efl_js/efl_js.cc | ||
189 | |||
190 | lib_efl_js_libefl_node_js_la_CPPFLAGS = $(lib_efl_js_libefl_js_la_CPPFLAGS) | ||
191 | lib_efl_js_libefl_node_js_la_LIBADD = @USE_EFL_JS_LIBS@ | ||
192 | lib_efl_js_libefl_node_js_la_DEPENDENCIES = @USE_EFL_JS_INTERNAL_LIBS@ | ||
193 | lib_efl_js_libefl_node_js_la_LIBTOOLFLAGS = --tag=disable-static | ||
194 | lib_efl_js_libefl_node_js_la_LDFLAGS = | ||
195 | else | ||
196 | lib_efl_js_libefl_js_la_SOURCES += \ | ||
197 | bindings/js/efl_js/efl_js.cc | ||
198 | endif | ||
199 | |||
200 | if EFL_ENABLE_TESTS | ||
201 | |||
202 | SUITE_RUNNER_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | ||
203 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
204 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
205 | -DTESTS_WD=\"`pwd`\" \ | ||
206 | -DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl_js\" \ | ||
207 | -DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/efl_js\" \ | ||
208 | -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl_js\" \ | ||
209 | @CHECK_CFLAGS@ \ | ||
210 | @EFL_JS_CFLAGS@ \ | ||
211 | @EINA_CXX_CFLAGS@ \ | ||
212 | @EO_CXX_CFLAGS@ \ | ||
213 | @EO_CFLAGS@ \ | ||
214 | @ECORE_CFLAGS@ \ | ||
215 | @ECORE_CXX_CFLAGS@ \ | ||
216 | @ECORE_JS_CFLAGS@ \ | ||
217 | @EINA_JS_CFLAGS@ | ||
218 | |||
219 | if HAVE_NODEJS | ||
220 | TESTS += tests/efl_js/eina_js_suite.js \ | ||
221 | tests/efl_js/eina_js_containers_suite.js \ | ||
222 | tests/efl_js/ecore_js_suite.js \ | ||
223 | tests/efl_js/eldbus_js_suite.js \ | ||
224 | tests/efl_js/ethumb_js_suite.js \ | ||
225 | tests/efl_js/eio_js_suite.js \ | ||
226 | tests/efl_js/benchmark_js_suite.js | ||
227 | |||
228 | check_LTLIBRARIES += tests/efl_js/libbenchmark_object.la | ||
229 | |||
230 | tests/efl_js/eina_js_suite.js tests/efl_js/eina_js_containers_suite.js tests/efl_js/ecore_js_suite.js tests/efl_js/eldbus_js_suite.js tests/efl_js/eio_js_suite.js tests/efl_js/ethumb_js_suite.js: $(top_builddir)/src/lib/efl_js/efl.node | ||
231 | |||
232 | tests/efl_js/benchmark_object.node: tests/efl_js/libbenchmark_object.la | ||
233 | $(AM_V_CP)$(CP) $(top_builddir)/src/tests/efl_js/.libs/libbenchmark_object.so $(top_builddir)/src/tests/efl_js/benchmark_object.node | ||
234 | tests/efl_js/benchmark_js_suite.js: $(top_builddir)/src/lib/efl_js/efl.node tests/efl_js/benchmark_object.node | ||
235 | |||
236 | tests_efl_js_libbenchmark_object_la_SOURCES = tests/efl_js/benchmark_object_impl.cc | ||
237 | tests_efl_js_libbenchmark_object_la_CPPFLAGS = \ | ||
238 | -I$(top_builddir)/src/lib/efl \ | ||
239 | -I$(top_srcdir)/src/bindings/js/efl_js \ | ||
240 | -I$(top_builddir)/src/tests/efl_js \ | ||
241 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
242 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
243 | -DTESTS_WD=\"`pwd`\" \ | ||
244 | -DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl_js\" \ | ||
245 | -DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/efl_js\" \ | ||
246 | -DPACKAGE_DATA_DIR=\"$(datadir)/efl_js\" \ | ||
247 | -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl_js\" \ | ||
248 | @CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ \ | ||
249 | @EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \ | ||
250 | @EO_JS_CFLAGS@ @EO_CXX_CFLAGS@ | ||
251 | tests_efl_js_libbenchmark_object_la_LIBADD = \ | ||
252 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
253 | tests_efl_js_libbenchmark_object_la_LDFLAGS = -rpath $(abs_top_builddir)/tests/efl_js @EFL_LTLIBRARY_FLAGS@ | ||
254 | tests_efl_js_libbenchmark_object_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
255 | tests_efl_js_libbenchmark_object_la_LIBTOOLFLAGS = --tag=disable-static | ||
256 | |||
257 | tests/efl_js/tests_efl_js_libbenchmark_object_la-benchmark_object_impl.l$(OBJEXT): tests/efl_js/benchmark_object.eo.js.cc tests/efl_js/benchmark_object.eo.c tests/efl_js/benchmark_object.eo.h | ||
258 | else | ||
259 | check_PROGRAMS += \ | ||
260 | tests/efl_js/eina_js_suite \ | ||
261 | tests/efl_js/eina_js_containers_suite \ | ||
262 | tests/efl_js/ecore_js_suite \ | ||
263 | tests/efl_js/eldbus_js_suite \ | ||
264 | tests/efl_js/ethumb_js_suite \ | ||
265 | tests/efl_js/eio_js_suite \ | ||
266 | tests/efl_js/benchmark_js_suite | ||
267 | TESTS += tests/efl_js/eina_js_suite \ | ||
268 | tests/efl_js/ecore_js_suite \ | ||
269 | tests/efl_js/eldbus_js_suite \ | ||
270 | tests/efl_js/ethumb_js_suite \ | ||
271 | tests/efl_js/eio_js_suite \ | ||
272 | tests/efl_js/benchmark_js_suite | ||
273 | |||
274 | tests_efl_js_eina_js_suite_SOURCES = \ | ||
275 | tests/efl_js/eina_js_suite.cc | ||
276 | |||
277 | tests_efl_js_eina_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
278 | tests_efl_js_eina_js_suite_LDADD = \ | ||
279 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
280 | tests_efl_js_eina_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
281 | |||
282 | tests_efl_js_eina_js_containers_suite_SOURCES = \ | ||
283 | tests/efl_js/eina_js_containers_suite.cc | ||
284 | |||
285 | tests_efl_js_eina_js_containers_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
286 | tests_efl_js_eina_js_containers_suite_LDADD = \ | ||
287 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
288 | tests_efl_js_eina_js_containers_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
289 | |||
290 | tests_efl_js_ecore_js_suite_SOURCES = \ | ||
291 | tests/efl_js/ecore_js_suite.cc | ||
292 | |||
293 | tests_efl_js_ecore_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
294 | tests_efl_js_ecore_js_suite_LDADD = \ | ||
295 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
296 | tests_efl_js_ecore_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
297 | |||
298 | tests_efl_js_eldbus_js_suite_SOURCES = \ | ||
299 | tests/efl_js/eldbus_js_suite.cc | ||
300 | |||
301 | tests_efl_js_eldbus_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
302 | tests_efl_js_eldbus_js_suite_LDADD = \ | ||
303 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
304 | tests_efl_js_eldbus_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
305 | |||
306 | tests_efl_js_ethumb_js_suite_SOURCES = \ | ||
307 | tests/efl_js/ethumb_js_suite.cc | ||
308 | |||
309 | tests_efl_js_ethumb_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
310 | tests_efl_js_ethumb_js_suite_LDADD = \ | ||
311 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
312 | tests_efl_js_ethumb_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
313 | |||
314 | tests_efl_js_eio_js_suite_SOURCES = \ | ||
315 | tests/efl_js/eio_js_suite.cc | ||
316 | |||
317 | tests_efl_js_eio_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
318 | tests_efl_js_eio_js_suite_LDADD = \ | ||
319 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
320 | tests_efl_js_eio_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
321 | |||
322 | tests_efl_js_benchmark_js_suite_SOURCES = \ | ||
323 | tests/efl_js/benchmark_js_suite.cc | ||
324 | |||
325 | tests_efl_js_benchmark_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS) | ||
326 | tests_efl_js_benchmark_js_suite_LDADD = \ | ||
327 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
328 | tests_efl_js_benchmark_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
329 | endif | ||
330 | endif | ||
331 | |||
332 | |||
333 | endif | ||
diff --git a/src/Makefile_Eina_Cxx.am b/src/Makefile_Eina_Cxx.am index 70ef18a7bd..e9f7c13eb9 100644 --- a/src/Makefile_Eina_Cxx.am +++ b/src/Makefile_Eina_Cxx.am | |||
@@ -14,6 +14,7 @@ bindings/eina_cxx/eina_clone_allocators.hh \ | |||
14 | bindings/eina_cxx/eina_error.hh \ | 14 | bindings/eina_cxx/eina_error.hh \ |
15 | bindings/eina_cxx/eina_eo_concrete_fwd.hh \ | 15 | bindings/eina_cxx/eina_eo_concrete_fwd.hh \ |
16 | bindings/eina_cxx/eina_fold.hh \ | 16 | bindings/eina_cxx/eina_fold.hh \ |
17 | bindings/eina_cxx/eina_function.hh \ | ||
17 | bindings/eina_cxx/eina_inarray.hh \ | 18 | bindings/eina_cxx/eina_inarray.hh \ |
18 | bindings/eina_cxx/eina_inlist.hh \ | 19 | bindings/eina_cxx/eina_inlist.hh \ |
19 | bindings/eina_cxx/eina_integer_sequence.hh \ | 20 | bindings/eina_cxx/eina_integer_sequence.hh \ |
@@ -21,7 +22,9 @@ bindings/eina_cxx/eina_iterator.hh \ | |||
21 | bindings/eina_cxx/eina_lists_auxiliary.hh \ | 22 | bindings/eina_cxx/eina_lists_auxiliary.hh \ |
22 | bindings/eina_cxx/eina_list.hh \ | 23 | bindings/eina_cxx/eina_list.hh \ |
23 | bindings/eina_cxx/eina_log.hh \ | 24 | bindings/eina_cxx/eina_log.hh \ |
25 | bindings/eina_cxx/eina_logical.hh \ | ||
24 | bindings/eina_cxx/eina_optional.hh \ | 26 | bindings/eina_cxx/eina_optional.hh \ |
27 | bindings/eina_cxx/eina_pp.hh \ | ||
25 | bindings/eina_cxx/eina_ptrarray.hh \ | 28 | bindings/eina_cxx/eina_ptrarray.hh \ |
26 | bindings/eina_cxx/eina_ptrlist.hh \ | 29 | bindings/eina_cxx/eina_ptrlist.hh \ |
27 | bindings/eina_cxx/eina_range_types.hh \ | 30 | bindings/eina_cxx/eina_range_types.hh \ |
@@ -31,6 +34,7 @@ bindings/eina_cxx/eina_string_view.hh \ | |||
31 | bindings/eina_cxx/eina_thread.hh \ | 34 | bindings/eina_cxx/eina_thread.hh \ |
32 | bindings/eina_cxx/eina_throw.hh \ | 35 | bindings/eina_cxx/eina_throw.hh \ |
33 | bindings/eina_cxx/eina_tuple.hh \ | 36 | bindings/eina_cxx/eina_tuple.hh \ |
37 | bindings/eina_cxx/eina_tuple_c.hh \ | ||
34 | bindings/eina_cxx/eina_tuple_unwrap.hh \ | 38 | bindings/eina_cxx/eina_tuple_unwrap.hh \ |
35 | bindings/eina_cxx/eina_type_traits.hh \ | 39 | bindings/eina_cxx/eina_type_traits.hh \ |
36 | bindings/eina_cxx/eina_value.hh | 40 | bindings/eina_cxx/eina_value.hh |
diff --git a/src/Makefile_Emotion.am b/src/Makefile_Emotion.am index f16a4a4c3d..4da5224060 100644 --- a/src/Makefile_Emotion.am +++ b/src/Makefile_Emotion.am | |||
@@ -347,3 +347,14 @@ installed_emotionluadir = $(datadir)/elua/modules/emotion | |||
347 | nodist_installed_emotionlua_DATA = $(generated_emotion_lua_all) | 347 | nodist_installed_emotionlua_DATA = $(generated_emotion_lua_all) |
348 | 348 | ||
349 | endif | 349 | endif |
350 | |||
351 | # TODO: gives undefined reference to emotion_object_class_get() | ||
352 | if HAVE_JS | ||
353 | |||
354 | generated_emotion_js_bindings = $(emotion_eolian_files:%.eo=%.eo.js.cc) | ||
355 | |||
356 | CLEANFILES += $(generated_emotion_js_bindings) | ||
357 | |||
358 | GENERATED_JS_BINDINGS += $(generated_emotion_js_bindings) | ||
359 | |||
360 | endif | ||
diff --git a/src/Makefile_Eo.am b/src/Makefile_Eo.am index 57b096e795..51924feeff 100644 --- a/src/Makefile_Eo.am +++ b/src/Makefile_Eo.am | |||
@@ -197,3 +197,13 @@ endif | |||
197 | 197 | ||
198 | 198 | ||
199 | EXTRA_DIST += tests/eo/eunit_tests.h lib/eo/eo_ptr_indirection.x | 199 | EXTRA_DIST += tests/eo/eunit_tests.h lib/eo/eo_ptr_indirection.x |
200 | |||
201 | if HAVE_JS | ||
202 | |||
203 | generated_eo_js_bindings = $(eo_eolian_files:%.eo=%.eo.js.cc) | ||
204 | |||
205 | CLEANFILES += $(generated_eo_js_bindings) | ||
206 | |||
207 | GENERATED_JS_BINDINGS += $(generated_eo_js_bindings) | ||
208 | |||
209 | endif | ||
diff --git a/src/Makefile_Eolian_Js.am b/src/Makefile_Eolian_Js.am new file mode 100644 index 0000000000..32cf893bf6 --- /dev/null +++ b/src/Makefile_Eolian_Js.am | |||
@@ -0,0 +1,123 @@ | |||
1 | |||
2 | if HAVE_JS | ||
3 | |||
4 | ### Binary | ||
5 | bin_PROGRAMS += bin/eolian_js/eolian_js | ||
6 | |||
7 | bin_eolian_js_eolian_js_SOURCES = \ | ||
8 | bin/eolian_js/main.cc | ||
9 | |||
10 | bin_eolian_js_eolian_js_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | ||
11 | -I$(top_srcdir)/src/bin/eolian_js \ | ||
12 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
13 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
14 | @EOLIAN_JS_CFLAGS@ \ | ||
15 | @EINA_CXX_CFLAGS@ \ | ||
16 | @EOLIAN_CXX_CFLAGS@ | ||
17 | |||
18 | bin_eolian_js_eolian_js_LDADD = @USE_EO_LIBS@ @USE_EOLIAN_LIBS@ | ||
19 | bin_eolian_js_eolian_js_DEPENDENCIES = @USE_EO_INTERNAL_LIBS@ @USE_EOLIAN_INTERNAL_LIBS@ | ||
20 | |||
21 | include Makefile_Eolian_Js_Helper.am | ||
22 | |||
23 | ### Unit tests | ||
24 | |||
25 | if EFL_ENABLE_TESTS | ||
26 | if HAVE_NODEJS | ||
27 | |||
28 | TESTS += tests/eolian_js/eolian_js_suite.js | ||
29 | |||
30 | check_LTLIBRARIES += tests/eolian_js/libeolian_js_suite.la | ||
31 | |||
32 | tests/eolian_js/eolian_js_suite.js: tests/eolian_js/eolian_js_suite_mod.node | ||
33 | tests/eolian_js/eolian_js_suite_mod.node: tests/eolian_js/libeolian_js_suite.la | ||
34 | $(AM_V_CP)$(CP) $(top_builddir)/src/tests/eolian_js/.libs/libeolian_js_suite.so $(top_builddir)/src/tests/eolian_js/eolian_js_suite_mod.node | ||
35 | |||
36 | tests_eolian_js_libeolian_js_suite_la_SOURCES = \ | ||
37 | tests/eolian_js/eolian_js_suite.cc \ | ||
38 | tests/eolian_js/eolian_js_test_eolian_js_binding.cc \ | ||
39 | tests/eolian_js/eolian_js_test_constructor_method_impl.c \ | ||
40 | tests/eolian_js/eolian_js_test_test_object_impl.c | ||
41 | |||
42 | tests_eolian_js_libeolian_js_suite_la_CPPFLAGS = \ | ||
43 | -I$(top_builddir)/src/lib/efl \ | ||
44 | -I$(top_srcdir)/src/bin/eolian_js \ | ||
45 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
46 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
47 | -I$(top_builddir)/src/tests/eolian_js \ | ||
48 | -DTESTS_WD=\"`pwd`\" \ | ||
49 | -DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_js\" \ | ||
50 | -DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_js\" \ | ||
51 | -DPACKAGE_DATA_DIR=\"$(datadir)/eolian_js\" \ | ||
52 | -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_js\" \ | ||
53 | @CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ \ | ||
54 | @EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \ | ||
55 | @EO_JS_CFLAGS@ @EO_CXX_CFLAGS@ | ||
56 | tests_eolian_js_libeolian_js_suite_la_LIBADD = \ | ||
57 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ | ||
58 | tests_eolian_js_libeolian_js_suite_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
59 | tests_eolian_js_libeolian_js_suite_la_CFLAGS = $(tests_eolian_js_libeolian_js_suite_la_CXXFLAGS) | ||
60 | tests_eolian_js_libeolian_js_suite_la_LIBTOOLFLAGS = --tag=disable-static | ||
61 | tests_eolian_js_libeolian_js_suite_la_LDFLAGS = -rpath $(abs_top_builddir)/tests/eolian_js @EFL_LTLIBRARY_FLAGS@ | ||
62 | |||
63 | # if compiler_o_lo == yes, lo, otherwise $(OBJEXT) | ||
64 | |||
65 | tests/eolian_js/tests_eolian_js_libeolian_js_suite_la-eolian_js_test_eolian_js_binding.l$(OBJEXT): tests/eolian_js/constructor_method_class.eo.js.cc tests/eolian_js/constructor_method_class.eo.h tests/eolian_js/test_object.eo.js.cc tests/eolian_js/test_object.eo.h | ||
66 | tests/eolian_js/tests_eolian_js_libeolian_js_suite_la-eolian_js_test_constructor_method_impl.l$(OBJEXT): tests/eolian_js/constructor_method_class.eo.c | ||
67 | tests/eolian_js/tests_eolian_js_libeolian_js_suite_la-eolian_js_test_test_object_impl.l$(OBJEXT): tests/eolian_js/test_object.eo.c | ||
68 | |||
69 | CLEANFILES += \ | ||
70 | tests/eolian_js/constructor_method_class.eo.js.cc \ | ||
71 | tests/eolian_js/constructor_method_class.eo.c \ | ||
72 | tests/eolian_js/constructor_method_class.eo.h \ | ||
73 | tests/eolian_js/test_object.eo.js.cc \ | ||
74 | tests/eolian_js/test_object.eo.c \ | ||
75 | tests/eolian_js/test_object.eo.h | ||
76 | else | ||
77 | check_PROGRAMS += tests/eolian_js/eolian_js_suite | ||
78 | TESTS += tests/eolian_js/eolian_js_suite | ||
79 | |||
80 | tests_eolian_js_eolian_js_suite_SOURCES = \ | ||
81 | tests/eolian_js/eolian_js_suite.cc \ | ||
82 | tests/eolian_js/eolian_js_test_eolian_js_binding.cc \ | ||
83 | tests/eolian_js/eolian_js_test_constructor_method_impl.c \ | ||
84 | tests/eolian_js/eolian_js_test_test_object_impl.c | ||
85 | |||
86 | tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_eolian_js_binding.$(OBJEXT): tests/eolian_js/constructor_method_class.eo.js.cc tests/eolian_js/constructor_method_class.eo.h tests/eolian_js/test_object.eo.js.cc tests/eolian_js/test_object.eo.h | ||
87 | tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_constructor_method_impl.$(OBJEXT): tests/eolian_js/constructor_method_class.eo.c | ||
88 | tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_test_object_impl.$(OBJEXT): tests/eolian_js/test_object.eo.c | ||
89 | |||
90 | CLEANFILES += \ | ||
91 | tests/eolian_js/constructor_method_class.eo.js.cc \ | ||
92 | tests/eolian_js/constructor_method_class.eo.c \ | ||
93 | tests/eolian_js/constructor_method_class.eo.h \ | ||
94 | tests/eolian_js/test_object.eo.js.cc \ | ||
95 | tests/eolian_js/test_object.eo.c \ | ||
96 | tests/eolian_js/test_object.eo.h | ||
97 | |||
98 | tests_eolian_js_eolian_js_suite_CPPFLAGS = \ | ||
99 | -I$(top_builddir)/src/lib/efl \ | ||
100 | -I$(top_srcdir)/src/bin/eolian_js \ | ||
101 | -I$(top_srcdir)/src/bindings/js/eina_js \ | ||
102 | -I$(top_srcdir)/src/bindings/js/eo_js \ | ||
103 | -I$(top_builddir)/src/tests/eolian_js \ | ||
104 | -I$(top_srcdir)/src/tests/efl_js \ | ||
105 | -DTESTS_WD=\"`pwd`\" \ | ||
106 | -DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_js\" \ | ||
107 | -DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_js\" \ | ||
108 | -DPACKAGE_DATA_DIR=\"$(datadir)/eolian_js\" \ | ||
109 | -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_js\" \ | ||
110 | @CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ @EFL_JS_CFLAGS@ \ | ||
111 | @EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \ | ||
112 | @EO_JS_CFLAGS@ @EO_CXX_CFLAGS@ @EFL_JS_CFLAGS@ | ||
113 | |||
114 | tests_eolian_js_eolian_js_suite_LDADD = \ | ||
115 | @CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ @USE_EVAS_LIBS@ @USE_EFL_JS_LIBS@ | ||
116 | tests_eolian_js_eolian_js_suite_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ @USE_EVAS_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@ | ||
117 | endif | ||
118 | endif | ||
119 | |||
120 | endif | ||
121 | |||
122 | |||
123 | |||
diff --git a/src/Makefile_Eolian_Js_Helper.am b/src/Makefile_Eolian_Js_Helper.am new file mode 100644 index 0000000000..fcc523153f --- /dev/null +++ b/src/Makefile_Eolian_Js_Helper.am | |||
@@ -0,0 +1,18 @@ | |||
1 | #if HAVE_EOLIAN_JS | ||
2 | #EOLIAN_JS = @eolian_js@ | ||
3 | #_EOLIAN_JS_DEP = @eolian_js@ | ||
4 | #else | ||
5 | EOLIAN_JS = EFL_RUN_IN_TREE=1 $(top_builddir)/src/bin/eolian_js/eolian_js${EXEEXT} | ||
6 | _EOLIAN_JS_DEP = bin/eolian_js/eolian_js${EXEEXT} | ||
7 | #endif | ||
8 | |||
9 | AM_V_EOLJS = $(am__v_EOLJS_@AM_V@) | ||
10 | am__v_EOLJS_ = $(am__v_EOLJS_@AM_DEFAULT_V@) | ||
11 | am__v_EOLJS_0 = @echo " EOLJS " $@; | ||
12 | |||
13 | SUFFIXES += .eo.js.cc | ||
14 | |||
15 | %.eo.js.cc: %.eo $(_EOLIAN_JS_DEP) | ||
16 | $(AM_V_EOLJS)$(EOLIAN_JS) $(EOLIAN_FLAGS) -o $@ $< | ||
17 | |||
18 | CLEANFILES += $(BUILT_SOURCES) | ||
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 3f7dd3941b..ebc5480151 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am | |||
@@ -2221,3 +2221,13 @@ $(NULL) | |||
2221 | 2221 | ||
2222 | installed_evasfiltersdir = $(datadir)/evas/filters/lua | 2222 | installed_evasfiltersdir = $(datadir)/evas/filters/lua |
2223 | dist_installed_evasfilters_DATA = $(evas_filters_lua) | 2223 | dist_installed_evasfilters_DATA = $(evas_filters_lua) |
2224 | |||
2225 | if HAVE_JS | ||
2226 | |||
2227 | generated_evas_js_bindings = $(evas_eolian_files:%.eo=%.eo.js.cc) | ||
2228 | |||
2229 | CLEANFILES += $(generated_evas_js_bindings) | ||
2230 | |||
2231 | GENERATED_JS_BINDINGS += $(generated_evas_js_bindings) | ||
2232 | |||
2233 | endif | ||
diff --git a/src/bin/efl_js/efljslaunch b/src/bin/efl_js/efljslaunch new file mode 100755 index 0000000000..785c30e3e3 --- /dev/null +++ b/src/bin/efl_js/efljslaunch | |||
@@ -0,0 +1,139 @@ | |||
1 | #!/bin/sh | ||
2 | ':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@" | ||
3 | |||
4 | // Core node modules | ||
5 | var path = require('path'); | ||
6 | var os = require('os'); | ||
7 | var zlib = require('zlib'); | ||
8 | var child_process = require('child_process'); | ||
9 | |||
10 | // 3rd party modules | ||
11 | var fs = require('fs-extra'); | ||
12 | var getopt = require('node-getopt'); | ||
13 | var tar = require('tar'); | ||
14 | |||
15 | function make_error_cb(message) | ||
16 | { | ||
17 | return function(e) { | ||
18 | console.error("Error %s: %s", message, e); | ||
19 | process.exit(1); | ||
20 | }; | ||
21 | } | ||
22 | |||
23 | function remove_files(options) | ||
24 | { | ||
25 | if (options.verbose) | ||
26 | console.log("Removing temporary files"); | ||
27 | |||
28 | fs.remove(options.project_folder); | ||
29 | } | ||
30 | |||
31 | function run_project(options) | ||
32 | { | ||
33 | if (options.verbose) | ||
34 | console.log("Running the project"); | ||
35 | |||
36 | var current_dir = process.cwd(); | ||
37 | process.chdir(options.project_root); | ||
38 | |||
39 | var proc = child_process.fork(options.metadata.Entry); | ||
40 | proc.on('exit', function(code){ | ||
41 | if (options.verbose) | ||
42 | console.log('Child exited with code %s', code); | ||
43 | process.chdir(current_dir); | ||
44 | if (!options.keep) | ||
45 | remove_files(options); | ||
46 | }); | ||
47 | |||
48 | } | ||
49 | |||
50 | function unpack_project_data(options) | ||
51 | { | ||
52 | if (options.verbose) | ||
53 | console.log("Unpacking project sources and assets"); | ||
54 | |||
55 | var datafile = path.join(options.project_folder, "data.tar.gz"); | ||
56 | var project_root = path.join(options.project_folder, "root"); | ||
57 | |||
58 | options.project_root = project_root; | ||
59 | |||
60 | var input = fs.createReadStream(datafile); | ||
61 | var unzipper = zlib.createGunzip(); | ||
62 | var extractor = tar.Extract({path: project_root, strip: 0}); | ||
63 | |||
64 | input.on('error', make_error_cb("reading package data file.")); | ||
65 | extractor.on('error', make_error_cb("unpacking package data file.")); | ||
66 | if (!("only-extract" in options)) | ||
67 | extractor.on('end', function(){ run_project(options); }); | ||
68 | |||
69 | input.pipe(unzipper) | ||
70 | unzipper.pipe(extractor); | ||
71 | } | ||
72 | |||
73 | function read_metadata(options) | ||
74 | { | ||
75 | if (options.verbose) | ||
76 | console.log("Reading project metadata"); | ||
77 | |||
78 | var project_folder = options.project_folder; | ||
79 | var metadata = JSON.parse(fs.readFileSync(path.join(project_folder, "meta.json"))); | ||
80 | |||
81 | if (options.verbose) | ||
82 | console.log("Project: %s\nVersion: %s\nEntry point: %s", metadata.Name, metadata.Version, metadata.Entry); | ||
83 | if ("only-dump" in options) | ||
84 | process.exit(0); | ||
85 | |||
86 | options.metadata = metadata; | ||
87 | |||
88 | unpack_project_data(options); | ||
89 | } | ||
90 | |||
91 | function extract(filename, options) | ||
92 | { | ||
93 | if (options.verbose) | ||
94 | console.log("Extracting ", filename, "with options ", options); | ||
95 | |||
96 | var project_id = path.basename(filename, ".epk"); | ||
97 | var project_folder = path.join(options['temp-dir'], project_id); | ||
98 | |||
99 | options.project_folder = project_folder; | ||
100 | options.project_id = project_id; | ||
101 | |||
102 | var input = fs.createReadStream(filename); | ||
103 | var extractor = tar.Extract({path: options['temp-dir'], strip: 0}); | ||
104 | |||
105 | input.on('error', make_error_cb("reading package file.")); | ||
106 | extractor.on('error', make_error_cb("unpacking package file.")); | ||
107 | extractor.on('end', function(){ read_metadata(options); }); | ||
108 | |||
109 | input.pipe(extractor); | ||
110 | } | ||
111 | |||
112 | function main() { | ||
113 | var options = getopt.create([ | ||
114 | ['d', 'only-dump', 'Only dump information about the package'], | ||
115 | ['e', 'only-extract', 'Only extract the package, do not run'], | ||
116 | ['h', 'help', 'Display this help'], | ||
117 | ['k', 'keep', 'Do not remove the files after exiting'], | ||
118 | ['t', 'temp-dir=ARG', 'Temporary dir to extract files'], | ||
119 | ['v', 'verbose', 'Print information messages'], | ||
120 | ]).bindHelp().parseSystem(); | ||
121 | |||
122 | var filename = options.argv[0]; | ||
123 | if (filename === undefined) | ||
124 | { | ||
125 | console.error("Must provide a package file."); | ||
126 | process.exit(1); | ||
127 | } | ||
128 | |||
129 | if (!('temp-dir' in options.options)) | ||
130 | { | ||
131 | options.options["temp-dir"] = path.join(os.tmpdir(), "efljs_apps"); | ||
132 | if (options.verbose) | ||
133 | console.log("Defaulting temp dir to ", options.options["temp-dir"]); | ||
134 | } | ||
135 | |||
136 | extract(filename, options.options); | ||
137 | } | ||
138 | |||
139 | main(); | ||
diff --git a/src/bin/efl_js/efljslaunch.desktop b/src/bin/efl_js/efljslaunch.desktop new file mode 100644 index 0000000000..53371cba97 --- /dev/null +++ b/src/bin/efl_js/efljslaunch.desktop | |||
@@ -0,0 +1,7 @@ | |||
1 | [Desktop Entry] | ||
2 | Name=EFL JS package launcher | ||
3 | Exec=efljslaunch %f | ||
4 | Type=Application | ||
5 | Categories=EFL | ||
6 | Terminal=true | ||
7 | MimeType=application/x-efljspackage; | ||
diff --git a/src/bin/efl_js/efljslaunch.xml b/src/bin/efl_js/efljslaunch.xml new file mode 100644 index 0000000000..b1db6841b2 --- /dev/null +++ b/src/bin/efl_js/efljslaunch.xml | |||
@@ -0,0 +1,7 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> | ||
3 | <mime-type type="application/x-efljspackage"> | ||
4 | <comment xml:lang="en">EFL JS package</comment> | ||
5 | <glob pattern="*.epk"/> | ||
6 | </mime-type> | ||
7 | </mime-info> \ No newline at end of file | ||
diff --git a/src/bin/efl_js/efljspack b/src/bin/efl_js/efljspack new file mode 100755 index 0000000000..50e27b6ac4 --- /dev/null +++ b/src/bin/efl_js/efljspack | |||
@@ -0,0 +1,251 @@ | |||
1 | #!/bin/sh | ||
2 | ':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@" | ||
3 | |||
4 | var zlib = require('zlib'); | ||
5 | var path = require('path'); | ||
6 | |||
7 | // external dependencies | ||
8 | var fs = require('fs-extra'); | ||
9 | var tar = require('tar'); | ||
10 | var fstream = require('fstream'); | ||
11 | var getopt = require('node-getopt'); | ||
12 | |||
13 | /* | ||
14 | * Packing a project. | ||
15 | * The efljs package has a similar format to debian packages. It is a | ||
16 | * tar package containing two files: | ||
17 | * | ||
18 | * meta.txt: Metadata information about this package. | ||
19 | * data.tar.gz: Gzipped data, with the project tree ready to be decompressed | ||
20 | * and run by the package launcher. | ||
21 | * | ||
22 | * During the build, a out/ directory is created in the project root to | ||
23 | * store the package and temporary files. | ||
24 | */ | ||
25 | |||
26 | // Creates a stub .project file and packs it. | ||
27 | function pack_single(sourcepath, options) | ||
28 | { | ||
29 | if (options.verbose) | ||
30 | console.log("Creating project file for single file app", sourcepath); | ||
31 | |||
32 | var dir_name = path.dirname(fs.realpathSync(sourcepath)); | ||
33 | var filename = path.basename(sourcepath); | ||
34 | var projectRegex = /^(.*).js$/g; | ||
35 | var project_name = projectRegex.exec(filename)[1]; | ||
36 | |||
37 | if (!validade_project_name(project_name)) | ||
38 | { | ||
39 | console.error("Invalid project name. Must start with a letter."); | ||
40 | process.exit(0); | ||
41 | } | ||
42 | |||
43 | var project_filename = path.join(dir_name, project_name + ".project"); | ||
44 | |||
45 | var fd = fs.openSync(project_filename, 'w'); | ||
46 | |||
47 | var jsonData = {}; | ||
48 | |||
49 | jsonData["Name"] = project_name; | ||
50 | jsonData["Entry"] = filename; | ||
51 | jsonData["Sources"] = [[filename, '.']]; | ||
52 | jsonData["Version"] = "0.1"; | ||
53 | |||
54 | fs.writeSync(fd, JSON.stringify(jsonData, null, 2)); | ||
55 | |||
56 | fs.closeSync(fd); | ||
57 | |||
58 | pack_project(project_filename, options); | ||
59 | |||
60 | } | ||
61 | |||
62 | function generate_build_info(configuration, project_file, options) | ||
63 | { | ||
64 | build_info = {}; | ||
65 | |||
66 | // project == project_dir | ||
67 | // /out == build_dir | ||
68 | // /data == data_dir | ||
69 | // /name-version == package_dir | ||
70 | |||
71 | build_info.package_id = configuration.Name + "-" + configuration.Version; | ||
72 | build_info.project_dir = path.dirname(project_file); | ||
73 | build_info.build_dir = path.join(build_info.project_dir, "out"); | ||
74 | build_info.data_dir = path.join(build_info.build_dir, "data"); | ||
75 | build_info.package_dir = path.join(build_info.build_dir, build_info.package_id); | ||
76 | build_info.data_file = path.join(build_info.package_dir, "data.tar.gz"); | ||
77 | build_info.package_file = path.join(build_info.build_dir, build_info.package_id + ".epk") | ||
78 | build_info.metadata_file = path.join(build_info.package_dir, "meta.json"); | ||
79 | |||
80 | if (options.verbose) | ||
81 | { | ||
82 | console.log("Project id: ", build_info.package_id); | ||
83 | console.log("Project source dir: ", build_info.project_dir); | ||
84 | console.log("Project build dir: ", build_info.build_dir); | ||
85 | console.log("Project data dir:", build_info.data_dir); | ||
86 | console.log("Project package dir:", build_info.package_dir); | ||
87 | } | ||
88 | |||
89 | return build_info; | ||
90 | |||
91 | } | ||
92 | |||
93 | // Project names must start with a letter and contain only | ||
94 | // letters, digits and underscores. | ||
95 | function validade_project_name(name) | ||
96 | { | ||
97 | return (/^[a-zA-Z][\w-]*$/).test(name) | ||
98 | } | ||
99 | |||
100 | function pack_project(project_file, options) | ||
101 | { | ||
102 | if (options.verbose) | ||
103 | console.log("Packing project from project file ", project_file); | ||
104 | |||
105 | var configuration = JSON.parse(fs.readFileSync(project_file)); | ||
106 | |||
107 | if (!validade_project_name(configuration.Name)) | ||
108 | { | ||
109 | console.error("Invalid project name. Must start with a letter."); | ||
110 | process.exit(0); | ||
111 | } | ||
112 | |||
113 | var build_info = generate_build_info(configuration, project_file, options); | ||
114 | |||
115 | try | ||
116 | { | ||
117 | fs.mkdirSync(build_info.build_dir); | ||
118 | fs.mkdirSync(build_info.data_dir); | ||
119 | fs.mkdirSync(build_info.package_dir); | ||
120 | } | ||
121 | catch (e) | ||
122 | { | ||
123 | console.warn("Warning: Project output directories not empty."); | ||
124 | } | ||
125 | |||
126 | create_metadata_file(configuration, build_info, options); | ||
127 | |||
128 | // If not explicitly named on configuration, add the entire directory | ||
129 | if (!('Sources' in configuration)) | ||
130 | { | ||
131 | generate_source_list(configuration, build_info.project_dir, options); | ||
132 | } | ||
133 | |||
134 | create_project_tree(configuration.Sources, build_info, options); | ||
135 | |||
136 | pack_data_dir(build_info, options); | ||
137 | } | ||
138 | |||
139 | function create_project_tree(sources, build_info, options) | ||
140 | { | ||
141 | for (var i = sources.length - 1; i >= 0; i--) { | ||
142 | if (options.verbose) | ||
143 | console.log("Adding file ", sources[i], "to package."); | ||
144 | var source_file = path.join(build_info.project_dir, sources[i][0]); | ||
145 | var destination_dir = path.join(build_info.data_dir, sources[i][1]); | ||
146 | var destination_filename = path.basename(source_file); | ||
147 | var destination_file = path.join(destination_dir, destination_filename); | ||
148 | |||
149 | fs.copySync(source_file, destination_file); | ||
150 | }; | ||
151 | } | ||
152 | |||
153 | function generate_source_list(configuration, project_dir, options) | ||
154 | { | ||
155 | console.log("Generating source list for project dir", build_info.project_dir); | ||
156 | var dir_entries = fs.readdirSync(project_dir); | ||
157 | var sources = []; | ||
158 | |||
159 | dir_entries.forEach(function(entry){ | ||
160 | if (entry == "out") | ||
161 | return; | ||
162 | sources.push([entry, "."]); | ||
163 | }); | ||
164 | configuration.Sources = sources; | ||
165 | } | ||
166 | |||
167 | function create_metadata_file(configuration, build_info, options) | ||
168 | { | ||
169 | if (options.verbose) | ||
170 | console.log("Creating metadata file", build_info.metadata_file); | ||
171 | |||
172 | var metadata = {}; | ||
173 | |||
174 | metadata.Name = configuration.Name; | ||
175 | metadata.Entry = configuration.Entry; | ||
176 | metadata.Version = configuration.Version; | ||
177 | |||
178 | var output = fs.createWriteStream(build_info.metadata_file); | ||
179 | output.write(JSON.stringify(metadata, null, 2)); | ||
180 | output.close(); | ||
181 | } | ||
182 | |||
183 | function pack_data_dir(build_info, options) | ||
184 | { | ||
185 | if (options.verbose) | ||
186 | console.log("Packing data..."); | ||
187 | |||
188 | pack_directory(build_info.data_dir, build_info.data_file, true, true, function(){ | ||
189 | if (options.verbose) | ||
190 | console.log("Packed data"); | ||
191 | pack_final_package(build_info, options); | ||
192 | }); | ||
193 | } | ||
194 | |||
195 | function pack_final_package(build_info, options) | ||
196 | { | ||
197 | if (options.verbose) | ||
198 | console.log("Creating package ", build_info.package_file); | ||
199 | pack_directory(build_info.package_dir, build_info.package_file, false, false, function(){ | ||
200 | if (options.verbose) | ||
201 | console.log("Created project package."); | ||
202 | }); | ||
203 | } | ||
204 | |||
205 | function pack_directory(source_dir, target_file, strip_base_dir, should_gzip, callback) | ||
206 | { | ||
207 | var output = fs.createWriteStream(target_file); | ||
208 | var packer = tar.Pack({fromBase: strip_base_dir == true}); | ||
209 | if (callback != undefined) | ||
210 | output.on('close', callback); | ||
211 | |||
212 | var reader = fstream.Reader({path: source_dir, type: "Directory"}); | ||
213 | var destStr = reader.pipe(packer); | ||
214 | if(should_gzip) | ||
215 | destStr = destStr.pipe(zlib.createGzip()); | ||
216 | destStr.pipe(output); | ||
217 | } | ||
218 | |||
219 | function main() | ||
220 | { | ||
221 | |||
222 | var options = getopt.create([ | ||
223 | ['v', 'verbose', 'Explain what is being done'], | ||
224 | ['h', 'help', 'Display this help'] | ||
225 | ]).bindHelp().parseSystem(); | ||
226 | |||
227 | filename = options.argv[0]; | ||
228 | |||
229 | if (typeof filename === 'undefined') | ||
230 | { | ||
231 | console.error('Must provide a valid js or project file.'); | ||
232 | process.exit(1); | ||
233 | } | ||
234 | |||
235 | if (endsWith(filename, ".js")) | ||
236 | { | ||
237 | pack_single(filename, options.options); | ||
238 | } | ||
239 | else if (endsWith(filename, ".project")) | ||
240 | { | ||
241 | pack_project(filename, options.options); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | main(); | ||
246 | |||
247 | //// Helper functions | ||
248 | function endsWith(str, suffix) | ||
249 | { | ||
250 | return str.indexOf(suffix, str.length - suffix.length) !== -1; | ||
251 | } | ||
diff --git a/src/bin/efl_js/launcher_main.cc b/src/bin/efl_js/launcher_main.cc new file mode 100644 index 0000000000..680f16ca52 --- /dev/null +++ b/src/bin/efl_js/launcher_main.cc | |||
@@ -0,0 +1,156 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | #include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <iostream> | ||
6 | #include <fstream> | ||
7 | #include <sstream> | ||
8 | #include <string> | ||
9 | #include <cerrno> | ||
10 | |||
11 | #include <Eo_Js.hh> | ||
12 | #include <Eina.hh> | ||
13 | #include <Eo.hh> | ||
14 | // #include <efl_js.hh> | ||
15 | |||
16 | using namespace std; | ||
17 | using namespace v8; | ||
18 | |||
19 | const char PATH_SEPARATOR = | ||
20 | #ifdef _WIN32 | ||
21 | '\\'; | ||
22 | #else | ||
23 | '/'; | ||
24 | #endif | ||
25 | |||
26 | static std::string get_file_contents(const char *filename) { | ||
27 | std::ifstream in(filename, std::ios::in); | ||
28 | if (in) { | ||
29 | std::ostringstream contents; | ||
30 | contents << in.rdbuf(); | ||
31 | in.close(); | ||
32 | return contents.str(); | ||
33 | } else { | ||
34 | throw(errno); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | static std::string get_filename(std::string path) | ||
39 | { | ||
40 | int beginIdx = path.rfind(PATH_SEPARATOR); | ||
41 | return path.substr(beginIdx + 1); | ||
42 | } | ||
43 | |||
44 | static void show_usage(std::string name) | ||
45 | { | ||
46 | std::cerr << "Usage: " << get_filename(name) << " <option(s)> [SOURCE]\n" << std::endl | ||
47 | << "Options:" << std::endl | ||
48 | << "\t-h, --help\t\t Show this help message" << std::endl; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Basic console.log implementation with space-separated values, | ||
53 | * no substitution | ||
54 | */ | ||
55 | void Log(const FunctionCallbackInfo<Value>& args) | ||
56 | { | ||
57 | Isolate* isolate = Isolate::GetCurrent(); | ||
58 | HandleScope scope(isolate); | ||
59 | |||
60 | for (int i=0; i < args.Length(); i++) | ||
61 | { | ||
62 | if (i != 0) | ||
63 | std::cout << " "; | ||
64 | String::Utf8Value string(args[i]); | ||
65 | std::cout << *string; | ||
66 | } | ||
67 | |||
68 | std::cout << std::endl; | ||
69 | |||
70 | args.GetReturnValue().Set(v8::Null(isolate)); | ||
71 | } | ||
72 | |||
73 | |||
74 | int main(int argc, char* argv[]) | ||
75 | { | ||
76 | |||
77 | std::string script_source; | ||
78 | char *filename = 0; | ||
79 | |||
80 | for (int i=1; i < argc; i++) | ||
81 | { | ||
82 | if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) | ||
83 | { | ||
84 | show_usage(argv[0]); | ||
85 | return 0; | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | filename = argv[i]; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | if (!filename) | ||
94 | { | ||
95 | std::cerr << "Error: No source provided." << std::endl; | ||
96 | show_usage(argv[0]); | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | try | ||
101 | { | ||
102 | script_source = get_file_contents(filename); | ||
103 | } catch (int errno) | ||
104 | { | ||
105 | perror("Error: "); | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | |||
110 | efl::eina::js::compatibility_initialize(); | ||
111 | v8::V8::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), true); | ||
112 | |||
113 | v8::Isolate* isolate = efl::eina::js::compatibility_isolate_new(); | ||
114 | { | ||
115 | Isolate::Scope isolate_scope(isolate); | ||
116 | HandleScope handleScope(isolate); | ||
117 | |||
118 | Local<Context> context = Context::New(isolate, NULL); | ||
119 | Context::Scope context_scope(context); | ||
120 | context->Enter(); | ||
121 | |||
122 | // Setup the console and log | ||
123 | Local<Object> console = Object::New(isolate); | ||
124 | Local<FunctionTemplate> log = FunctionTemplate::New(isolate, Log); | ||
125 | console->Set(String::NewFromUtf8(isolate, "log"), log->GetFunction()); | ||
126 | |||
127 | Local<Object> global = context->Global(); | ||
128 | global->Set(String::NewFromUtf8(isolate, "console"), console); | ||
129 | |||
130 | // Set up the efl exports; Needed to enter the context before this | ||
131 | // due to creating Objects instead of Objects Templates | ||
132 | // WIP: Commented out due to potential missing v8 platform implementation issues | ||
133 | // Local<Object> efl_exports = Object::New(isolate); | ||
134 | // global->Set(String::NewFromUtf8(isolate, "efl"), efl_exports); | ||
135 | // efl_js::init(efl_exports); | ||
136 | |||
137 | // And now the user's script | ||
138 | Local<String> source = String::NewFromUtf8(isolate, script_source.c_str()); | ||
139 | |||
140 | Local<Script> script = Script::Compile(source); | ||
141 | |||
142 | TryCatch tryCatch(isolate); | ||
143 | Local<Value> result = script->Run(); | ||
144 | |||
145 | if (result.IsEmpty()) | ||
146 | { | ||
147 | Local<Value> exception = tryCatch.Exception(); | ||
148 | String::Utf8Value exception_str(exception); | ||
149 | printf("Exception: %s\n", *exception_str); | ||
150 | } | ||
151 | |||
152 | } | ||
153 | |||
154 | V8::Dispose(); | ||
155 | return 0; | ||
156 | } | ||
diff --git a/src/bin/eolian_js/.gitignore b/src/bin/eolian_js/.gitignore new file mode 100644 index 0000000000..631f68aa1f --- /dev/null +++ b/src/bin/eolian_js/.gitignore | |||
@@ -0,0 +1 @@ | |||
/eolian_js | |||
diff --git a/src/bin/eolian_js/eolian/class.hh b/src/bin/eolian_js/eolian/class.hh new file mode 100644 index 0000000000..bd04d5fedd --- /dev/null +++ b/src/bin/eolian_js/eolian/class.hh | |||
@@ -0,0 +1,139 @@ | |||
1 | #ifndef EOLIAN_KLASS_HH | ||
2 | #define EOLIAN_KLASS_HH | ||
3 | |||
4 | #include <Eina.hh> | ||
5 | |||
6 | #include <eolian/js/domain.hh> | ||
7 | |||
8 | #include <ostream> | ||
9 | |||
10 | inline std::string name(Eolian_Class const* klass) | ||
11 | { | ||
12 | return ::eolian_class_name_get(klass); | ||
13 | } | ||
14 | |||
15 | inline std::string full_name(Eolian_Class const* klass) | ||
16 | { | ||
17 | return ::eolian_class_full_name_get(klass); | ||
18 | } | ||
19 | |||
20 | inline std::string full_name_transformed(Eolian_Class const* klass) | ||
21 | { | ||
22 | auto r = full_name(klass); | ||
23 | std::replace(r.begin(), r.end(), '.', '_'); | ||
24 | return r; | ||
25 | } | ||
26 | |||
27 | inline std::size_t namespace_size(Eolian_Class const* klass) | ||
28 | { | ||
29 | std::size_t size = 0; | ||
30 | for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass)) | ||
31 | , last; first != last; ++first) | ||
32 | ++size; | ||
33 | return size; | ||
34 | } | ||
35 | |||
36 | inline std::string type_class_name(Eolian_Type const* tp) | ||
37 | { | ||
38 | if (tp) | ||
39 | { | ||
40 | Eolian_Type_Type tpt = ::eolian_type_type_get(tp); | ||
41 | if (tpt == EOLIAN_TYPE_POINTER || tpt == EOLIAN_TYPE_ALIAS || tpt == EOLIAN_TYPE_REGULAR) | ||
42 | { | ||
43 | return type_class_name(::eolian_type_base_type_get(tp)); | ||
44 | } | ||
45 | else if(tpt == EOLIAN_TYPE_CLASS) | ||
46 | { | ||
47 | Eolian_Class const* klass = ::eolian_type_class_get(tp); | ||
48 | if (klass) | ||
49 | { | ||
50 | Eina_Stringshare* klass_name = ::eolian_class_full_name_get(klass); | ||
51 | if (!klass_name) | ||
52 | throw std::runtime_error("Could not get Eo class name"); | ||
53 | |||
54 | return klass_name; | ||
55 | } // TODO: else should throw std::runtime_error("Could not get Eo class"); | ||
56 | } | ||
57 | else if(tpt == EOLIAN_TYPE_STRUCT) | ||
58 | { | ||
59 | auto struct_type_full_name = ::eolian_type_full_name_get(tp); | ||
60 | if (!struct_type_full_name) | ||
61 | throw std::runtime_error("Could not get struct name"); | ||
62 | return struct_type_full_name; | ||
63 | } | ||
64 | } | ||
65 | return ""; | ||
66 | } | ||
67 | |||
68 | inline void print_lower_case_namespace(Eolian_Class const* klass, std::ostream& os) | ||
69 | { | ||
70 | std::vector<std::string> namespace_; | ||
71 | for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass)) | ||
72 | , last; first != last; ++first) | ||
73 | namespace_.push_back(&*first); | ||
74 | for(auto first = namespace_.begin(), last = namespace_.end() | ||
75 | ; first != last; ++first) | ||
76 | { | ||
77 | std::string lower(*first); | ||
78 | std::transform(lower.begin(), lower.end(), lower.begin(), tolower); | ||
79 | os << lower; | ||
80 | if(std::next(first) != last) os << "::"; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | inline void print_eo_class(Eolian_Class const* klass, std::ostream& os) | ||
85 | { | ||
86 | assert(klass != 0); | ||
87 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print_eo_class"; | ||
88 | |||
89 | auto toupper = [] (unsigned char c) { return std::toupper(c); }; | ||
90 | |||
91 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print_eo_class"; | ||
92 | std::vector<std::string> namespace_; | ||
93 | for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass)) | ||
94 | , last; first != last; ++first) | ||
95 | namespace_.push_back(&*first); | ||
96 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "namespace"; | ||
97 | namespace_.push_back(name(klass)); | ||
98 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "class"; | ||
99 | switch(eolian_class_type_get(klass)) | ||
100 | { | ||
101 | case EOLIAN_CLASS_REGULAR: | ||
102 | case EOLIAN_CLASS_ABSTRACT: | ||
103 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ""; | ||
104 | namespace_.push_back("CLASS"); | ||
105 | break; | ||
106 | case EOLIAN_CLASS_INTERFACE: | ||
107 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ""; | ||
108 | namespace_.push_back("INTERFACE"); | ||
109 | break; | ||
110 | case EOLIAN_CLASS_MIXIN: | ||
111 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ""; | ||
112 | namespace_.push_back("MIXIN"); | ||
113 | break; | ||
114 | default: | ||
115 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "default ?"; | ||
116 | std::abort(); | ||
117 | } | ||
118 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ""; | ||
119 | for(auto first = namespace_.begin(), last = namespace_.end() | ||
120 | ; first != last; ++first) | ||
121 | { | ||
122 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ""; | ||
123 | std::string upper(*first); | ||
124 | std::transform(upper.begin(), upper.end(), upper.begin(), toupper); | ||
125 | os << upper; | ||
126 | if(std::next(first) != last) os << "_"; | ||
127 | } | ||
128 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ""; | ||
129 | } | ||
130 | |||
131 | inline bool is_evas(Eolian_Class const* klass) | ||
132 | { | ||
133 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is_evas"; | ||
134 | efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass)); | ||
135 | return first != efl::eina::iterator<const char>() | ||
136 | && std::strcmp(&*first, "Evas") == 0; | ||
137 | } | ||
138 | |||
139 | #endif | ||
diff --git a/src/bin/eolian_js/eolian/js/domain.hh b/src/bin/eolian_js/eolian/js/domain.hh new file mode 100644 index 0000000000..38cf542873 --- /dev/null +++ b/src/bin/eolian_js/eolian/js/domain.hh | |||
@@ -0,0 +1,8 @@ | |||
1 | |||
2 | #include <Eina.hh> | ||
3 | |||
4 | namespace eolian { namespace js { | ||
5 | |||
6 | extern efl::eina::log_domain domain; | ||
7 | |||
8 | } } | ||
diff --git a/src/bin/eolian_js/eolian/js/format.hh b/src/bin/eolian_js/eolian/js/format.hh new file mode 100644 index 0000000000..a07d541e14 --- /dev/null +++ b/src/bin/eolian_js/eolian/js/format.hh | |||
@@ -0,0 +1,44 @@ | |||
1 | #ifndef EOLIAN_JS_FORMAT_HH | ||
2 | #define EOLIAN_JS_FORMAT_HH | ||
3 | |||
4 | #include <eolian/js/domain.hh> | ||
5 | |||
6 | #include <algorithm> | ||
7 | #include <string> | ||
8 | #include <cctype> | ||
9 | |||
10 | namespace eolian { namespace js { | ||
11 | |||
12 | namespace format { | ||
13 | |||
14 | std::string generic(std::string const& in) | ||
15 | { | ||
16 | std::string s = in; | ||
17 | auto i = s.find('_'); | ||
18 | while (i != std::string::npos) | ||
19 | { | ||
20 | if (i <= 0 || i+1 >= s.size() || | ||
21 | !::isalnum(s[i-1]) || !::isalnum(s[i+1])) | ||
22 | { | ||
23 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Entity '" << in | ||
24 | << "' can't be conveniently converted to a JavaScript name."; | ||
25 | return in; | ||
26 | } | ||
27 | s[i+1] = static_cast<char>(::toupper(s[i+1])); | ||
28 | s.erase(i, 1); | ||
29 | i = s.find('_', i); | ||
30 | } | ||
31 | return s; | ||
32 | } | ||
33 | |||
34 | std::string constant(std::string in) | ||
35 | { | ||
36 | std::transform(in.begin(), in.end(), in.begin(), ::toupper); | ||
37 | return in; | ||
38 | } | ||
39 | |||
40 | } | ||
41 | |||
42 | } } | ||
43 | |||
44 | #endif | ||
diff --git a/src/bin/eolian_js/main.cc b/src/bin/eolian_js/main.cc new file mode 100644 index 0000000000..bc575fdf8e --- /dev/null +++ b/src/bin/eolian_js/main.cc | |||
@@ -0,0 +1,1090 @@ | |||
1 | |||
2 | #ifdef HAVE_CONFIG_H | ||
3 | # include <config.h> | ||
4 | #endif | ||
5 | |||
6 | #include <Eolian.h> | ||
7 | #include <Eina.hh> | ||
8 | |||
9 | #include <eolian/js/domain.hh> | ||
10 | #include <eolian/js/format.hh> | ||
11 | #include <eolian/class.hh> | ||
12 | |||
13 | #include <iostream> | ||
14 | #include <fstream> | ||
15 | #include <unordered_map> | ||
16 | #include <sstream> | ||
17 | #include <stdexcept> | ||
18 | |||
19 | #include <libgen.h> | ||
20 | #include <getopt.h> | ||
21 | #include <cstdlib> | ||
22 | #include <vector> | ||
23 | #include <set> | ||
24 | |||
25 | namespace eolian { namespace js { | ||
26 | |||
27 | efl::eina::log_domain domain("eolian_js"); | ||
28 | |||
29 | struct incomplete_complex_type_error : public std::exception | ||
30 | { | ||
31 | explicit incomplete_complex_type_error(std::string const& msg_arg) | ||
32 | : msg(msg_arg) | ||
33 | {} | ||
34 | virtual ~incomplete_complex_type_error() {} | ||
35 | virtual const char* what() const noexcept { return msg.c_str(); } | ||
36 | |||
37 | std::string msg; | ||
38 | }; | ||
39 | |||
40 | } } | ||
41 | |||
42 | |||
43 | std::string | ||
44 | _lowercase(std::string str) | ||
45 | { | ||
46 | transform(begin(str), end(str), begin(str), tolower); | ||
47 | return str; | ||
48 | } | ||
49 | |||
50 | std::string | ||
51 | _uppercase(std::string str) | ||
52 | { | ||
53 | transform(begin(str), end(str), begin(str), toupper); | ||
54 | return str; | ||
55 | } | ||
56 | |||
57 | std::string | ||
58 | _class_name_getter(std::string const& caller_class_prefix, std::string class_name) | ||
59 | { | ||
60 | std::replace(class_name.begin(), class_name.end(), '.', '_'); | ||
61 | return caller_class_prefix + "_" + class_name + "_cls_name_getter"; | ||
62 | } | ||
63 | |||
64 | void | ||
65 | _final_type_and_type_type_get(Eolian_Type const* tp_in, Eolian_Type const*& tp_out, Eolian_Type_Type& tpt_out) | ||
66 | { | ||
67 | tp_out = tp_in; | ||
68 | tpt_out = eolian_type_type_get(tp_in); | ||
69 | while ((tpt_out == EOLIAN_TYPE_REGULAR || tpt_out == EOLIAN_TYPE_ALIAS) && !eolian_type_is_extern(tp_out)) | ||
70 | { | ||
71 | auto t = eolian_type_base_type_get(tp_out); | ||
72 | // TODO: shouldn't __undefined_type be flagged as external??? | ||
73 | if (!t || !eolian_type_full_name_get(t) || strcmp(eolian_type_full_name_get(t), "__undefined_type") == 0) break; | ||
74 | tp_out = t; | ||
75 | tpt_out = eolian_type_type_get(t); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | std::string | ||
80 | _eolian_type_cpp_type_named_get(const Eolian_Type *tp, std::string const& caller_class_prefix, std::set<std::string>& need_name_getter) | ||
81 | { | ||
82 | const auto is_const = eolian_type_is_const(tp); | ||
83 | |||
84 | Eolian_Type_Type tpt = EOLIAN_TYPE_UNKNOWN_TYPE; | ||
85 | _final_type_and_type_type_get(tp, tp, tpt); | ||
86 | |||
87 | if (tpt == EOLIAN_TYPE_UNKNOWN_TYPE) | ||
88 | return "error"; | ||
89 | |||
90 | std::string result; | ||
91 | |||
92 | if ((tpt == EOLIAN_TYPE_VOID | ||
93 | || tpt == EOLIAN_TYPE_REGULAR | ||
94 | || tpt == EOLIAN_TYPE_COMPLEX | ||
95 | || tpt == EOLIAN_TYPE_STRUCT | ||
96 | || tpt == EOLIAN_TYPE_STRUCT_OPAQUE | ||
97 | || tpt == EOLIAN_TYPE_ENUM | ||
98 | || tpt == EOLIAN_TYPE_ALIAS | ||
99 | || tpt == EOLIAN_TYPE_CLASS) | ||
100 | && is_const) | ||
101 | { | ||
102 | result += "const "; | ||
103 | } | ||
104 | |||
105 | |||
106 | if (tpt == EOLIAN_TYPE_REGULAR | ||
107 | || tpt == EOLIAN_TYPE_COMPLEX | ||
108 | || tpt == EOLIAN_TYPE_STRUCT | ||
109 | || tpt == EOLIAN_TYPE_STRUCT_OPAQUE | ||
110 | || tpt == EOLIAN_TYPE_ENUM | ||
111 | || tpt == EOLIAN_TYPE_ALIAS | ||
112 | || tpt == EOLIAN_TYPE_CLASS) | ||
113 | { | ||
114 | for (efl::eina::iterator<const char> first(::eolian_type_namespaces_get(tp)), last; first != last; ++first) | ||
115 | { | ||
116 | std::string np(&*first); | ||
117 | result += np + "_"; // TODO: transform it to the C++ equivalent? | ||
118 | } | ||
119 | |||
120 | // this comes from ctypes at eo_lexer.c and KEYWORDS at eo_lexer.h | ||
121 | const static std::unordered_map<std::string, std::string> type_map = { | ||
122 | {"byte", "signed char"}, | ||
123 | {"ubyte", "unsigned char"}, | ||
124 | {"char", "char"}, | ||
125 | {"short", "short"}, | ||
126 | {"ushort", "unsigned short"}, | ||
127 | {"int", "int"}, | ||
128 | {"uint", "unsigned int"}, | ||
129 | {"long", "long"}, | ||
130 | {"ulong", "unsigned long"}, | ||
131 | {"llong", "long long"}, | ||
132 | {"ullong", "unsigned long long"}, | ||
133 | {"int8", "int8_t"}, | ||
134 | {"uint8", "uint8_t"}, | ||
135 | {"int16", "int16_t"}, | ||
136 | {"uint16", "uint16_t"}, | ||
137 | {"int32", "int32_t"}, | ||
138 | {"uint32", "uint32_t"}, | ||
139 | {"int64", "int64_t"}, | ||
140 | {"uint64", "uint64_t"}, | ||
141 | {"int128", "int128_t"}, | ||
142 | {"uint128", "uint128_t"}, | ||
143 | {"size", "size_t"}, | ||
144 | {"ssize", "ssize_t"}, | ||
145 | {"intptr", "intptr_t"}, | ||
146 | {"uintptr", "uintptr_t"}, | ||
147 | {"ptrdiff", "ptrdiff_t"}, | ||
148 | {"time", "time_t"}, | ||
149 | {"float", "float"}, | ||
150 | {"double", "double"}, | ||
151 | {"bool", "Eina_Bool"}, | ||
152 | {"void", "void"}, | ||
153 | {"generic_value", "Eina_Value"}, | ||
154 | {"accessor", "Eina_Accessor"}, | ||
155 | {"array", "Eina_Array"}, | ||
156 | {"iterator", "Eina_Iterator"}, | ||
157 | {"hash", "Eina_Hash"}, | ||
158 | {"list", "Eina_List"} | ||
159 | }; | ||
160 | |||
161 | std::string type_name = eolian_type_name_get(tp); | ||
162 | auto it = type_map.find(type_name); | ||
163 | if (it != end(type_map)) | ||
164 | type_name = it->second; | ||
165 | result += type_name; | ||
166 | |||
167 | if (tpt == EOLIAN_TYPE_STRUCT) | ||
168 | { | ||
169 | result = "efl::eina::js::make_struct_tag<" + result + ">"; | ||
170 | } | ||
171 | } | ||
172 | else if (tpt == EOLIAN_TYPE_VOID) | ||
173 | result += "void"; | ||
174 | else // tpt == EOLIAN_TYPE_POINTER | ||
175 | { | ||
176 | auto btp = eolian_type_base_type_get(tp); | ||
177 | result += _eolian_type_cpp_type_named_get(btp, caller_class_prefix, need_name_getter); | ||
178 | |||
179 | const auto base_is_const = eolian_type_is_const(btp); | ||
180 | |||
181 | Eolian_Type_Type btpt = EOLIAN_TYPE_UNKNOWN_TYPE; | ||
182 | _final_type_and_type_type_get(btp, btp, btpt); | ||
183 | |||
184 | if (btpt == EOLIAN_TYPE_STRUCT) | ||
185 | { | ||
186 | std::string f = "::make_struct_tag"; | ||
187 | auto p = result.find(f); | ||
188 | if (p == std::string::npos) | ||
189 | throw std::runtime_error("missing struct type tag"); | ||
190 | result.replace(p, f.size(), "::make_struct_ptr_tag"); | ||
191 | result.pop_back(); | ||
192 | result += " *"; | ||
193 | if (is_const) result += " const"; | ||
194 | result += ">"; | ||
195 | } | ||
196 | else | ||
197 | { | ||
198 | if (btpt != EOLIAN_TYPE_POINTER || base_is_const) | ||
199 | result += ' '; | ||
200 | result += '*'; | ||
201 | if (is_const) result += " const"; | ||
202 | } | ||
203 | |||
204 | if (btpt == EOLIAN_TYPE_COMPLEX) | ||
205 | { | ||
206 | result = "efl::eina::js::make_complex_tag<" + result; | ||
207 | |||
208 | bool has_subtypes = false; | ||
209 | auto subtypes = eolian_type_subtypes_get(btp); | ||
210 | const Eolian_Type *subtype; | ||
211 | EINA_ITERATOR_FOREACH(subtypes, subtype) | ||
212 | { | ||
213 | auto t = _eolian_type_cpp_type_named_get(subtype, caller_class_prefix, need_name_getter); | ||
214 | auto k = type_class_name(subtype); | ||
215 | if (!k.empty()) | ||
216 | { | ||
217 | result += ", " + t + ", " + _class_name_getter(caller_class_prefix, k); | ||
218 | need_name_getter.insert(k); | ||
219 | } | ||
220 | else | ||
221 | { | ||
222 | result += ", " + t + ", ::efl::eina::js::nonclass_cls_name_getter"; | ||
223 | } | ||
224 | has_subtypes = true; | ||
225 | } | ||
226 | |||
227 | if (!has_subtypes) | ||
228 | throw eolian::js::incomplete_complex_type_error("Incomplete complex type"); | ||
229 | |||
230 | result += ">"; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /*if (!name.empty()) | ||
235 | { | ||
236 | if (tpt != EOLIAN_TYPE_POINTER) | ||
237 | result += ' '; | ||
238 | result += name; | ||
239 | }*/ | ||
240 | |||
241 | return result; | ||
242 | } | ||
243 | |||
244 | using ParametersIterator = efl::eina::iterator<const ::Eolian_Function_Parameter>; | ||
245 | |||
246 | std::vector<const ::Eolian_Function_Parameter*> | ||
247 | _eolian_function_keys_get(const Eolian_Function *function_id, Eolian_Function_Type ftype) | ||
248 | { | ||
249 | std::vector<const ::Eolian_Function_Parameter*> keys; | ||
250 | |||
251 | for(ParametersIterator it(::eolian_property_keys_get(function_id, ftype)), last; it != last; ++it) | ||
252 | keys.push_back(&*it); | ||
253 | |||
254 | return keys; | ||
255 | } | ||
256 | |||
257 | std::vector<const ::Eolian_Function_Parameter*> | ||
258 | _eolian_function_parameters_get(const Eolian_Function *function_id, Eolian_Function_Type function_type) | ||
259 | { | ||
260 | std::vector<const ::Eolian_Function_Parameter*> parameters; | ||
261 | |||
262 | ParametersIterator it { (function_type == EOLIAN_METHOD) ? | ||
263 | ::eolian_function_parameters_get(function_id) : | ||
264 | ::eolian_property_values_get(function_id, function_type) | ||
265 | }, last; | ||
266 | |||
267 | for(; it != last; ++it) | ||
268 | parameters.push_back(&*it); | ||
269 | |||
270 | return parameters; | ||
271 | } | ||
272 | |||
273 | bool | ||
274 | _function_return_is_missing(Eolian_Function const* func, Eolian_Function_Type func_type) | ||
275 | { | ||
276 | // XXX This function shouldn't exist. Eolian should | ||
277 | // forge functions a priori. Bindings generators | ||
278 | // shouldn't be required to convert such thing. | ||
279 | Eolian_Type const* type = | ||
280 | ::eolian_function_return_type_get(func, func_type); | ||
281 | return !type; | ||
282 | } | ||
283 | |||
284 | void separate_functions(Eolian_Class const* klass, Eolian_Function_Type t, bool ignore_constructors, | ||
285 | std::vector<Eolian_Function const*>& constructor_functions, | ||
286 | std::vector<Eolian_Function const*>& normal_functions) | ||
287 | { | ||
288 | efl::eina::iterator<Eolian_Function> first ( ::eolian_class_functions_get(klass, t) ) | ||
289 | , last; | ||
290 | for(; first != last; ++first) | ||
291 | { | ||
292 | Eolian_Function const* function = &*first; | ||
293 | if(eolian_function_scope_get(function) == EOLIAN_SCOPE_PUBLIC) | ||
294 | { | ||
295 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ::eolian_function_full_c_name_get(function, t, EINA_FALSE); | ||
296 | if(strcmp("elm_obj_entry_input_panel_imdata_get", ::eolian_function_full_c_name_get(function, t, EINA_FALSE)) != 0 && | ||
297 | !eolian_function_is_beta(function) && | ||
298 | // strcmp("data_callback", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
299 | strcmp("property", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
300 | strcmp("part_text_anchor_geometry_get", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
301 | strcmp("children_iterator_new", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
302 | strcmp("inputs_get", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
303 | strcmp("constructor", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
304 | strcmp("render_updates", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
305 | strcmp("render2_updates", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
306 | strcmp("event_callback_priority_add", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
307 | strcmp("event_callback_array_priority_add", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
308 | strcmp("event_callback_array_del", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
309 | strcmp("event_callback_call", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
310 | strcmp("event_callback_forwarder_add", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
311 | strcmp("event_callback_forwarder_del", ::eolian_function_name_get(function)) != 0 && // TODO: remove this | ||
312 | strcmp("event_callback_del", ::eolian_function_name_get(function)) != 0) | ||
313 | { | ||
314 | if( ::eolian_function_is_constructor(function, klass)) | ||
315 | { | ||
316 | if(!ignore_constructors) | ||
317 | { | ||
318 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is a constructor"; | ||
319 | constructor_functions.push_back(function); | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "ignoring parent's constructors"; | ||
324 | } | ||
325 | } | ||
326 | else /*if( std::strcmp( ::eolian_function_full_c_name_get(function, t, EINA_FALSE) | ||
327 | , "eo_parent") != 0)*/ | ||
328 | { | ||
329 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is a NOT constructor " | ||
330 | << ::eolian_function_full_c_name_get(function, t, EINA_FALSE); | ||
331 | normal_functions.push_back(function); | ||
332 | } | ||
333 | // else | ||
334 | // { | ||
335 | // EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "parent_set as first constructor"; | ||
336 | // constructor_functions.insert(constructor_functions.begin(), function); | ||
337 | // normal_functions.push_back(function); | ||
338 | // } | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | int main(int argc, char** argv) | ||
345 | { | ||
346 | namespace format = eolian::js::format; | ||
347 | |||
348 | std::vector<std::string> include_paths; | ||
349 | std::string out_file, in_file; | ||
350 | |||
351 | efl::eina::eina_init eina_init; | ||
352 | struct eolian_init | ||
353 | { | ||
354 | eolian_init() { ::eolian_init(); } | ||
355 | ~eolian_init() { ::eolian_shutdown(); } | ||
356 | } eolian_init; | ||
357 | |||
358 | const struct option long_options[] = | ||
359 | { | ||
360 | { "in", required_argument, 0, 'I' }, | ||
361 | { "out-file", required_argument, 0, 'o' }, | ||
362 | { "version", no_argument, 0, 'v' }, | ||
363 | { "help", no_argument, 0, 'h' }, | ||
364 | { 0, 0, 0, 0 } | ||
365 | }; | ||
366 | const char* options = "I:D:o:c:arvh"; | ||
367 | |||
368 | // get command line options | ||
369 | int c, idx; | ||
370 | while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1) | ||
371 | { | ||
372 | if (c == 'I') | ||
373 | { | ||
374 | include_paths.push_back(optarg); | ||
375 | } | ||
376 | else if (c == 'o') | ||
377 | { | ||
378 | if(!out_file.empty()) | ||
379 | { | ||
380 | // _usage(argv[0]); | ||
381 | return 1; | ||
382 | } | ||
383 | out_file = optarg; | ||
384 | } | ||
385 | else if (c == 'h') | ||
386 | { | ||
387 | // _usage(argv[0]); | ||
388 | return 1; | ||
389 | } | ||
390 | else if (c == 'v') | ||
391 | { | ||
392 | // _print_version(); | ||
393 | // if (argc == 2) exit(EXIT_SUCCESS); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | if (optind == argc-1) | ||
398 | { | ||
399 | in_file = argv[optind]; | ||
400 | } | ||
401 | |||
402 | // Add include paths to eolian library | ||
403 | for(auto src : include_paths) | ||
404 | if (!::eolian_directory_scan(src.c_str())) | ||
405 | { | ||
406 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) | ||
407 | << "Couldn't load eolian from '" << src << "'."; | ||
408 | } | ||
409 | if (!::eolian_all_eot_files_parse()) | ||
410 | { | ||
411 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) | ||
412 | << "Eolian failed parsing eot files"; | ||
413 | assert(false && "Error parsing eot files"); | ||
414 | } | ||
415 | if (!::eolian_file_parse(in_file.c_str())) | ||
416 | { | ||
417 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) | ||
418 | << "Failed parsing: " << in_file << "."; | ||
419 | assert(false && "Error parsing input file"); | ||
420 | } | ||
421 | |||
422 | // Create filename path for output | ||
423 | std::string file_basename; | ||
424 | const Eolian_Class *klass = NULL; | ||
425 | { | ||
426 | char* dup = strdup(in_file.c_str()); | ||
427 | char *bn = basename(dup); | ||
428 | klass = ::eolian_class_get_by_file(bn); | ||
429 | file_basename = bn; | ||
430 | free(dup); | ||
431 | } | ||
432 | if(!klass) | ||
433 | { | ||
434 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "could not find any class defined in this eo file"; | ||
435 | return -1; | ||
436 | } | ||
437 | |||
438 | std::vector<Eolian_Function const*> constructor_functions; | ||
439 | std::vector<Eolian_Function const*> normal_functions; | ||
440 | |||
441 | std::set<Eolian_Class const*> classes; | ||
442 | |||
443 | // separate normal functions from constructors for all methods and properties | ||
444 | separate_functions(klass, EOLIAN_METHOD, false, constructor_functions, normal_functions); | ||
445 | separate_functions(klass, EOLIAN_PROPERTY, false, constructor_functions, normal_functions); | ||
446 | |||
447 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "functions were separated"; | ||
448 | |||
449 | // function to iterate through all inheritance class | ||
450 | std::function<void(Eolian_Class const*, std::function<void(Eolian_Class const*)>)> | ||
451 | recurse_inherits | ||
452 | = [&] (Eolian_Class const* klass, std::function<void(Eolian_Class const*)> function) | ||
453 | { | ||
454 | for(efl::eina::iterator<const char> first ( ::eolian_class_inherits_get(klass)) | ||
455 | , last; first != last; ++first) | ||
456 | { | ||
457 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << &*first << std::endl; | ||
458 | Eolian_Class const* base = ::eolian_class_get_by_name(&*first); | ||
459 | function(base); | ||
460 | recurse_inherits(base, function); | ||
461 | } | ||
462 | }; | ||
463 | |||
464 | // save functions from all inhehritance | ||
465 | auto save_functions = [&](Eolian_Class const* klass) | ||
466 | { | ||
467 | if(classes.find(klass) == classes.end()) | ||
468 | { | ||
469 | classes.insert(klass); | ||
470 | separate_functions(klass, EOLIAN_METHOD, true, constructor_functions, normal_functions); | ||
471 | separate_functions(klass, EOLIAN_PROPERTY, true, constructor_functions, normal_functions); | ||
472 | } | ||
473 | }; | ||
474 | // save functions from all inheritance class without constructors | ||
475 | recurse_inherits(klass, save_functions); | ||
476 | |||
477 | EINA_CXX_DOM_LOG_DBG(eolian::js::domain) << "inherits were recursed"; | ||
478 | |||
479 | std::ofstream os (out_file.c_str()); | ||
480 | if(!os.is_open()) | ||
481 | { | ||
482 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Couldn't open output file " << out_file; | ||
483 | return -1; | ||
484 | } | ||
485 | |||
486 | EINA_CXX_DOM_LOG_DBG(eolian::js::domain) << "output was opened"; | ||
487 | |||
488 | std::string class_name(name(klass)), | ||
489 | class_full_name(full_name(klass)), | ||
490 | upper_case_class_name(_uppercase(class_name)), | ||
491 | lower_case_class_name(_lowercase(class_name)); | ||
492 | |||
493 | // Start preamble generation | ||
494 | if (getenv("EFL_RUN_IN_TREE")) | ||
495 | { | ||
496 | os << "#ifdef HAVE_CONFIG_H\n"; | ||
497 | os << "#include \"config.h\"\n"; | ||
498 | os << "#endif\n"; | ||
499 | |||
500 | os << "#include <Efl.h>\n"; | ||
501 | os << "#include <Ecore.h>\n"; | ||
502 | os << "#include <Eo.h>\n\n"; | ||
503 | } | ||
504 | else | ||
505 | { | ||
506 | os << "#ifdef HAVE_CONFIG_H\n"; | ||
507 | os << "#include \"elementary_config.h\"\n"; | ||
508 | os << "#endif\n"; | ||
509 | |||
510 | os << "#include <Efl.h>\n"; | ||
511 | os << "#include <Ecore.h>\n"; | ||
512 | os << "#include <Eo.h>\n"; | ||
513 | os << "#include <Evas.h>\n"; | ||
514 | os << "#include <Edje.h>\n"; | ||
515 | |||
516 | os << "#include <Elementary.h>\n\n"; | ||
517 | os << "extern \"C\" {\n"; | ||
518 | os << "#include <elm_widget.h>\n"; | ||
519 | os << "}\n\n"; | ||
520 | } | ||
521 | os << "#include <Eina_Js.hh>\n\n"; | ||
522 | os << "#include <Eo_Js.hh>\n\n"; | ||
523 | os << "#ifdef EAPI\n"; | ||
524 | os << "# undef EAPI\n"; | ||
525 | os << "#endif\n"; | ||
526 | |||
527 | os << "#ifdef _WIN32\n"; | ||
528 | os << "# define EAPI __declspec(dllimport)\n"; | ||
529 | os << "#else\n"; | ||
530 | os << "# ifdef __GNUC__\n"; | ||
531 | os << "# if __GNUC__ >= 4\n"; | ||
532 | os << "# define EAPI __attribute__ ((visibility(\"default\")))\n"; | ||
533 | os << "# else\n"; | ||
534 | os << "# define EAPI\n"; | ||
535 | os << "# endif\n"; | ||
536 | os << "# else\n"; | ||
537 | os << "# define EAPI\n"; | ||
538 | os << "# endif\n"; | ||
539 | os << "#endif /* ! _WIN32 */\n\n"; | ||
540 | os << "extern \"C\" {\n"; | ||
541 | |||
542 | // generate include for necessary headers | ||
543 | if(is_evas(klass)) | ||
544 | os << "#include <Evas.h>\n"; | ||
545 | |||
546 | auto includes_fun = [&os] (Eolian_Class const* klass) | ||
547 | { | ||
548 | os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n"; | ||
549 | }; | ||
550 | // generate include for all inheritance | ||
551 | recurse_inherits(klass, includes_fun); | ||
552 | os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n"; | ||
553 | |||
554 | os << "}\n\n"; | ||
555 | |||
556 | os << "#ifdef _WIN32\n"; | ||
557 | os << "# undef EAPI\n"; | ||
558 | os << "# define EAPI __declspec(dllexport)\n"; | ||
559 | os << "#endif /* ! _WIN32 */\n\n"; | ||
560 | |||
561 | os << "#include <array>\n\n"; | ||
562 | |||
563 | EINA_CXX_DOM_LOG_DBG(eolian::js::domain) << "includes added"; | ||
564 | |||
565 | // generate open namespaces | ||
566 | if(namespace_size(klass)) | ||
567 | { | ||
568 | std::string space = ""; | ||
569 | for(efl::eina::iterator<const char> first(::eolian_class_namespaces_get(klass)), last; first != last; ++first) | ||
570 | { | ||
571 | std::string lower(_lowercase(&*first)); | ||
572 | os << "namespace " << lower << " {" << space; | ||
573 | space = " "; | ||
574 | } | ||
575 | |||
576 | os << "\n"; | ||
577 | } | ||
578 | |||
579 | // generate event map | ||
580 | std::string event_map = class_name; | ||
581 | event_map += "_ev_info_map"; | ||
582 | |||
583 | os << "namespace {\n"; | ||
584 | os << "::efl::eo::js::event_information_map " << event_map << ";\n"; | ||
585 | os << "}\n"; | ||
586 | |||
587 | EINA_CXX_DOM_LOG_DBG(eolian::js::domain) << "namespace"; | ||
588 | |||
589 | // save functions that need a name getter for structs | ||
590 | std::set<std::string> need_name_getter; | ||
591 | |||
592 | // generate all structs parsed in this file | ||
593 | std::stringstream structs_ss; | ||
594 | for (efl::eina::iterator<Eolian_Type> first(::eolian_type_structs_get_by_file(file_basename.c_str())) | ||
595 | , last; first != last; ++first) | ||
596 | { | ||
597 | std::stringstream ss; | ||
598 | auto tp = &*first; | ||
599 | if (::eolian_type_type_get(tp) == EOLIAN_TYPE_STRUCT_OPAQUE) | ||
600 | continue; | ||
601 | |||
602 | auto struct_name = ::eolian_type_name_get(tp); | ||
603 | auto struct_type_full_name = ::eolian_type_full_name_get(tp); | ||
604 | if (!struct_name || !struct_type_full_name) | ||
605 | { | ||
606 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get struct type name"; | ||
607 | continue; | ||
608 | } | ||
609 | else if(strcmp(struct_type_full_name, "Eo.Callback_Array_Item") == 0) | ||
610 | continue; | ||
611 | std::string struct_c_name = struct_type_full_name; | ||
612 | std::replace(struct_c_name.begin(), struct_c_name.end(), '.', '_'); | ||
613 | ss << " {\n"; | ||
614 | ss << " auto fields_func = [](v8::Isolate* isolate_, v8::Local<v8::ObjectTemplate> prototype_)\n"; | ||
615 | ss << " {\n"; | ||
616 | for (efl::eina::iterator<Eolian_Struct_Type_Field> sf(::eolian_type_struct_fields_get(tp)) | ||
617 | , sf_end; sf != sf_end; ++sf) | ||
618 | { | ||
619 | auto field_type = ::eolian_type_struct_field_type_get(&*sf); | ||
620 | auto field_name = ::eolian_type_struct_field_name_get(&*sf); | ||
621 | if (!field_name) | ||
622 | { | ||
623 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get struct field name"; | ||
624 | continue; | ||
625 | } | ||
626 | std::string field_type_tag_name; | ||
627 | try | ||
628 | { | ||
629 | field_type_tag_name = _eolian_type_cpp_type_named_get(field_type, class_name, need_name_getter); | ||
630 | } | ||
631 | catch(eolian::js::incomplete_complex_type_error const& e) | ||
632 | { | ||
633 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Exception while generating '" << field_name << "' fielf of '" << struct_type_full_name << "' struct: " << e.what(); | ||
634 | continue; | ||
635 | } | ||
636 | std::string member_ref = struct_c_name; | ||
637 | member_ref += "::"; | ||
638 | member_ref += field_name; | ||
639 | |||
640 | auto k = type_class_name(field_type); | ||
641 | if (!k.empty()) | ||
642 | { | ||
643 | need_name_getter.insert(k); | ||
644 | k = _class_name_getter(class_name, k); | ||
645 | } | ||
646 | else | ||
647 | { | ||
648 | k = "::efl::eina::js::nonclass_cls_name_getter"; | ||
649 | } | ||
650 | ss << " prototype_->SetAccessor(::efl::eina::js::compatibility_new<v8::String>(isolate_, \"" << format::generic(field_name) << "\"),\n"; | ||
651 | ss << " static_cast<v8::AccessorGetterCallback>(&::efl::eo::js::get_struct_member<" << struct_c_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">),\n"; | ||
652 | ss << " static_cast<v8::AccessorSetterCallback>(&::efl::eo::js::set_struct_member<" << struct_c_name << ", " << field_type_tag_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">));\n"; | ||
653 | } | ||
654 | ss << " };\n"; | ||
655 | ss << " auto to_export = ::efl::eo::js::get_namespace({"; | ||
656 | bool comma = false; | ||
657 | for (efl::eina::iterator<const char> ns_it(::eolian_type_namespaces_get(tp)), ns_end; ns_it != ns_end; ++ns_it) | ||
658 | { | ||
659 | if (comma) | ||
660 | ss << ", "; | ||
661 | comma = true; | ||
662 | ss << '"' << format::generic(&*ns_it) << '"'; | ||
663 | } | ||
664 | ss << "}, isolate, global);\n"; | ||
665 | ss << " ::efl::eo::js::register_struct<" << struct_c_name << ">(isolate, \"" | ||
666 | << format::generic(struct_name) << "\", \"" << struct_type_full_name << "\", to_export, fields_func);\n"; | ||
667 | ss << " }\n"; | ||
668 | |||
669 | structs_ss << ss.str(); | ||
670 | } | ||
671 | |||
672 | // generate register function for V8 | ||
673 | std::stringstream register_from_constructor_begin_ss; | ||
674 | register_from_constructor_begin_ss | ||
675 | << "EAPI v8::Local<v8::ObjectTemplate>\n" | ||
676 | << "register_" << lower_case_class_name << "_from_constructor\n" | ||
677 | << "(v8::Isolate* isolate, v8::Handle<v8::FunctionTemplate> constructor, ::efl::eina::js::global_ref<v8::Function>* constructor_from_eo)\n" | ||
678 | << "{\n" | ||
679 | << " v8::Local<v8::ObjectTemplate> instance = constructor->InstanceTemplate();\n" | ||
680 | << " instance->SetInternalFieldCount(1);\n" | ||
681 | << " v8::Handle<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();\n"; | ||
682 | |||
683 | std::stringstream functions_ss; | ||
684 | std::set<std::string> member_names; | ||
685 | std::set<std::string> event_member_names; | ||
686 | for(auto function : normal_functions) | ||
687 | { | ||
688 | std::vector<Eolian_Function_Type> function_types; | ||
689 | switch (eolian_function_type_get(function)) | ||
690 | { | ||
691 | case EOLIAN_METHOD: | ||
692 | function_types = {EOLIAN_METHOD}; | ||
693 | break; | ||
694 | case EOLIAN_PROPERTY: | ||
695 | function_types = {EOLIAN_PROP_GET, EOLIAN_PROP_SET}; | ||
696 | break; | ||
697 | case EOLIAN_PROP_GET: | ||
698 | function_types = {EOLIAN_PROP_GET}; | ||
699 | break; | ||
700 | case EOLIAN_PROP_SET: | ||
701 | function_types = {EOLIAN_PROP_SET}; | ||
702 | break; | ||
703 | default: | ||
704 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Unresolved function type"; | ||
705 | continue; | ||
706 | } | ||
707 | |||
708 | // generate function registration | ||
709 | for (const auto function_type : function_types) | ||
710 | { | ||
711 | try | ||
712 | { | ||
713 | std::string member_name; | ||
714 | switch (function_type) | ||
715 | { | ||
716 | case EOLIAN_METHOD: | ||
717 | member_name = eolian_function_name_get(function); | ||
718 | break; | ||
719 | case EOLIAN_PROP_SET: | ||
720 | member_name = std::string("set_") + eolian_function_name_get(function); | ||
721 | break; | ||
722 | case EOLIAN_PROP_GET: | ||
723 | member_name = std::string("get_") + eolian_function_name_get(function); | ||
724 | break; | ||
725 | case EOLIAN_PROPERTY: | ||
726 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "EOLIAN_PROPERTY function type is invalid at this point"; | ||
727 | return -1; | ||
728 | case EOLIAN_UNRESOLVED: | ||
729 | default: | ||
730 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Unresolved function type"; | ||
731 | return -1; | ||
732 | } | ||
733 | |||
734 | if(member_names.find(member_name) == member_names.end()) | ||
735 | { | ||
736 | member_names.insert(member_name); | ||
737 | std::stringstream ss; | ||
738 | auto output_begin = [&] (std::string name) | ||
739 | { | ||
740 | if(! ::eolian_function_is_constructor(function, klass)) | ||
741 | ss << " prototype->Set( ::efl::eina::js::compatibility_new<v8::String>(isolate, \"" | ||
742 | << format::generic(name) << "\")\n" | ||
743 | << " , ::efl::eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::call_function\n" | ||
744 | << " , efl::eo::js::call_function_data<\n" | ||
745 | << " ::efl::eina::_mpl::tuple_c<std::size_t"; | ||
746 | }; | ||
747 | |||
748 | output_begin(member_name); | ||
749 | |||
750 | const auto key_params = _eolian_function_keys_get(function, function_type); | ||
751 | const auto parameters = _eolian_function_parameters_get(function, function_type); | ||
752 | |||
753 | std::vector<const ::Eolian_Function_Parameter*> full_params; | ||
754 | full_params.insert(end(full_params), begin(key_params), end(key_params)); | ||
755 | // only one property_get parameter is translated as the function return in C | ||
756 | const auto param_as_return = (EOLIAN_PROP_GET == function_type) && (parameters.size() == 1) | ||
757 | && _function_return_is_missing(function, function_type); | ||
758 | if (!param_as_return) | ||
759 | full_params.insert(end(full_params), begin(parameters), end(parameters)); | ||
760 | |||
761 | // call_function_data Ins | ||
762 | std::size_t i = 0; | ||
763 | for (auto parameter : full_params) | ||
764 | { | ||
765 | if (EOLIAN_PROP_SET == function_type) | ||
766 | ss << ", " << i; | ||
767 | else | ||
768 | if (EOLIAN_METHOD == function_type) | ||
769 | { | ||
770 | switch (eolian_parameter_direction_get(parameter)) | ||
771 | { | ||
772 | case EOLIAN_IN_PARAM: | ||
773 | case EOLIAN_INOUT_PARAM: | ||
774 | ss << ", " << i; | ||
775 | default: break; | ||
776 | } | ||
777 | } | ||
778 | ++i; | ||
779 | } | ||
780 | |||
781 | // call_function_data Outs | ||
782 | ss << ">\n , ::efl::eina::_mpl::tuple_c<std::size_t"; | ||
783 | auto key_count = key_params.size(); | ||
784 | i = 0; | ||
785 | for (auto parameter : full_params) | ||
786 | { | ||
787 | // ignore keys | ||
788 | if (key_count > 0) | ||
789 | { | ||
790 | --key_count; | ||
791 | ++i; | ||
792 | continue; | ||
793 | } | ||
794 | |||
795 | // properties doesn't support in/out/inout | ||
796 | if (EOLIAN_PROP_GET == function_type) | ||
797 | ss << ", " << i; | ||
798 | else | ||
799 | if (EOLIAN_METHOD == function_type) | ||
800 | { | ||
801 | switch (eolian_parameter_direction_get(parameter)) | ||
802 | { | ||
803 | case EOLIAN_OUT_PARAM: | ||
804 | case EOLIAN_INOUT_PARAM: | ||
805 | ss << ", " << i; | ||
806 | default: break; | ||
807 | } | ||
808 | } | ||
809 | ++i; | ||
810 | } | ||
811 | |||
812 | // call_function_data Ownership | ||
813 | ss << ">\n , std::tuple<\n"; | ||
814 | auto sep = ""; | ||
815 | for (auto parameter : full_params) | ||
816 | { | ||
817 | auto type = eolian_parameter_type_get(parameter); | ||
818 | if(eolian_type_is_own(type)) | ||
819 | ss << sep << " ::std::true_type"; | ||
820 | else | ||
821 | ss << sep << " ::std::false_type"; | ||
822 | sep = ",\n"; | ||
823 | } | ||
824 | |||
825 | |||
826 | // call_function_data Return | ||
827 | ss << ">\n , "; | ||
828 | |||
829 | const Eolian_Type *return_type = nullptr; | ||
830 | if (param_as_return) | ||
831 | { | ||
832 | return_type = eolian_parameter_type_get(parameters[0]); | ||
833 | } | ||
834 | else | ||
835 | { | ||
836 | return_type = ::eolian_function_return_type_get(function, function_type); | ||
837 | } | ||
838 | std::string param = "void"; | ||
839 | if (nullptr != return_type) | ||
840 | { | ||
841 | param = _eolian_type_cpp_type_named_get(return_type, class_name, need_name_getter); | ||
842 | } | ||
843 | ss << param; | ||
844 | |||
845 | |||
846 | // call_function_data Parameters | ||
847 | ss << "\n , std::tuple<\n"; | ||
848 | sep = " "; | ||
849 | key_count = key_params.size(); | ||
850 | for (auto parameter : full_params) | ||
851 | { | ||
852 | // TODO: REVIEW ALL THIS TOO!!! | ||
853 | auto type = eolian_parameter_type_get(parameter); | ||
854 | auto param = _eolian_type_cpp_type_named_get(type, class_name, need_name_getter); | ||
855 | |||
856 | if (!key_count && EOLIAN_PROP_GET == function_type) | ||
857 | param += "*"; | ||
858 | else | ||
859 | { | ||
860 | switch(eolian_parameter_direction_get(parameter)) | ||
861 | { | ||
862 | case EOLIAN_OUT_PARAM: | ||
863 | case EOLIAN_INOUT_PARAM: | ||
864 | param += "*"; | ||
865 | default: break; | ||
866 | } | ||
867 | } | ||
868 | |||
869 | ss << sep << param; | ||
870 | sep = ",\n "; | ||
871 | |||
872 | if (key_count > 0) --key_count; | ||
873 | } | ||
874 | |||
875 | |||
876 | std::string param_class_names; | ||
877 | for (auto parameter : full_params) | ||
878 | { | ||
879 | param_class_names += '"' + type_class_name(::eolian_parameter_type_get(parameter)) + "\", "; | ||
880 | } | ||
881 | param_class_names += '"' + type_class_name(return_type) + '"'; | ||
882 | |||
883 | std::string param_class_names_array = "std::array<const char*, "; | ||
884 | param_class_names_array += std::to_string(full_params.size() + 1); | ||
885 | param_class_names_array += ">{{" + param_class_names + "}}"; | ||
886 | |||
887 | auto output_end = [&] (std::string const& name) | ||
888 | { | ||
889 | ss << "> >(isolate, " << param_class_names_array << ", & ::" << name << ")));\n"; | ||
890 | }; | ||
891 | switch (function_type) | ||
892 | { | ||
893 | case EOLIAN_METHOD: | ||
894 | output_end(eolian_function_full_c_name_get(function, function_type, EINA_FALSE)); | ||
895 | break; | ||
896 | case EOLIAN_PROP_SET: | ||
897 | output_end(eolian_function_full_c_name_get(function, function_type, EINA_FALSE) /*+ std::string("_set")*/); | ||
898 | break; | ||
899 | case EOLIAN_PROP_GET: | ||
900 | output_end(eolian_function_full_c_name_get(function, function_type, EINA_FALSE) /*+ std::string("_get")*/); | ||
901 | break; | ||
902 | case EOLIAN_PROPERTY: | ||
903 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "EOLIAN_PROPERTY function type is invalid at this point"; | ||
904 | return -1; | ||
905 | case EOLIAN_UNRESOLVED: | ||
906 | default: | ||
907 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Unresolved function type"; | ||
908 | return -1; | ||
909 | } | ||
910 | |||
911 | // Write function to functions stream | ||
912 | functions_ss << ss.str(); | ||
913 | } | ||
914 | } | ||
915 | catch(eolian::js::incomplete_complex_type_error const& e) | ||
916 | { | ||
917 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Exception while generating '" << eolian_function_name_get(function) << "': " << e.what(); | ||
918 | } | ||
919 | } | ||
920 | } | ||
921 | |||
922 | // generate all events | ||
923 | std::stringstream events_ss; | ||
924 | auto generate_events = [&] (Eolian_Class const* klass) | ||
925 | { | ||
926 | std::stringstream ss; | ||
927 | for(efl::eina::iterator< ::Eolian_Event> first ( ::eolian_class_events_get(klass)) | ||
928 | , last; first != last; ++first) | ||
929 | { | ||
930 | std::string event_name (::eolian_event_name_get(&*first)); | ||
931 | std::replace(event_name.begin(), event_name.end(), ',', '_'); | ||
932 | |||
933 | if (!eolian_event_is_beta(&*first) && | ||
934 | event_member_names.find(event_name) == event_member_names.end()) | ||
935 | { | ||
936 | auto tp = eolian_event_type_get(&*first); | ||
937 | ss << " {\n"; | ||
938 | ss << " static efl::eo::js::event_information ev_info{&constructor_from_eo, " << eolian_event_c_name_get(&*first); | ||
939 | ss << ", &efl::eo::js::event_callback<"; | ||
940 | ss << (tp ? _eolian_type_cpp_type_named_get(tp, class_name, need_name_getter) : "void"); | ||
941 | ss << ">, \"" << type_class_name(tp) << "\"};\n"; | ||
942 | ss << " " << event_map << "[\"" << event_name << "\"] = &ev_info;\n"; | ||
943 | ss << " }\n"; | ||
944 | event_member_names.insert(event_name); | ||
945 | } | ||
946 | } | ||
947 | events_ss << ss.str(); | ||
948 | }; | ||
949 | generate_events(klass); | ||
950 | recurse_inherits(klass, generate_events); | ||
951 | |||
952 | std::stringstream register_from_constructor_end_ss; | ||
953 | register_from_constructor_end_ss | ||
954 | << " prototype->Set(::efl::eina::js::compatibility_new<v8::String>(isolate, \"on\")\n" | ||
955 | << " , ::efl::eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::on_event\n" | ||
956 | << " , ::efl::eina::js::compatibility_new<v8::External>(isolate, &" << event_map << ")));\n" | ||
957 | << " static_cast<void>(prototype); /* avoid warnings */\n" | ||
958 | << " static_cast<void>(isolate); /* avoid warnings */\n" | ||
959 | << " static_cast<void>(constructor_from_eo); /* avoid warnings */\n" | ||
960 | << " return instance;\n" | ||
961 | << "}\n\n"; | ||
962 | |||
963 | std::stringstream name_getters_ss; | ||
964 | for (auto const& k : need_name_getter) | ||
965 | { | ||
966 | name_getters_ss << " struct " << _class_name_getter(class_name, k) << " { static char const* class_name() { return \"" << k << "\"; } };\n"; | ||
967 | } | ||
968 | |||
969 | os << "namespace {\n"; | ||
970 | os << name_getters_ss.str(); | ||
971 | os << "}\n\n"; | ||
972 | |||
973 | os << register_from_constructor_begin_ss.str(); | ||
974 | os << functions_ss.str(); | ||
975 | os << register_from_constructor_end_ss.str(); | ||
976 | |||
977 | // generate main entry-point for generation | ||
978 | os << "EAPI void register_" << lower_case_class_name | ||
979 | << "(v8::Handle<v8::Object> global, v8::Isolate* isolate)\n"; | ||
980 | os << "{\n"; | ||
981 | os << " v8::Handle<v8::FunctionTemplate> constructor = ::efl::eina::js::compatibility_new<v8::FunctionTemplate>\n"; | ||
982 | os << " (isolate, efl::eo::js::constructor\n" | ||
983 | << " , efl::eo::js::constructor_data(isolate\n" | ||
984 | " , "; | ||
985 | |||
986 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "before print eo_class"; | ||
987 | |||
988 | print_eo_class(klass, os); | ||
989 | |||
990 | EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print eo_class"; | ||
991 | |||
992 | for(auto function : constructor_functions) | ||
993 | { | ||
994 | auto ftype = eolian_function_type_get(function); | ||
995 | if(ftype == EOLIAN_PROPERTY) | ||
996 | ftype = EOLIAN_PROP_SET; | ||
997 | os << "\n , & ::" | ||
998 | << eolian_function_full_c_name_get(function, ftype, EINA_FALSE); | ||
999 | } | ||
1000 | |||
1001 | os << "));\n"; | ||
1002 | |||
1003 | os << " static ::efl::eina::js::global_ref<v8::Function> constructor_from_eo;\n"; | ||
1004 | os << events_ss.str(); | ||
1005 | os << " register_" << lower_case_class_name << "_from_constructor(isolate, constructor, &constructor_from_eo);\n"; | ||
1006 | |||
1007 | os << " constructor->SetClassName( ::efl::eina::js::compatibility_new<v8::String>(isolate, \"" | ||
1008 | << format::generic(class_name) | ||
1009 | << "\"));\n"; | ||
1010 | |||
1011 | os << " auto to_export = ::efl::eo::js::get_namespace({"; | ||
1012 | if (namespace_size(klass)) | ||
1013 | { | ||
1014 | bool comma = false; | ||
1015 | for (efl::eina::iterator<const char> ns_it(::eolian_class_namespaces_get(klass)), ns_end; ns_it != ns_end; ++ns_it) | ||
1016 | { | ||
1017 | if (comma) | ||
1018 | os << ", "; | ||
1019 | comma = true; | ||
1020 | os << '"' << format::generic(&*ns_it) << '"'; | ||
1021 | } | ||
1022 | } | ||
1023 | os << "}, isolate, global);\n"; | ||
1024 | |||
1025 | os << " to_export->Set( ::efl::eina::js::compatibility_new<v8::String>(isolate, \"" | ||
1026 | << format::generic(class_name) << "\")" | ||
1027 | << ", constructor->GetFunction());\n"; | ||
1028 | |||
1029 | |||
1030 | os << " {\n"; | ||
1031 | os << " v8::Handle<v8::FunctionTemplate> constructor = ::efl::eina::js::compatibility_new<v8::FunctionTemplate>\n"; | ||
1032 | os << " (isolate, &efl::eo::js::construct_from_eo);\n"; | ||
1033 | os << " constructor->SetClassName( ::efl::eina::js::compatibility_new<v8::String>(isolate, \"" | ||
1034 | << format::generic(class_name) | ||
1035 | << "\"));\n"; | ||
1036 | os << " v8::Local<v8::ObjectTemplate> instance = " | ||
1037 | << "register_" << lower_case_class_name << "_from_constructor(isolate, constructor, &constructor_from_eo);\n"; | ||
1038 | os << " ::efl::eina::js::make_persistent(isolate, instance);\n"; | ||
1039 | os << " constructor_from_eo = {isolate, constructor->GetFunction()};\n"; | ||
1040 | os << " ::efl::eina::js::register_class_constructor(\"" << class_full_name << "\", constructor_from_eo.handle());\n"; | ||
1041 | os << " }\n"; | ||
1042 | |||
1043 | os << structs_ss.str(); | ||
1044 | |||
1045 | // generate enumerations | ||
1046 | for (efl::eina::iterator<Eolian_Type> first(::eolian_type_enums_get_by_file(file_basename.c_str())) | ||
1047 | , last; first != last; ++first) | ||
1048 | { | ||
1049 | auto tp = &*first; | ||
1050 | if (::eolian_type_is_extern(tp)) | ||
1051 | continue; | ||
1052 | std::string enum_name = ::eolian_type_name_get(tp); | ||
1053 | os << " {\n"; | ||
1054 | os << " auto to_export = ::efl::eo::js::get_namespace({"; | ||
1055 | bool comma = false; | ||
1056 | for (efl::eina::iterator<const char> ns_it(::eolian_type_namespaces_get(tp)), ns_end; ns_it != ns_end; ++ns_it) | ||
1057 | { | ||
1058 | if (comma) | ||
1059 | os << ", "; | ||
1060 | comma = true; | ||
1061 | os << '"' << format::generic(&*ns_it) << '"'; | ||
1062 | } | ||
1063 | os << "}, isolate, global);\n"; | ||
1064 | os << " v8::Handle<v8::Object> enum_obj = efl::eina::js::compatibility_new<v8::Object>(isolate);\n"; | ||
1065 | os << " to_export->Set(efl::eina::js::compatibility_new<v8::String>(isolate, \"" | ||
1066 | << format::generic(enum_name) << "\"), enum_obj);\n"; | ||
1067 | for (efl::eina::iterator<Eolian_Enum_Type_Field> ef(::eolian_type_enum_fields_get(tp)) | ||
1068 | , ef_end; ef != ef_end; ++ef) | ||
1069 | { | ||
1070 | auto field_name = ::eolian_type_enum_field_name_get(&*ef); | ||
1071 | auto field_c_name = ::eolian_type_enum_field_c_name_get(&*ef); | ||
1072 | if (!field_name || !field_c_name) | ||
1073 | { | ||
1074 | EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get enum field name"; | ||
1075 | continue; | ||
1076 | } | ||
1077 | os << " enum_obj->Set(efl::eina::js::compatibility_new<v8::String>(isolate, \"" << format::constant(field_name) << "\"),\n"; | ||
1078 | os << " efl::eina::js::compatibility_new<v8::Int32>(isolate, static_cast<int32_t>(::" << field_c_name << ")));\n"; | ||
1079 | } | ||
1080 | os << " }\n"; | ||
1081 | } | ||
1082 | |||
1083 | os << "}\n\n"; | ||
1084 | |||
1085 | for(std::size_t i = 0, j = namespace_size(klass); i != j; ++i) | ||
1086 | os << "}"; | ||
1087 | os << "\n"; | ||
1088 | |||
1089 | |||
1090 | } | ||
diff --git a/src/bindings/eina_cxx/Eina.hh b/src/bindings/eina_cxx/Eina.hh index d12b0c930f..8f5462892e 100644 --- a/src/bindings/eina_cxx/Eina.hh +++ b/src/bindings/eina_cxx/Eina.hh | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <eina_log.hh> | 22 | #include <eina_log.hh> |
23 | #include <eina_optional.hh> | 23 | #include <eina_optional.hh> |
24 | #include <eina_integer_sequence.hh> | 24 | #include <eina_integer_sequence.hh> |
25 | #include <eina_pp.hh> | ||
25 | 26 | ||
26 | /** | 27 | /** |
27 | * @page eina_cxx_main Eina C++ (BETA) | 28 | * @page eina_cxx_main Eina C++ (BETA) |
diff --git a/src/bindings/eina_cxx/eina_accessor.hh b/src/bindings/eina_cxx/eina_accessor.hh index b867f14248..d084918ca8 100644 --- a/src/bindings/eina_cxx/eina_accessor.hh +++ b/src/bindings/eina_cxx/eina_accessor.hh | |||
@@ -114,7 +114,10 @@ struct accessor_common_base | |||
114 | * @warning It is important to take care when using it, since the | 114 | * @warning It is important to take care when using it, since the |
115 | * handle will be automatically release upon object destruction. | 115 | * handle will be automatically release upon object destruction. |
116 | */ | 116 | */ |
117 | Eina_Accessor* native_handle() const; | 117 | Eina_Accessor* native_handle() const |
118 | { | ||
119 | return _impl; | ||
120 | } | ||
118 | 121 | ||
119 | /** | 122 | /** |
120 | * @brief Swap content between both objects. | 123 | * @brief Swap content between both objects. |
diff --git a/src/bindings/eina_cxx/eina_array.hh b/src/bindings/eina_cxx/eina_array.hh index eb9e5578aa..d352de5ab7 100644 --- a/src/bindings/eina_cxx/eina_array.hh +++ b/src/bindings/eina_cxx/eina_array.hh | |||
@@ -32,6 +32,8 @@ public: | |||
32 | typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */ | 32 | typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */ |
33 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */ | 33 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */ |
34 | 34 | ||
35 | typedef typename _base_type::native_handle_type native_handle_type; | ||
36 | |||
35 | using _base_type::_base_type; | 37 | using _base_type::_base_type; |
36 | using _base_type::clear; | 38 | using _base_type::clear; |
37 | using _base_type::size; | 39 | using _base_type::size; |
@@ -59,6 +61,7 @@ public: | |||
59 | using _base_type::ciend; | 61 | using _base_type::ciend; |
60 | using _base_type::swap; | 62 | using _base_type::swap; |
61 | using _base_type::max_size; | 63 | using _base_type::max_size; |
64 | using _base_type::release_native_handle; | ||
62 | using _base_type::native_handle; | 65 | using _base_type::native_handle; |
63 | 66 | ||
64 | friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs) | 67 | friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs) |
@@ -131,6 +134,101 @@ struct _ptr_eo_array_iterator : _ptr_array_iterator<Eo> | |||
131 | using _base_type::native_handle; | 134 | using _base_type::native_handle; |
132 | }; | 135 | }; |
133 | 136 | ||
137 | /** | ||
138 | * @internal | ||
139 | */ | ||
140 | struct _eo_array_access_traits : _ptr_array_access_traits | ||
141 | { | ||
142 | template <typename T> | ||
143 | struct iterator | ||
144 | { | ||
145 | typedef _ptr_eo_array_iterator<T> type; | ||
146 | }; | ||
147 | template <typename T> | ||
148 | struct const_iterator : iterator<T const> {}; | ||
149 | |||
150 | template <typename T> | ||
151 | static T& back(Eina_Array* array) | ||
152 | { | ||
153 | return *static_cast<T*>(static_cast<void*>(array->data[size<T>(array)-1])); | ||
154 | } | ||
155 | template <typename T> | ||
156 | static T const& back(Eina_Array const* array) | ||
157 | { | ||
158 | return _eo_array_access_traits::back<T>(const_cast<Eina_Array*>(array)); | ||
159 | } | ||
160 | template <typename T> | ||
161 | static T& front(Eina_Array* array) | ||
162 | { | ||
163 | return *static_cast<T*>(static_cast<void*>(array->data[0])); | ||
164 | } | ||
165 | template <typename T> | ||
166 | static T const& front(Eina_Array const* array) | ||
167 | { | ||
168 | return _eo_array_access_traits::front<T>(const_cast<Eina_Array*>(array)); | ||
169 | } | ||
170 | template <typename T> | ||
171 | static typename iterator<T>::type begin(Eina_Array* array) | ||
172 | { | ||
173 | return _ptr_eo_array_iterator<T>(array->data); | ||
174 | } | ||
175 | template <typename T> | ||
176 | static typename iterator<T>::type end(Eina_Array* array) | ||
177 | { | ||
178 | return _ptr_eo_array_iterator<T>(array->data + size<T>(array)); | ||
179 | } | ||
180 | template <typename T> | ||
181 | static typename const_iterator<T>::type begin(Eina_Array const* array) | ||
182 | { | ||
183 | return _eo_array_access_traits::begin<T>(const_cast<Eina_Array*>(array)); | ||
184 | } | ||
185 | template <typename T> | ||
186 | static typename const_iterator<T>::type end(Eina_Array const* array) | ||
187 | { | ||
188 | return _eo_array_access_traits::end<T>(const_cast<Eina_Array*>(array)); | ||
189 | } | ||
190 | template <typename T> | ||
191 | static std::reverse_iterator<typename iterator<T>::type> rbegin(Eina_Array* array) | ||
192 | { | ||
193 | return std::reverse_iterator<_ptr_eo_array_iterator<T> >(_eo_array_access_traits::end<T>(array)); | ||
194 | } | ||
195 | template <typename T> | ||
196 | static std::reverse_iterator<typename iterator<T>::type> rend(Eina_Array* array) | ||
197 | { | ||
198 | return std::reverse_iterator<_ptr_eo_array_iterator<T> >(_eo_array_access_traits::begin<T>(array)); | ||
199 | } | ||
200 | template <typename T> | ||
201 | static std::reverse_iterator<typename const_iterator<T>::type> rbegin(Eina_Array const* array) | ||
202 | { | ||
203 | return std::reverse_iterator<_ptr_eo_array_iterator<T>const>(_eo_array_access_traits::end<T>(array)); | ||
204 | } | ||
205 | template <typename T> | ||
206 | static std::reverse_iterator<typename const_iterator<T>::type> rend(Eina_Array const* array) | ||
207 | { | ||
208 | return std::reverse_iterator<_ptr_eo_array_iterator<T>const>(_eo_array_access_traits::begin<T>(array)); | ||
209 | } | ||
210 | template <typename T> | ||
211 | static typename const_iterator<T>::type cbegin(Eina_Array const* array) | ||
212 | { | ||
213 | return _eo_array_access_traits::begin<T>(array); | ||
214 | } | ||
215 | template <typename T> | ||
216 | static typename const_iterator<T>::type cend(Eina_Array const* array) | ||
217 | { | ||
218 | return _eo_array_access_traits::end<T>(array); | ||
219 | } | ||
220 | template <typename T> | ||
221 | static std::reverse_iterator<typename const_iterator<T>::type> crbegin(Eina_Array const* array) | ||
222 | { | ||
223 | return _eo_array_access_traits::rbegin<T>(array); | ||
224 | } | ||
225 | template <typename T> | ||
226 | static std::reverse_iterator<typename const_iterator<T>::type> crend(Eina_Array const* array) | ||
227 | { | ||
228 | return _eo_array_access_traits::rend<T>(array); | ||
229 | } | ||
230 | }; | ||
231 | |||
134 | template <typename T, typename CloneAllocator> | 232 | template <typename T, typename CloneAllocator> |
135 | class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type> | 233 | class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type> |
136 | : ptr_array<Eo, typename std::conditional | 234 | : ptr_array<Eo, typename std::conditional |
@@ -156,7 +254,9 @@ public: | |||
156 | typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */ | 254 | typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */ |
157 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */ | 255 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */ |
158 | 256 | ||
159 | explicit array(Eina_Array* handle) | 257 | typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */ |
258 | |||
259 | explicit array(native_handle_type handle) | ||
160 | : _base_type(handle) {} | 260 | : _base_type(handle) {} |
161 | array(clone_allocator_type alloc) : _base_type(alloc) {} | 261 | array(clone_allocator_type alloc) : _base_type(alloc) {} |
162 | array() {} | 262 | array() {} |
@@ -318,6 +418,7 @@ public: | |||
318 | 418 | ||
319 | using _base_type::swap; | 419 | using _base_type::swap; |
320 | using _base_type::max_size; | 420 | using _base_type::max_size; |
421 | using _base_type::release_native_handle; | ||
321 | using _base_type::native_handle; | 422 | using _base_type::native_handle; |
322 | 423 | ||
323 | friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs) | 424 | friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs) |
@@ -331,7 +432,154 @@ bool operator!=(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> co | |||
331 | { | 432 | { |
332 | return !(lhs == rhs); | 433 | return !(lhs == rhs); |
333 | } | 434 | } |
435 | |||
436 | template <typename T, typename Enable = void> | ||
437 | class range_array : range_ptr_array<T> | ||
438 | { | ||
439 | typedef range_ptr_array<T> _base_type; | ||
440 | public: | ||
441 | typedef typename _base_type::value_type value_type; | ||
442 | typedef typename _base_type::reference reference; | ||
443 | typedef typename _base_type::const_reference const_reference; | ||
444 | typedef typename _base_type::const_iterator const_iterator; | ||
445 | typedef typename _base_type::iterator iterator; | ||
446 | typedef typename _base_type::pointer pointer; | ||
447 | typedef typename _base_type::const_pointer const_pointer; | ||
448 | typedef typename _base_type::size_type size_type; | ||
449 | typedef typename _base_type::difference_type difference_type; | ||
450 | |||
451 | typedef typename _base_type::reverse_iterator reverse_iterator; | ||
452 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; | ||
453 | |||
454 | typedef typename _base_type::native_handle_type native_handle_type; | ||
455 | |||
456 | range_array& operator=(range_array&& other) = default; | ||
457 | |||
458 | using _base_type::_base_type; | ||
459 | using _base_type::size; | ||
460 | using _base_type::empty; | ||
461 | using _base_type::back; | ||
462 | using _base_type::front; | ||
463 | using _base_type::begin; | ||
464 | using _base_type::end; | ||
465 | using _base_type::rbegin; | ||
466 | using _base_type::rend; | ||
467 | using _base_type::cbegin; | ||
468 | using _base_type::cend; | ||
469 | using _base_type::crbegin; | ||
470 | using _base_type::crend; | ||
471 | using _base_type::release_native_handle; | ||
472 | using _base_type::native_handle; | ||
473 | }; | ||
474 | |||
475 | template <typename T> | ||
476 | class range_array<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type> | ||
477 | : range_ptr_array<Eo> | ||
478 | { | ||
479 | typedef range_ptr_array<Eo> _base_type; | ||
480 | typedef range_array<T> _self_type; | ||
481 | public: | ||
482 | typedef T value_type; | ||
483 | typedef value_type& reference; | ||
484 | typedef value_type const& const_reference; | ||
485 | typedef _ptr_eo_array_iterator<value_type const> const_iterator; | ||
486 | typedef _ptr_eo_array_iterator<value_type> iterator; | ||
487 | typedef value_type* pointer; | ||
488 | typedef value_type const* const_pointer; | ||
489 | typedef std::size_t size_type; | ||
490 | typedef std::ptrdiff_t difference_type; | ||
491 | |||
492 | typedef std::reverse_iterator<iterator> reverse_iterator; | ||
493 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | ||
494 | |||
495 | typedef typename _base_type::native_handle_type native_handle_type; | ||
496 | |||
497 | explicit range_array(native_handle_type handle) | ||
498 | : _base_type(handle) {} | ||
499 | range_array() {} | ||
500 | range_array(range_array<T> const& other) | ||
501 | : _base_type(other.native_handle()) | ||
502 | { | ||
503 | } | ||
504 | range_array<T>& operator=(range_array<T>const& other) | ||
505 | { | ||
506 | _base_type::_handle = other._handle; | ||
507 | return *this; | ||
508 | } | ||
509 | range_array& operator=(range_array&& other) = default; | ||
510 | range_array(range_array&& other) = default; | ||
334 | 511 | ||
512 | using _base_type::size; | ||
513 | using _base_type::empty; | ||
514 | |||
515 | reference front() | ||
516 | { | ||
517 | return _eo_array_access_traits::front<value_type>(native_handle()); | ||
518 | } | ||
519 | reference back() | ||
520 | { | ||
521 | return _eo_array_access_traits::back<value_type>(native_handle()); | ||
522 | } | ||
523 | const_reference front() const { return const_cast<_self_type*>(this)->front(); } | ||
524 | const_reference back() const { return const_cast<_self_type*>(this)->back(); } | ||
525 | iterator begin() | ||
526 | { | ||
527 | return _eo_array_access_traits::begin<value_type>(native_handle()); | ||
528 | } | ||
529 | iterator end() | ||
530 | { | ||
531 | return _eo_array_access_traits::end<value_type>(native_handle()); | ||
532 | } | ||
533 | const_iterator begin() const | ||
534 | { | ||
535 | return const_cast<_self_type*>(this)->begin(); | ||
536 | } | ||
537 | const_iterator end() const | ||
538 | { | ||
539 | return const_cast<_self_type*>(this)->end(); | ||
540 | } | ||
541 | const_iterator cbegin() const | ||
542 | { | ||
543 | return begin(); | ||
544 | } | ||
545 | const_iterator cend() const | ||
546 | { | ||
547 | return end(); | ||
548 | } | ||
549 | reverse_iterator rbegin() | ||
550 | { | ||
551 | return _eo_array_access_traits::rbegin<value_type>(native_handle()); | ||
552 | } | ||
553 | reverse_iterator rend() | ||
554 | { | ||
555 | return _eo_array_access_traits::rend<value_type>(native_handle()); | ||
556 | } | ||
557 | const_reverse_iterator rbegin() const | ||
558 | { | ||
559 | return const_cast<_self_type*>(this)->rbegin(); | ||
560 | } | ||
561 | const_reverse_iterator rend() const | ||
562 | { | ||
563 | return const_cast<_self_type*>(this)->rend(); | ||
564 | } | ||
565 | const_reverse_iterator crbegin() const | ||
566 | { | ||
567 | return rbegin(); | ||
568 | } | ||
569 | const_reverse_iterator crend() const | ||
570 | { | ||
571 | return rend(); | ||
572 | } | ||
573 | using _base_type::swap; | ||
574 | using _base_type::release_native_handle; | ||
575 | using _base_type::native_handle; | ||
576 | |||
577 | friend bool operator==(range_array<T> const& rhs, range_array<T> const& lhs) | ||
578 | { | ||
579 | return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); | ||
580 | } | ||
581 | }; | ||
582 | |||
335 | } } | 583 | } } |
336 | 584 | ||
337 | #endif | 585 | #endif |
diff --git a/src/bindings/eina_cxx/eina_clone_allocators.hh b/src/bindings/eina_cxx/eina_clone_allocators.hh index 824d6d6ce9..76ff620f98 100644 --- a/src/bindings/eina_cxx/eina_clone_allocators.hh +++ b/src/bindings/eina_cxx/eina_clone_allocators.hh | |||
@@ -154,7 +154,8 @@ struct malloc_clone_allocator | |||
154 | template <typename T> | 154 | template <typename T> |
155 | static void deallocate_clone(T const* p) | 155 | static void deallocate_clone(T const* p) |
156 | { | 156 | { |
157 | static_assert(std::is_pod<T>::value, "malloc_clone_allocator can only be used with POD types"); | 157 | static_assert(std::is_pod<T>::value || std::is_void<T>::value |
158 | , "malloc_clone_allocator can only be used with POD types"); | ||
158 | std::free(const_cast<T*>(p)); | 159 | std::free(const_cast<T*>(p)); |
159 | } | 160 | } |
160 | }; | 161 | }; |
diff --git a/src/bindings/eina_cxx/eina_function.hh b/src/bindings/eina_cxx/eina_function.hh new file mode 100644 index 0000000000..cef6da5a43 --- /dev/null +++ b/src/bindings/eina_cxx/eina_function.hh | |||
@@ -0,0 +1,26 @@ | |||
1 | #ifndef EFL_EINA_FUNCTION_HH | ||
2 | #define EFL_EINA_FUNCTION_HH | ||
3 | |||
4 | namespace efl { namespace eina { namespace _mpl { | ||
5 | |||
6 | template <typename T> | ||
7 | struct function_params; | ||
8 | |||
9 | template <typename R, typename... P> | ||
10 | struct function_params<R(*)(P...)> | ||
11 | { | ||
12 | typedef std::tuple<P...> type; | ||
13 | }; | ||
14 | |||
15 | template <typename T> | ||
16 | struct function_return; | ||
17 | |||
18 | template <typename R, typename... P> | ||
19 | struct function_return<R(*)(P...)> | ||
20 | { | ||
21 | typedef R type; | ||
22 | }; | ||
23 | |||
24 | } } } | ||
25 | |||
26 | #endif | ||
diff --git a/src/bindings/eina_cxx/eina_integer_sequence.hh b/src/bindings/eina_cxx/eina_integer_sequence.hh index 854bb8f3d0..f99c871c34 100644 --- a/src/bindings/eina_cxx/eina_integer_sequence.hh +++ b/src/bindings/eina_cxx/eina_integer_sequence.hh | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef EINA_CXX_EINA_INTEGER_SEQUENCE_HH | 1 | #ifndef EINA_CXX_EINA_INTEGER_SEQUENCE_HH |
2 | #define EINA_CXX_EINA_INTEGER_SEQUENCE_HH | 2 | #define EINA_CXX_EINA_INTEGER_SEQUENCE_HH |
3 | 3 | ||
4 | #include <cstdlib> | ||
5 | |||
4 | /** | 6 | /** |
5 | * @addtogroup Eina_Cxx_Data_Types_Group | 7 | * @addtogroup Eina_Cxx_Data_Types_Group |
6 | * | 8 | * |
diff --git a/src/bindings/eina_cxx/eina_list.hh b/src/bindings/eina_cxx/eina_list.hh index 760ada3963..1221867c7b 100644 --- a/src/bindings/eina_cxx/eina_list.hh +++ b/src/bindings/eina_cxx/eina_list.hh | |||
@@ -190,6 +190,8 @@ public: | |||
190 | typedef typename _base_type::reverse_iterator reverse_iterator; | 190 | typedef typename _base_type::reverse_iterator reverse_iterator; |
191 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; | 191 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; |
192 | 192 | ||
193 | using _base_type::native_handle_type; | ||
194 | |||
193 | list& operator=(list&& other) = default; | 195 | list& operator=(list&& other) = default; |
194 | list(list&& other) = default; | 196 | list(list&& other) = default; |
195 | list() = default; | 197 | list() = default; |
@@ -224,6 +226,7 @@ public: | |||
224 | using _base_type::max_size; | 226 | using _base_type::max_size; |
225 | using _base_type::native_handle; | 227 | using _base_type::native_handle; |
226 | using _base_type::accessor; | 228 | using _base_type::accessor; |
229 | using _base_type::release_native_handle; | ||
227 | }; | 230 | }; |
228 | 231 | ||
229 | template <typename T, typename CloneAllocator> | 232 | template <typename T, typename CloneAllocator> |
@@ -251,7 +254,9 @@ public: | |||
251 | typedef std::reverse_iterator<iterator> reverse_iterator; | 254 | typedef std::reverse_iterator<iterator> reverse_iterator; |
252 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 255 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
253 | 256 | ||
254 | explicit list(Eina_List* handle) | 257 | using _base_type::native_handle_type; |
258 | |||
259 | explicit list(typename _self_type::native_handle_type handle) | ||
255 | : _base_type(handle) {} | 260 | : _base_type(handle) {} |
256 | list(clone_allocator_type alloc) : _base_type(alloc) {} | 261 | list(clone_allocator_type alloc) : _base_type(alloc) {} |
257 | list() {} | 262 | list() {} |
@@ -295,6 +300,7 @@ public: | |||
295 | using _base_type::get_clone_allocator; | 300 | using _base_type::get_clone_allocator; |
296 | using _base_type::pop_back; | 301 | using _base_type::pop_back; |
297 | using _base_type::pop_front; | 302 | using _base_type::pop_front; |
303 | using _base_type::release_native_handle; | ||
298 | 304 | ||
299 | void push_back(const_reference w) | 305 | void push_back(const_reference w) |
300 | { | 306 | { |
@@ -464,6 +470,8 @@ public: | |||
464 | typedef typename _base_type::reverse_iterator reverse_iterator; | 470 | typedef typename _base_type::reverse_iterator reverse_iterator; |
465 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; | 471 | typedef typename _base_type::const_reverse_iterator const_reverse_iterator; |
466 | 472 | ||
473 | using _base_type::native_handle_type; | ||
474 | |||
467 | using _base_type::_base_type; | 475 | using _base_type::_base_type; |
468 | using _base_type::size; | 476 | using _base_type::size; |
469 | using _base_type::empty; | 477 | using _base_type::empty; |
@@ -501,9 +509,9 @@ public: | |||
501 | typedef std::reverse_iterator<iterator> reverse_iterator; | 509 | typedef std::reverse_iterator<iterator> reverse_iterator; |
502 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 510 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
503 | 511 | ||
504 | typedef typename _base_type::native_handle_type native_handle_type; | 512 | using _base_type::native_handle_type; |
505 | 513 | ||
506 | explicit range_list(native_handle_type handle) | 514 | explicit range_list(typename _self_type::native_handle_type handle) |
507 | : _base_type(handle) {} | 515 | : _base_type(handle) {} |
508 | range_list() {} | 516 | range_list() {} |
509 | range_list(range_list<T> const& other) | 517 | range_list(range_list<T> const& other) |
diff --git a/src/bindings/eina_cxx/eina_logical.hh b/src/bindings/eina_cxx/eina_logical.hh new file mode 100644 index 0000000000..d53d3541ad --- /dev/null +++ b/src/bindings/eina_cxx/eina_logical.hh | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef EFL_EINA_LOGICAL_HH | ||
2 | #define EFL_EINA_LOGICAL_HH | ||
3 | |||
4 | #include <type_traits> | ||
5 | |||
6 | namespace efl { namespace eina { namespace _mpl { | ||
7 | |||
8 | template <bool... N> | ||
9 | struct or_; | ||
10 | |||
11 | template <> | ||
12 | struct or_<> : std::integral_constant<bool, false> {}; | ||
13 | |||
14 | template <bool B> | ||
15 | struct or_<B> : std::integral_constant<bool, B> {}; | ||
16 | |||
17 | template <bool B1, bool B2, bool... Bs> | ||
18 | struct or_<B1, B2, Bs...> : std::integral_constant<bool, B1 || B2 || or_<Bs...>::value> {}; | ||
19 | |||
20 | template <bool... N> | ||
21 | struct and_; | ||
22 | |||
23 | template <> | ||
24 | struct and_<> : std::integral_constant<bool, true> {}; | ||
25 | |||
26 | template <bool B> | ||
27 | struct and_<B> : std::integral_constant<bool, B> {}; | ||
28 | |||
29 | template <bool B1, bool B2, bool... Bs> | ||
30 | struct and_<B1, B2, Bs...> : std::integral_constant<bool, B1 && B2 && and_<Bs...>::value> {}; | ||
31 | |||
32 | } } } | ||
33 | |||
34 | #endif | ||
diff --git a/src/bindings/eina_cxx/eina_pp.hh b/src/bindings/eina_cxx/eina_pp.hh new file mode 100644 index 0000000000..22a6a22ef7 --- /dev/null +++ b/src/bindings/eina_cxx/eina_pp.hh | |||
@@ -0,0 +1,8 @@ | |||
1 | |||
2 | #ifndef EINA_PP_HH | ||
3 | #define EINA_PP_HH | ||
4 | |||
5 | #define EINA_STRINGIZE_IMPL(x) #x | ||
6 | #define EINA_STRINGIZE(x) EINA_STRINGIZE_IMPL(x) | ||
7 | |||
8 | #endif | ||
diff --git a/src/bindings/eina_cxx/eina_ptrarray.hh b/src/bindings/eina_cxx/eina_ptrarray.hh index 2f40627ce9..f47202ebb5 100644 --- a/src/bindings/eina_cxx/eina_ptrarray.hh +++ b/src/bindings/eina_cxx/eina_ptrarray.hh | |||
@@ -295,10 +295,12 @@ struct range_ptr_array : _range_template<T, _ptr_array_access_traits> | |||
295 | typedef _range_template<T, _ptr_array_access_traits> _base_type; /**< Type for the base class. */ | 295 | typedef _range_template<T, _ptr_array_access_traits> _base_type; /**< Type for the base class. */ |
296 | typedef typename _base_type::value_type value_type; /**< The type of each element. */ | 296 | typedef typename _base_type::value_type value_type; /**< The type of each element. */ |
297 | 297 | ||
298 | typedef typename _base_type::native_handle_type native_handle_type; | ||
299 | |||
298 | /** | 300 | /** |
299 | * @brief Creates a range from a native Eina array handle. | 301 | * @brief Creates a range from a native Eina array handle. |
300 | */ | 302 | */ |
301 | range_ptr_array(Eina_Array* array) | 303 | range_ptr_array(native_handle_type array) |
302 | : _base_type(array) | 304 | : _base_type(array) |
303 | {} | 305 | {} |
304 | 306 | ||
@@ -391,7 +393,7 @@ struct _ptr_array_common_base | |||
391 | /** | 393 | /** |
392 | * @internal | 394 | * @internal |
393 | */ | 395 | */ |
394 | T* _new_clone(T const& a) | 396 | T* _new_clone(typename container_value_type<T>::type const& a) |
395 | { | 397 | { |
396 | return _get_clone_allocator().allocate_clone(a); | 398 | return _get_clone_allocator().allocate_clone(a); |
397 | } | 399 | } |
@@ -402,6 +404,7 @@ struct _ptr_array_common_base | |||
402 | struct _ptr_array_impl : CloneAllocator | 404 | struct _ptr_array_impl : CloneAllocator |
403 | { | 405 | { |
404 | _ptr_array_impl() : _array( ::eina_array_new(32u) ) {} | 406 | _ptr_array_impl() : _array( ::eina_array_new(32u) ) {} |
407 | _ptr_array_impl(Eina_Array* array) : _array(array) {} | ||
405 | _ptr_array_impl(CloneAllocator allocator) | 408 | _ptr_array_impl(CloneAllocator allocator) |
406 | : clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {} | 409 | : clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {} |
407 | 410 | ||
@@ -449,6 +452,8 @@ public: | |||
449 | 452 | ||
450 | typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr; | 453 | typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr; |
451 | 454 | ||
455 | typedef Eina_Array* native_handle_type; | ||
456 | |||
452 | /** | 457 | /** |
453 | * @brief Default constructor. Create an empty array. | 458 | * @brief Default constructor. Create an empty array. |
454 | * | 459 | * |
@@ -1210,6 +1215,13 @@ public: | |||
1210 | */ | 1215 | */ |
1211 | size_type max_size() const { return -1; } | 1216 | size_type max_size() const { return -1; } |
1212 | 1217 | ||
1218 | Eina_Array* release_native_handle() | ||
1219 | { | ||
1220 | Eina_Array* tmp = this->_impl._array; | ||
1221 | this->_impl._array = ::eina_array_new(32u); | ||
1222 | return tmp; | ||
1223 | } | ||
1224 | |||
1213 | /** | 1225 | /** |
1214 | * @brief Get a handle for the wrapped Eina_Array. | 1226 | * @brief Get a handle for the wrapped Eina_Array. |
1215 | * @return Handle for the native Eina array. | 1227 | * @return Handle for the native Eina array. |
diff --git a/src/bindings/eina_cxx/eina_ptrlist.hh b/src/bindings/eina_cxx/eina_ptrlist.hh index 2f18d10ffb..f7254b1ef2 100644 --- a/src/bindings/eina_cxx/eina_ptrlist.hh +++ b/src/bindings/eina_cxx/eina_ptrlist.hh | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <eina_eo_concrete_fwd.hh> | 9 | #include <eina_eo_concrete_fwd.hh> |
10 | #include <eina_iterator.hh> | 10 | #include <eina_iterator.hh> |
11 | #include <eina_throw.hh> | 11 | #include <eina_throw.hh> |
12 | #include <eina_range_types.hh> | ||
12 | 13 | ||
13 | #include <memory> | 14 | #include <memory> |
14 | #include <iterator> | 15 | #include <iterator> |
@@ -370,7 +371,7 @@ struct _ptr_list_common_base | |||
370 | /** | 371 | /** |
371 | * @internal | 372 | * @internal |
372 | */ | 373 | */ |
373 | T* _new_clone(T const& a) | 374 | T* _new_clone(typename container_value_type<T>::type const& a) |
374 | { | 375 | { |
375 | return _get_clone_allocator().allocate_clone(a); | 376 | return _get_clone_allocator().allocate_clone(a); |
376 | } | 377 | } |
@@ -413,11 +414,12 @@ class ptr_list : protected _ptr_list_common_base<T, CloneAllocator> | |||
413 | { | 414 | { |
414 | typedef _ptr_list_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */ | 415 | typedef _ptr_list_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */ |
415 | public: | 416 | public: |
416 | typedef T value_type; /**< The type of each element. */ | 417 | typedef typename container_value_type<T>::type |
417 | typedef T& reference; /**< Type for a reference to an element. */ | 418 | value_type; /**< The type of each element. */ |
418 | typedef T const& const_reference; /**< Type for a constant reference to an element. */ | 419 | typedef value_type& reference; /**< Type for a reference to an element. */ |
419 | typedef _ptr_list_iterator<T const> const_iterator; /**< Type for a iterator for this container. */ | 420 | typedef value_type const& const_reference; /**< Type for a constant reference to an element. */ |
420 | typedef _ptr_list_iterator<T> iterator; /**< Type for a constant iterator for this container. */ | 421 | typedef _ptr_list_iterator<value_type const> const_iterator; /**< Type for a iterator for this container. */ |
422 | typedef _ptr_list_iterator<value_type> iterator; /**< Type for a constant iterator for this container. */ | ||
421 | typedef T* pointer; /**< Type for a pointer to an element. */ | 423 | typedef T* pointer; /**< Type for a pointer to an element. */ |
422 | typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ | 424 | typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ |
423 | typedef std::size_t size_type; /**< Type for size information. */ | 425 | typedef std::size_t size_type; /**< Type for size information. */ |
@@ -427,6 +429,8 @@ public: | |||
427 | typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */ | 429 | typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */ |
428 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */ | 430 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */ |
429 | 431 | ||
432 | typedef Eina_List* native_handle_type; | ||
433 | |||
430 | typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr; | 434 | typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr; |
431 | 435 | ||
432 | /** | 436 | /** |
@@ -554,7 +558,7 @@ public: | |||
554 | */ | 558 | */ |
555 | std::size_t size() const | 559 | std::size_t size() const |
556 | { | 560 | { |
557 | return _ptr_list_access_traits::size<T>(this->_impl._list); | 561 | return _ptr_list_access_traits::size<value_type>(this->_impl._list); |
558 | } | 562 | } |
559 | 563 | ||
560 | /** | 564 | /** |
@@ -566,7 +570,7 @@ public: | |||
566 | */ | 570 | */ |
567 | bool empty() const | 571 | bool empty() const |
568 | { | 572 | { |
569 | return _ptr_list_access_traits::empty<T>(this->_impl._list); | 573 | return _ptr_list_access_traits::empty<value_type>(this->_impl._list); |
570 | } | 574 | } |
571 | 575 | ||
572 | /** | 576 | /** |
@@ -940,7 +944,7 @@ public: | |||
940 | */ | 944 | */ |
941 | value_type& back() | 945 | value_type& back() |
942 | { | 946 | { |
943 | return _ptr_list_access_traits::back<T>(this->_impl._list); | 947 | return _ptr_list_access_traits::back<value_type>(this->_impl._list); |
944 | } | 948 | } |
945 | 949 | ||
946 | /** | 950 | /** |
@@ -952,7 +956,7 @@ public: | |||
952 | */ | 956 | */ |
953 | value_type const& back() const | 957 | value_type const& back() const |
954 | { | 958 | { |
955 | return _ptr_list_access_traits::back<T>(this->_impl._list); | 959 | return _ptr_list_access_traits::back<value_type>(this->_impl._list); |
956 | } | 960 | } |
957 | 961 | ||
958 | /** | 962 | /** |
@@ -961,7 +965,7 @@ public: | |||
961 | */ | 965 | */ |
962 | value_type& front() | 966 | value_type& front() |
963 | { | 967 | { |
964 | return _ptr_list_access_traits::front<T>(this->_impl._list); | 968 | return _ptr_list_access_traits::front<value_type>(this->_impl._list); |
965 | } | 969 | } |
966 | 970 | ||
967 | /** | 971 | /** |
@@ -973,7 +977,7 @@ public: | |||
973 | */ | 977 | */ |
974 | value_type const& front() const | 978 | value_type const& front() const |
975 | { | 979 | { |
976 | return _ptr_list_access_traits::front<T>(this->_impl._list); | 980 | return _ptr_list_access_traits::front<value_type>(this->_impl._list); |
977 | } | 981 | } |
978 | 982 | ||
979 | /** | 983 | /** |
@@ -985,7 +989,7 @@ public: | |||
985 | */ | 989 | */ |
986 | const_iterator begin() const | 990 | const_iterator begin() const |
987 | { | 991 | { |
988 | return _ptr_list_access_traits::cbegin<T>(this->_impl._list); | 992 | return _ptr_list_access_traits::cbegin<value_type>(this->_impl._list); |
989 | } | 993 | } |
990 | 994 | ||
991 | /** | 995 | /** |
@@ -997,7 +1001,7 @@ public: | |||
997 | */ | 1001 | */ |
998 | const_iterator end() const | 1002 | const_iterator end() const |
999 | { | 1003 | { |
1000 | return _ptr_list_access_traits::cend<T>(this->_impl._list); | 1004 | return _ptr_list_access_traits::cend<value_type>(this->_impl._list); |
1001 | } | 1005 | } |
1002 | 1006 | ||
1003 | /** | 1007 | /** |
@@ -1010,7 +1014,7 @@ public: | |||
1010 | */ | 1014 | */ |
1011 | iterator begin() | 1015 | iterator begin() |
1012 | { | 1016 | { |
1013 | return _ptr_list_access_traits::begin<T>(this->_impl._list); | 1017 | return _ptr_list_access_traits::begin<value_type>(this->_impl._list); |
1014 | } | 1018 | } |
1015 | 1019 | ||
1016 | /** | 1020 | /** |
@@ -1026,7 +1030,7 @@ public: | |||
1026 | */ | 1030 | */ |
1027 | iterator end() | 1031 | iterator end() |
1028 | { | 1032 | { |
1029 | return _ptr_list_access_traits::end<T>(this->_impl._list); | 1033 | return _ptr_list_access_traits::end<value_type>(this->_impl._list); |
1030 | } | 1034 | } |
1031 | 1035 | ||
1032 | /** | 1036 | /** |
@@ -1038,7 +1042,7 @@ public: | |||
1038 | */ | 1042 | */ |
1039 | const_reverse_iterator rbegin() const | 1043 | const_reverse_iterator rbegin() const |
1040 | { | 1044 | { |
1041 | return _ptr_list_access_traits::rbegin<T>(this->_impl._list); | 1045 | return _ptr_list_access_traits::rbegin<value_type>(this->_impl._list); |
1042 | } | 1046 | } |
1043 | 1047 | ||
1044 | /** | 1048 | /** |
@@ -1050,7 +1054,7 @@ public: | |||
1050 | */ | 1054 | */ |
1051 | const_reverse_iterator rend() const | 1055 | const_reverse_iterator rend() const |
1052 | { | 1056 | { |
1053 | return _ptr_list_access_traits::rend<T>(this->_impl._list); | 1057 | return _ptr_list_access_traits::rend<value_type>(this->_impl._list); |
1054 | } | 1058 | } |
1055 | 1059 | ||
1056 | /** | 1060 | /** |
@@ -1063,7 +1067,7 @@ public: | |||
1063 | */ | 1067 | */ |
1064 | reverse_iterator rbegin() | 1068 | reverse_iterator rbegin() |
1065 | { | 1069 | { |
1066 | return _ptr_list_access_traits::rbegin<T>(this->_impl._list); | 1070 | return _ptr_list_access_traits::rbegin<value_type>(this->_impl._list); |
1067 | } | 1071 | } |
1068 | 1072 | ||
1069 | /** | 1073 | /** |
@@ -1080,7 +1084,7 @@ public: | |||
1080 | */ | 1084 | */ |
1081 | reverse_iterator rend() | 1085 | reverse_iterator rend() |
1082 | { | 1086 | { |
1083 | return _ptr_list_access_traits::rend<T>(this->_impl._list); | 1087 | return _ptr_list_access_traits::rend<value_type>(this->_impl._list); |
1084 | } | 1088 | } |
1085 | 1089 | ||
1086 | /** | 1090 | /** |
@@ -1093,7 +1097,7 @@ public: | |||
1093 | */ | 1097 | */ |
1094 | const_iterator cbegin() const | 1098 | const_iterator cbegin() const |
1095 | { | 1099 | { |
1096 | return _ptr_list_access_traits::cbegin<T>(this->_impl._list); | 1100 | return _ptr_list_access_traits::cbegin<value_type>(this->_impl._list); |
1097 | } | 1101 | } |
1098 | 1102 | ||
1099 | /** | 1103 | /** |
@@ -1106,7 +1110,7 @@ public: | |||
1106 | */ | 1110 | */ |
1107 | const_iterator cend() const | 1111 | const_iterator cend() const |
1108 | { | 1112 | { |
1109 | return _ptr_list_access_traits::cend<T>(this->_impl._list); | 1113 | return _ptr_list_access_traits::cend<value_type>(this->_impl._list); |
1110 | } | 1114 | } |
1111 | 1115 | ||
1112 | /** | 1116 | /** |
@@ -1119,7 +1123,7 @@ public: | |||
1119 | */ | 1123 | */ |
1120 | const_reverse_iterator crbegin() const | 1124 | const_reverse_iterator crbegin() const |
1121 | { | 1125 | { |
1122 | return _ptr_list_access_traits::crbegin<T>(this->_impl._list); | 1126 | return _ptr_list_access_traits::crbegin<value_type>(this->_impl._list); |
1123 | } | 1127 | } |
1124 | 1128 | ||
1125 | /** | 1129 | /** |
@@ -1132,7 +1136,7 @@ public: | |||
1132 | */ | 1136 | */ |
1133 | const_reverse_iterator crend() const | 1137 | const_reverse_iterator crend() const |
1134 | { | 1138 | { |
1135 | return _ptr_list_access_traits::crend<T>(this->_impl._list); | 1139 | return _ptr_list_access_traits::crend<value_type>(this->_impl._list); |
1136 | } | 1140 | } |
1137 | 1141 | ||
1138 | /** | 1142 | /** |
@@ -1143,9 +1147,9 @@ public: | |||
1143 | * the first element of the list. If the list is empty the returned | 1147 | * the first element of the list. If the list is empty the returned |
1144 | * iterator is the same as the one returned by @ref iend(). | 1148 | * iterator is the same as the one returned by @ref iend(). |
1145 | */ | 1149 | */ |
1146 | eina::iterator<T> ibegin() | 1150 | eina::iterator<value_type> ibegin() |
1147 | { | 1151 | { |
1148 | return _ptr_list_access_traits::ibegin<T>(this->_impl._list); | 1152 | return _ptr_list_access_traits::ibegin<value_type>(this->_impl._list); |
1149 | } | 1153 | } |
1150 | 1154 | ||
1151 | /** | 1155 | /** |
@@ -1160,9 +1164,9 @@ public: | |||
1160 | * @note Note that attempting to access this position causes undefined | 1164 | * @note Note that attempting to access this position causes undefined |
1161 | * behavior. | 1165 | * behavior. |
1162 | */ | 1166 | */ |
1163 | eina::iterator<T> iend() | 1167 | eina::iterator<value_type> iend() |
1164 | { | 1168 | { |
1165 | return _ptr_list_access_traits::iend<T>(this->_impl._list); | 1169 | return _ptr_list_access_traits::iend<value_type>(this->_impl._list); |
1166 | } | 1170 | } |
1167 | 1171 | ||
1168 | /** | 1172 | /** |
@@ -1174,7 +1178,7 @@ public: | |||
1174 | */ | 1178 | */ |
1175 | eina::iterator<T const> ibegin() const | 1179 | eina::iterator<T const> ibegin() const |
1176 | { | 1180 | { |
1177 | return _ptr_list_access_traits::ibegin<T>(this->_impl._list); | 1181 | return _ptr_list_access_traits::ibegin<value_type>(this->_impl._list); |
1178 | } | 1182 | } |
1179 | 1183 | ||
1180 | /** | 1184 | /** |
@@ -1186,7 +1190,7 @@ public: | |||
1186 | */ | 1190 | */ |
1187 | eina::iterator<T const> iend() const | 1191 | eina::iterator<T const> iend() const |
1188 | { | 1192 | { |
1189 | return _ptr_list_access_traits::iend<T>(this->_impl._list); | 1193 | return _ptr_list_access_traits::iend<value_type>(this->_impl._list); |
1190 | } | 1194 | } |
1191 | 1195 | ||
1192 | /** | 1196 | /** |
@@ -1199,7 +1203,7 @@ public: | |||
1199 | */ | 1203 | */ |
1200 | eina::iterator<T const> cibegin() const | 1204 | eina::iterator<T const> cibegin() const |
1201 | { | 1205 | { |
1202 | return _ptr_list_access_traits::cibegin<T>(this->_impl._list); | 1206 | return _ptr_list_access_traits::cibegin<value_type>(this->_impl._list); |
1203 | } | 1207 | } |
1204 | 1208 | ||
1205 | /** | 1209 | /** |
@@ -1212,7 +1216,7 @@ public: | |||
1212 | */ | 1216 | */ |
1213 | eina::iterator<T const> ciend() const | 1217 | eina::iterator<T const> ciend() const |
1214 | { | 1218 | { |
1215 | return _ptr_list_access_traits::ciend<T>(this->_impl._list); | 1219 | return _ptr_list_access_traits::ciend<value_type>(this->_impl._list); |
1216 | } | 1220 | } |
1217 | 1221 | ||
1218 | /** | 1222 | /** |
@@ -1230,6 +1234,13 @@ public: | |||
1230 | */ | 1234 | */ |
1231 | size_type max_size() const { return -1; } | 1235 | size_type max_size() const { return -1; } |
1232 | 1236 | ||
1237 | Eina_List* release_native_handle() | ||
1238 | { | ||
1239 | Eina_List* tmp = this->_impl._list; | ||
1240 | this->_impl._list = 0; | ||
1241 | return tmp; | ||
1242 | } | ||
1243 | |||
1233 | /** | 1244 | /** |
1234 | * @brief Get a handle for the wrapped @c Eina_List. | 1245 | * @brief Get a handle for the wrapped @c Eina_List. |
1235 | * @return Handle for the native Eina list. | 1246 | * @return Handle for the native Eina list. |
@@ -1275,9 +1286,9 @@ public: | |||
1275 | * @brief Get a @ref eina::accessor for the list. | 1286 | * @brief Get a @ref eina::accessor for the list. |
1276 | * @return <tt>eina::accessor</tt> to the list. | 1287 | * @return <tt>eina::accessor</tt> to the list. |
1277 | */ | 1288 | */ |
1278 | eina::accessor<T> accessor() | 1289 | eina::accessor<value_type> accessor() |
1279 | { | 1290 | { |
1280 | return eina::accessor<T>(eina_list_accessor_new(this->_impl._list)); | 1291 | return eina::accessor<value_type>(eina_list_accessor_new(this->_impl._list)); |
1281 | } | 1292 | } |
1282 | }; | 1293 | }; |
1283 | 1294 | ||
diff --git a/src/bindings/eina_cxx/eina_range_types.hh b/src/bindings/eina_cxx/eina_range_types.hh index 844e2ef4cc..313ca05cd9 100644 --- a/src/bindings/eina_cxx/eina_range_types.hh +++ b/src/bindings/eina_cxx/eina_range_types.hh | |||
@@ -22,11 +22,12 @@ namespace efl { namespace eina { | |||
22 | template <typename T, typename Traits> | 22 | template <typename T, typename Traits> |
23 | struct _const_range_template | 23 | struct _const_range_template |
24 | { | 24 | { |
25 | typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */ | 25 | typedef typename container_value_type<T>::type |
26 | typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */ | 26 | value_type; /**< The type of each element. */ |
27 | typedef T value_type; /**< The type of each element. */ | 27 | typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */ |
28 | typedef T& reference; /**< Type for a reference to an element. */ | 28 | typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */ |
29 | typedef T const& const_reference; /**< Type for a constant reference to an element. */ | 29 | typedef value_type& reference; /**< Type for a reference to an element. */ |
30 | typedef value_type const& const_reference; /**< Type for a constant reference to an element. */ | ||
30 | typedef T* pointer; /**< Type for a pointer to an element. */ | 31 | typedef T* pointer; /**< Type for a pointer to an element. */ |
31 | typedef T const* const_pointer; /**< Type for a constant pointer to an element. */ | 32 | typedef T const* const_pointer; /**< Type for a constant pointer to an element. */ |
32 | typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */ | 33 | typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */ |
@@ -50,6 +51,17 @@ struct _const_range_template | |||
50 | : _handle(handle) {} | 51 | : _handle(handle) {} |
51 | 52 | ||
52 | /** | 53 | /** |
54 | * @brief Release the handle of the native Eina container. | ||
55 | * @return Handle for the native Eina container. | ||
56 | */ | ||
57 | native_handle_type release_native_handle() | ||
58 | { | ||
59 | auto h = _handle; | ||
60 |