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
This commit is contained in:
Felipe Magno de Almeida 2014-09-01 15:08:49 -03:00
parent 1a3cb45f1c
commit a3db1dddd3
141 changed files with 20312 additions and 135 deletions

1
.gitignore vendored
View File

@ -35,6 +35,7 @@ tags
*.eo.legacy.h *.eo.legacy.h
*.eo.hh *.eo.hh
*.eo.impl.hh *.eo.impl.hh
*.eo.js.cc
*.eo.lua *.eo.lua
*.luac *.luac
.dir-locals.el .dir-locals.el

View File

@ -172,6 +172,14 @@ if HAVE_ELUA
pkgconfig_DATA += pc/elua.pc pkgconfig_DATA += pc/elua.pc
endif endif
if HAVE_JS
pkgconfig_DATA += \
pc/eolian-js.pc \
pc/efl-js.pc \
pc/eo-js.pc \
pc/eina-js.pc
endif
if BUILD_ENGINE_SOFTWARE_X11 if BUILD_ENGINE_SOFTWARE_X11
pkgconfig_DATA += pc/evas-software-x11.pc pkgconfig_DATA += pc/evas-software-x11.pc
endif endif

View File

@ -1051,6 +1051,191 @@ EFL_EVAL_PKGS([EINA_CXX])
EFL_LIB_END([Eina_Cxx]) EFL_LIB_END([Eina_Cxx])
#### End of Eina CXX #### End of Eina CXX
AC_ARG_WITH([js],
[AS_HELP_STRING([--with-js=@<:@nodejs/libv8/libuv/none@:>@],[enable JavaScript bindings using nodejs or libv8/libuv as build dependencies. The libuv option implies libv8. @<:@default=none@:>@])],
[want_js="${withval}"], [want_js="none"])
EFLJS_CXXFLAGS=""
AC_LANG_PUSH([C++])
case "$want_js" in
nodejs)
AC_CHECK_HEADERS([node/v8.h nodejs/deps/v8/v8.h nodejs/deps/v8/include/v8.h nodejs/src/v8.h v8.h],
[
v8_header=AC_header
v8_header_define=AS_TR_CPP([HAVE_]AC_header)
EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -D$v8_header_define"
break
]
[AC_MSG_ERROR([Could not find v8 include headers from nodejs.])])
AC_CHECK_HEADERS([node/node.h nodejs/deps/node/node.h nodejs/deps/node/include/node.h nodejs/src/node.h node.h],
[
node_header_define=AS_TR_CPP([HAVE_]AC_header)
EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -D$node_header_define"
break
]
[AC_MSG_ERROR([Could not find node include headers from nodejs.])])
AC_CHECK_HEADERS([node/uv.h nodejs/deps/uv/uv.h nodejs/deps/uv/include/uv.h nodejs/src/uv.h uv.h],
[
uv_header_define=AS_TR_CPP([HAVE_]AC_header)
EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -D$uv_header_define"
break
]
[AC_MSG_ERROR([Could not find uv include headers from nodejs.])])
;;
libv8)
AC_CHECK_HEADERS([v8.h],
[
v8_header=AC_header
break
]
[AC_MSG_ERROR([Could not find v8 include headers from libv8.])])
;;
libuv)
AC_CHECK_HEADERS([v8.h],
[
v8_header=AC_header
break
]
[AC_MSG_ERROR([Could not find v8 include headers from libv8.])])
AC_CHECK_HEADERS([uv.h],
[break]
[AC_MSG_ERROR([Could not find uv include headers from libuv.])])
;;
none)
;;
*) AC_MSG_ERROR([Invalid javascript dependency (${want_js}): must be none, nodejs, libv8 or libuv]) ;;
esac
have_v8_global="no"
have_v8_create_params="no"
if test "$want_js" != "none" ; then
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include "$v8_header"
]],
[[
v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = nullptr;
]])
],
[
AC_DEFINE(HAVE_V8_CREATE_PARAMS, 1, [Define to 1 if you must pass create_params explicitly.])
have_v8_create_params="yes"
AC_MSG_NOTICE([checking for v8::Isolate::CreateParams... yes])
],
[
AC_MSG_NOTICE([checking for v8::Isolate::CreateParams... no])
])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include "$v8_header"
#include <type_traits>
]],
[[
static_assert((std::is_same< ::v8::Global<void>, ::v8::UniquePersistent<void>>::value), "");
]])
],
[
AC_DEFINE(HAVE_V8_GLOBAL, 1, [Define to 1 if you must pass create_params explicitly.])
have_v8_global="yes"
AC_MSG_NOTICE([checking for v8::Global<T> class... yes])
],
[
AC_MSG_NOTICE([checking for v8::Global<T> class... no])
])
fi
AM_CONDITIONAL([HAVE_V8_CREATE_PARAMS], [test "x${have_v8_create_params}" = "xyes"])
AM_CONDITIONAL([HAVE_V8_GLOBAL], [test "x${have_v8_global}" = "xyes"])
AC_SUBST([HAVE_V8_CREATE_PARAMS])
AC_SUBST([HAVE_V8_GLOBAL])
AC_LANG_POP([C++])
AM_CONDITIONAL([HAVE_NODEJS], [test "x${want_js}" = "xnodejs"])
AC_DEFINE_IF([HAVE_NODEJS], [test "x${want_js}" = "xnodejs"],
[1], [Using NodeJS])
AC_SUBST([want_js])
AC_SUBST([HAVE_NODEJS])
have_js="no"
if test "x${want_js}" != "xnone" ; then
have_js="yes"
fi
AM_CONDITIONAL([HAVE_JS], [test "x${have_js}" = "xyes"])
AC_DEFINE_IF([HAVE_JS], [test "x${have_js}" = "xyes"], [1], [Compiling bindings for JavaScript])
AC_SUBST([HAVE_JS])
AM_CONDITIONAL([HAVE_LIBUV], [test "x${want_js}" = "xnodejs" -o "x${want_js}" = "xlibuv"])
AC_DEFINE_IF([HAVE_LIBUV], [test "x${want_js}" = "xnodejs" -o "x${want_js}" = "xlibuv"],
[1], [Compiling libuv event loop integration])
AC_SUBST([HAVE_LIBUV])
# For efljspack mime handling
AM_CONDITIONAL([HAVE_XDG_DATA_HOME], [test "x${XDG_DATA_HOME}" != "x"])
AM_COND_IF([HAVE_XDG_DATA_HOME], [AC_SUBST([XDG_DATA_HOME])], [AC_SUBST([XDG_DATA_HOME], "$HOME/.local/share")])
#### Eina JS
EFL_LIB_START_OPTIONAL([Eina_Js], [test "x${have_js}" = "xyes"])
EFL_INTERNAL_DEPEND_PKG([EINA_JS], [Eina])
EFL_INTERNAL_DEPEND_PKG([EINA_JS], [Eo])
EFL_ADD_CFLAGS([EINA_JS], [${EFL_PTHREAD_CFLAGS}])
EFL_EVAL_PKGS([EINA_JS])
EFL_LIB_END_OPTIONAL([Eina_Js])
#### End of Eina JS
#### Ecore JS
EFL_LIB_START_OPTIONAL([Ecore_Js], [test "x${have_js}" = "xyes"])
EFL_INTERNAL_DEPEND_PKG([ECORE_JS], [ecore])
EFL_INTERNAL_DEPEND_PKG([ECORE_JS], [ecore_file])
EFL_ADD_CFLAGS([ECORE_JS], [${EFL_PTHREAD_CFLAGS}])
EFL_EVAL_PKGS([ECORE_JS])
EFL_LIB_END_OPTIONAL([Ecore_Js])
#### End of Ecore JS
#### Eio JS
EFL_LIB_START_OPTIONAL([Eio_Js], [test "x${have_js}" = "xyes"])
EFL_INTERNAL_DEPEND_PKG([EIO_JS], [eio])
EFL_ADD_CFLAGS([EIO_JS], [${EFL_PTHREAD_CFLAGS}])
EFL_EVAL_PKGS([EIO_JS])
EFL_LIB_END_OPTIONAL([Eio_Js])
#### End of Eio JS
#### Ethumb JS
EFL_LIB_START_OPTIONAL([Ethumb_Js], [test "x${have_js}" = "xyes"])
EFL_INTERNAL_DEPEND_PKG([ETHUMB_JS], [ethumb])
EFL_INTERNAL_DEPEND_PKG([ETHUMB_JS], [ethumb_client])
EFL_ADD_CFLAGS([ETHUMB_JS], [${EFL_PTHREAD_CFLAGS}])
EFL_EVAL_PKGS([ETHUMB_JS])
EFL_LIB_END_OPTIONAL([Ethumb_Js])
#### End of Ethumb JS
#### Eldbus JS
EFL_LIB_START_OPTIONAL([Eldbus_Js], [test "x${have_js}" = "xyes"])
EFL_INTERNAL_DEPEND_PKG([ELDBUS_JS], [eldbus])
EFL_ADD_CFLAGS([ELDBUS_JS], [${EFL_PTHREAD_CFLAGS}])
EFL_EVAL_PKGS([ELDBUS_JS])
EFL_LIB_END_OPTIONAL([Eldbus_Js])
#### End of Eldbus JS
#### Eo JS
EFL_LIB_START_OPTIONAL([Eo_Js], [test "x${have_js}" = "xyes"])
EFL_INTERNAL_DEPEND_PKG([EO_JS], [eina])
EFL_ADD_CFLAGS([EO_JS], [${EFL_PTHREAD_CFLAGS}])
EFL_EVAL_PKGS([EO_JS])
EFL_LIB_END_OPTIONAL([Eo_Js])
#### End of Eo JS
#### Eo #### Eo
EFL_LIB_START([Eo]) EFL_LIB_START([Eo])
@ -1244,6 +1429,15 @@ EFL_INTERNAL_DEPEND_PKG([EOLIAN], [eina])
EFL_LIB_END([Eolian]) EFL_LIB_END([Eolian])
#### End of Eolian #### End of Eolian
EFL_LIB_START_OPTIONAL([Eolian_Js], [test "${have_js}" = "yes"])
EFL_INTERNAL_DEPEND_PKG([EOLIAN_JS], [eina])
EFL_INTERNAL_DEPEND_PKG([EOLIAN_JS], [eolian])
EFL_LIB_END_OPTIONAL([Eolian_Js])
#### End of Eolian
EFL_LIB_START([Eolian_Cxx]) EFL_LIB_START([Eolian_Cxx])
### Default values ### Default values
@ -2322,6 +2516,17 @@ AC_ARG_ENABLE([g-main-loop],
fi fi
], ],
[want_g_main_loop="no"]) [want_g_main_loop="no"])
AC_ARG_ENABLE([libuv],
[AS_HELP_STRING([--enable-libuv],[enable ecore_main_loop based on libuv. @<:@default=disabled@:>@])],
[
if test "x${enableval}" = "xyes" ; then
want_libuv="yes"
CFOPT_WARNING="xyes"
else
want_libuv="no"
fi
],
[want_libuv="no"])
AC_ARG_ENABLE([gstreamer], AC_ARG_ENABLE([gstreamer],
[AS_HELP_STRING([--enable-gstreamer],[enable gstreamer 0.10 support. @<:@default=disabled@:>@])], [AS_HELP_STRING([--enable-gstreamer],[enable gstreamer 0.10 support. @<:@default=disabled@:>@])],
@ -2410,6 +2615,7 @@ EFL_OPTIONAL_DEPEND_PKG([ECORE], [${want_systemd}], [SYSTEMD], [libsystemd])
EFL_ADD_FEATURE([ECORE], [systemd-daemon], [${want_systemd}]) EFL_ADD_FEATURE([ECORE], [systemd-daemon], [${want_systemd}])
EFL_ADD_FEATURE([ECORE], [glib]) EFL_ADD_FEATURE([ECORE], [glib])
EFL_ADD_FEATURE([ECORE], [g-main-loop]) EFL_ADD_FEATURE([ECORE], [g-main-loop])
EFL_ADD_FEATURE([ECORE], [libuv])
want_glib_integration_always=no want_glib_integration_always=no
if test "x${with_glib}" = "xalways" ; then if test "x${with_glib}" = "xalways" ; then
@ -2419,6 +2625,9 @@ fi
if test "x${want_g_main_loop}" = "xyes" ; then if test "x${want_g_main_loop}" = "xyes" ; then
AC_DEFINE([USE_G_MAIN_LOOP], [1], [Use g_main_loop in ecore]) AC_DEFINE([USE_G_MAIN_LOOP], [1], [Use g_main_loop in ecore])
if test "x${want_js}" = "xnodejs" -o "x${want_js}" = "xlibuv" ; then
AC_MSG_ERROR([Can't define glib and libuv integration together])
fi
fi fi
# not EFL_OPTIONAL_DEPEND_PKG() because it's only used for ecore examples # not EFL_OPTIONAL_DEPEND_PKG() because it's only used for ecore examples
@ -4007,7 +4216,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [emile])
ECORE_EVAS_MODULE([extn], [${want_ecore_evas_extn}]) ECORE_EVAS_MODULE([extn], [${want_ecore_evas_extn}])
ECORE_EVAS_MODULE([ews], [yes]) ECORE_EVAS_MODULE([ews], [yes])
ECORE_EVAS_MODULE([fb], [${want_fb}]) ECORE_EVAS_MODULE([fb], [${want_fb}])
ECORE_EVAS_MODULE([drm], [${want_drm}], ECORE_EVAS_MODULE([drm], [${want_drm}],
[EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [${want_drm}], [ecore-drm])]) [EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [${want_drm}], [ecore-drm])])
ECORE_EVAS_MODULE([gl-drm], [${want_gl_drm}], ECORE_EVAS_MODULE([gl-drm], [${want_gl_drm}],
[EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [${want_gl_drm}], [ecore-drm])]) [EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_EVAS], [${want_gl_drm}], [ecore-drm])])
@ -4677,6 +4886,63 @@ EFL_ADD_LIBS([ELOCATION], [-lm])
EFL_LIB_END([Elocation]) EFL_LIB_END([Elocation])
#### End of Elocation #### End of Elocation
#### Efl_Js
EFL_LIB_START_OPTIONAL([Efl_Js], [test "x${have_js}" = "xyes"])
### Default values
### Additional options to configure
### Checks for programs
### Checks for libraries
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eina])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eo])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eet])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore_Evas])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore_Con])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ecore_Audio])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Efl])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Evas])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Edje])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Emotion])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eldbus])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Emile])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Ethumb_Client])
EFL_INTERNAL_DEPEND_PKG([EFL_JS], [Eio])
AM_COND_IF([HAVE_NODEJS], [], [ EFL_ADD_LIBS([EFL_JS], [-lv8]) ])
EFL_EVAL_PKGS([EFL_JS])
AM_COND_IF([HAVE_NODEJS], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_NODEJS"], [])
AM_COND_IF([HAVE_LIBUV], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_LIBUV"], [])
AM_COND_IF([HAVE_JS], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_JS"], [])
AM_COND_IF([HAVE_V8_CREATE_PARAMS], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_V8_CREATE_PARAMS"], [])
AM_COND_IF([HAVE_V8_GLOBAL], [EFLJS_CXXFLAGS="$EFLJS_CXXFLAGS -DHAVE_V8_GLOBAL"], [])
AC_SUBST([EFLJS_CXXFLAGS])
### Checks for header files
### Checks for types
### Checks for structures
### Checks for compiler characteristics
### Checks for linker characteristics
### Checks for library functions
### Check availability
EFL_LIB_END_OPTIONAL([Efl_Js])
#### End of Efl_Js
### Add Wayland server library if test is enabled ### Add Wayland server library if test is enabled
if test "x${want_tests}" = "xyes" -a "x${want_wayland}" = "xyes"; then if test "x${want_tests}" = "xyes" -a "x${want_wayland}" = "xyes"; then
EFL_DEPEND_PKG([ECORE_WAYLAND_SRV], [WAYLAND], [wayland-server >= 1.8.0]) EFL_DEPEND_PKG([ECORE_WAYLAND_SRV], [WAYLAND], [wayland-server >= 1.8.0])
@ -4809,6 +5075,10 @@ pc/eo.pc
pc/eo-cxx.pc pc/eo-cxx.pc
pc/eolian.pc pc/eolian.pc
pc/eolian-cxx.pc pc/eolian-cxx.pc
pc/eina-js.pc
pc/efl-js.pc
pc/eolian-js.pc
pc/eo-js.pc
pc/efl.pc pc/efl.pc
pc/efl-cxx.pc pc/efl-cxx.pc
pc/evas-fb.pc pc/evas-fb.pc
@ -4991,6 +5261,8 @@ echo " Cryptography..: ${build_crypto}"
echo " X11...........: ${with_x11}" echo " X11...........: ${with_x11}"
echo " OpenGL........: ${with_opengl}" echo " OpenGL........: ${with_opengl}"
echo " C++11.........: ${have_cxx11}" echo " C++11.........: ${have_cxx11}"
echo " JavaScript....: ${want_js}"
echo " JavaScript flg: $EINA_JS_LIBS"
echo "Eina............: yes (${features_eina} unwind=$have_unwind)" echo "Eina............: yes (${features_eina} unwind=$have_unwind)"
echo "Eo..............: yes (${features_eo})" echo "Eo..............: yes (${features_eo})"
echo "Eolian..........: yes (${features_eolian})" echo "Eolian..........: yes (${features_eolian})"
@ -5052,6 +5324,7 @@ echo " CPPFLAGS......: $CPPFLAGS"
echo " CFLAGS........: $CFLAGS" echo " CFLAGS........: $CFLAGS"
echo " CXXFLAGS......: $CXXFLAGS" echo " CXXFLAGS......: $CXXFLAGS"
echo " LDFLAGS.......: $LDFLAGS" echo " LDFLAGS.......: $LDFLAGS"
echo " EFLJS_CXXFLAGS: $EFLJS_CXXFLAGS"
if test "x${with_binary_edje_cc}" != "x"; then if test "x${with_binary_edje_cc}" != "x"; then
echo " edje_cc.......: ${with_binary_edje_cc}" echo " edje_cc.......: ${with_binary_edje_cc}"

3
pc/.gitignore vendored
View File

@ -28,6 +28,7 @@
/efreet.pc /efreet.pc
/eina.pc /eina.pc
/eina-cxx.pc /eina-cxx.pc
/eina-js.pc
/eet-cxx.pc /eet-cxx.pc
/eio.pc /eio.pc
/eio-cxx.pc /eio-cxx.pc
@ -36,6 +37,7 @@
/embryo.pc /embryo.pc
/emotion.pc /emotion.pc
/eo.pc /eo.pc
/eo-js.pc
/ephysics.pc /ephysics.pc
/escape.pc /escape.pc
/ethumb.pc /ethumb.pc
@ -57,6 +59,7 @@
/evil.pc /evil.pc
/eolian.pc /eolian.pc
/eolian-cxx.pc /eolian-cxx.pc
/eolian-js.pc
/eo-cxx.pc /eo-cxx.pc
/evas-cxx.pc /evas-cxx.pc
/ecore-cxx.pc /ecore-cxx.pc

15
pc/efl-js.pc.in Normal file
View File

@ -0,0 +1,15 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
datarootdir=@datarootdir@
datadir=@datadir@
want_js=@want_js@
Name: EFL JavaScript
Description: JavaScript C++ helpers for data structures
Version: @PACKAGE_VERSION@
Requires.private: @requirements_pc_eina@
Libs.private: @requirements_libs_eina@
Libs: -L${libdir} -lefl_js
Cflags: -I${includedir}/efl-js-@VMAJ@ @EFLJS_CXXFLAGS@

14
pc/eina-js.pc.in Normal file
View File

@ -0,0 +1,14 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
datarootdir=@datarootdir@
datadir=@datadir@
want_js=@want_js@
Name: Eina JavaScript
Description: JavaScript C++ helpers for data structures
Version: @PACKAGE_VERSION@
Requires.private: @requirements_pc_eina@
Libs.private: @requirements_libs_eina@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eina-@VMAJ@ -I${includedir}/eina-js-@VMAJ@

15
pc/eo-js.pc.in Normal file
View File

@ -0,0 +1,15 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
datarootdir=@datarootdir@
datadir=@datadir@
eoincludedir=@datadir@/eolian/include
eolian_flags=-I${eoincludedir}/eo-@VMAJ@
Name: Eo JavaScript
Description: JavaScript C++ helpers for bindings for EFL's generic object system.
Version: @PACKAGE_VERSION@
Requires.private: @requirements_pc_eo@
Libs.private: @requirements_libs_eo@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eo-@VMAJ@ -I${includedir}/eo-js-@VMAJ@

14
pc/eolian-js.pc.in Normal file
View File

@ -0,0 +1,14 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
datarootdir=@datarootdir@
datadir=@datadir@
Name: Eolian-JS
Description: EFL's JavaScript bindings generator.
Version: @VERSION@
Require.private: @requirements_pc_eolian@
Libs: -L${libdir}
Libs.private: @requirements_libs_eolian@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eolian-js-@VMAJ@

View File

@ -13,4 +13,4 @@ Requires.private: @requirements_pc_evas@
Version: @VERSION@ Version: @VERSION@
Libs: -L${libdir} -levas Libs: -L${libdir} -levas
Libs.private: @requirements_libs_evas@ Libs.private: @requirements_libs_evas@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/evas-@VMAJ@ Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/evas-@VMAJ@ -I${includedir}/evas-@VMAJ@/canvas

View File

@ -15,6 +15,7 @@ check_PROGRAMS =
TESTS = TESTS =
EXTRA_DIST = EXTRA_DIST =
GENERATED_JS_BINDINGS =
EFL_INSTALL_EXEC_HOOK= EFL_INSTALL_EXEC_HOOK=
@ -76,6 +77,21 @@ include Makefile_Eio_Cxx.am
include Makefile_Elua.am include Makefile_Elua.am
include Makefile_Elocation.am include Makefile_Elocation.am
if HAVE_JS
AM_V_CP = $(am__v_CP_@AM_V@)
am__v_CP_ = $(am__v_CP_@AM_DEFAULT_V@)
am__v_CP_0 = @echo " CP " $@;
CP = cp
if EFL_ENABLE_TESTS
if HAVE_NODEJS
AM_TESTS_ENVIRONMENT = NODE_PATH='$(abs_builddir)/lib/efl_js:$(abs_builddir)/tests/eolian_js:$(abs_builddir)/tests/efl_js'; export NODE_PATH;
endif
endif
endif
include Makefile_Eolian_Js.am
include Makefile_Efl_Js.am
.PHONY: benchmark examples .PHONY: benchmark examples
BENCHMARK_SUBDIRS = \ BENCHMARK_SUBDIRS = \

View File

@ -271,3 +271,13 @@ installed_ecoreluadir = $(datadir)/elua/modules/ecore
nodist_installed_ecorelua_DATA = $(generated_ecore_lua_all) nodist_installed_ecorelua_DATA = $(generated_ecore_lua_all)
endif endif
if HAVE_JS
generated_ecore_js_bindings = $(ecore_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_ecore_js_bindings)
GENERATED_JS_BINDINGS += $(generated_ecore_js_bindings)
endif

View File

@ -104,4 +104,15 @@ nodist_installed_ecoreaudiolua_DATA = $(generated_ecore_audio_lua_all)
endif endif
if HAVE_JS
generated_ecore_audio_js_bindings = $(ecore_audio_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_ecore_audio_js_bindings)
GENERATED_JS_BINDINGS += $(generated_ecore_audio_js_bindings)
endif endif
endif

View File

@ -143,3 +143,13 @@ installed_ecoreconluadir = $(datadir)/elua/modules/ecore_con
nodist_installed_ecoreconlua_DATA = $(generated_ecore_con_lua_all) nodist_installed_ecoreconlua_DATA = $(generated_ecore_con_lua_all)
endif endif
if HAVE_JS
generated_ecore_con_js_bindings = $(ecore_con_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_ecore_con_js_bindings)
GENERATED_JS_BINDINGS += $(generated_ecore_con_js_bindings)
endif

19
src/Makefile_Ecore_Js.am Normal file
View File

@ -0,0 +1,19 @@
### Library
if HAVE_JS
installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@
dist_installed_ecorejsheaders_DATA = \
bindings/js/ecore_js/Ecore_Js.hh \
bindings/js/ecore_js/ecore_js_init.hh \
bindings/js/ecore_js/ecore_js_mainloop.hh \
bindings/js/ecore_js/ecore_js_timer.hh \
bindings/js/ecore_js/ecore_js_event.hh \
bindings/js/ecore_js/ecore_js_job.hh \
bindings/js/ecore_js/ecore_js_idle.hh \
bindings/js/ecore_js/ecore_js_animator.hh \
bindings/js/ecore_js/ecore_js_poller.hh \
bindings/js/ecore_js/ecore_js_throttle.hh \
bindings/js/ecore_js/ecore_js_file.hh
endif

View File

@ -130,7 +130,7 @@ if HAVE_WIN32
USE_EDJE_BIN_LIBS = -L$(top_builddir)/src/lib/evil @USE_EDJE_LIBS@ USE_EDJE_BIN_LIBS = -L$(top_builddir)/src/lib/evil @USE_EDJE_LIBS@
else else
USE_EDJE_BIN_LIBS = @USE_EDJE_LIBS@ USE_EDJE_BIN_LIBS = @USE_EDJE_LIBS@
endif endif
bin_PROGRAMS += \ bin_PROGRAMS += \
bin/edje/edje_cc \ bin/edje/edje_cc \
@ -334,3 +334,13 @@ installed_edjeluadir = $(datadir)/elua/modules/edje
nodist_installed_edjelua_DATA = $(generated_edje_lua_all) nodist_installed_edjelua_DATA = $(generated_edje_lua_all)
endif endif
if HAVE_JS
generated_edje_js_bindings = $(edje_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_edje_js_bindings)
GENERATED_JS_BINDINGS += $(generated_edje_js_bindings)
endif

View File

@ -80,6 +80,16 @@ nodist_installed_efllua_DATA = $(generated_efl_lua_all)
endif endif
if HAVE_JS
generated_efl_js_bindings = $(efl_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_efl_js_bindings)
GENERATED_JS_BINDINGS += $(generated_efl_js_bindings)
endif
### Binary ### Binary
bin_PROGRAMS += \ bin_PROGRAMS += \

333
src/Makefile_Efl_Js.am Normal file
View File

@ -0,0 +1,333 @@
if HAVE_JS
if HAVE_NODEJS
noinst_lib_LTLIBRARIES = lib/efl_js/libefl_node_js.la
noinst_libdir = $(libdir)/efl_js
$(top_builddir)/src/lib/efl_js/efl.node: lib/efl_js/libefl_node_js.la
$(AM_V_CP)$(CP) $(top_builddir)/src/lib/efl_js/.libs/libefl_node_js.so $(top_builddir)/src/lib/efl_js/efl.node
eflnodedir = $(libdir)/node_modules
eflnode_DATA = $(top_builddir)/src/lib/efl_js/efl.node
CLEANFILES += ${eflnodedir_DATA}
EXTRA_DIST += ${eflnodedir_DATA}
efljsmimedir = @XDG_DATA_HOME@/mime/packages
efljsmime_DATA = bin/efl_js/efljslaunch.xml
efljsdesktopdir = @XDG_DATA_HOME@/applications
efljsdesktop_DATA = bin/efl_js/efljslaunch.desktop
bin_SCRIPTS += \
bin/efl_js/efljslaunch \
bin/efl_js/efljspack
else
bin_PROGRAMS += bin/efl_js/eflv8js
bin_efl_js_eflv8js_SOURCES = \
bin/efl_js/launcher_main.cc
bin_efl_js_eflv8js_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bindings/js/efl_js \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
@CHECK_CFLAGS@ \
@EINA_CXX_CFLAGS@ \
@EO_CXX_CFLAGS@ \
@EMILE_CFLAGS@ \
@ECORE_CFLAGS@ \
@EET_CFLAGS@ \
@EO_CFLAGS@ \
@EFL_JS_CFLAGS@ \
@EINA_JS_CFLAGS@ \
@EO_JS_CFLAGS@
bin_efl_js_eflv8js_LDFLAGS = \
-lv8 \
@USE_EFL_JS_INTERNAL_LIBS@
bin_efl_js_eflv8js_LDADD = \
@USE_EFL_JS_LIBS@
endif
bindings/js/efl_js/eolian_js_bindings.cc: $(GENERATED_JS_BINDINGS)
@echo @ECHO_E@ "#ifdef HAVE_CONFIG_H" > $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include \"config.h\"" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Efl.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Efl_Config.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Ecore.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Eo.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Ecore_Con.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Ecore_Audio.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Evas.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Edje.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Ecore_Con_Eet.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@echo @ECHO_E@ "#include <Emotion.h>\n" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
@for i in $(GENERATED_JS_BINDINGS); do echo "#include <$$i>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc; done
CLEANFILES += bindings/js/efl_js/eolian_js_bindings.cc
## Install Ecore-JS headers
installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@
dist_installed_ecorejsheaders_DATA = \
bindings/js/ecore_js/Ecore_Js.hh
## Install Eio-JS headers
installed_eiojsheadersdir = $(includedir)/eio-js-@VMAJ@
dist_installed_eiojsheaders_DATA = \
bindings/js/eio_js/Eio_Js.hh
## Install Ethumb-JS headers
installed_ethumbjsheadersdir = $(includedir)/ethumb-js-@VMAJ@
dist_installed_ethumbjsheaders_DATA = \
bindings/js/ethumb_js/Ethumb_Js.hh
## Install Eldbus-JS headers
installed_eldbusjsheadersdir = $(includedir)/eldbus-js-@VMAJ@
dist_installed_eldbusjsheaders_DATA = \
bindings/js/eldbus_js/Eldbus_Js.hh
## Install Eo-JS headers
installed_eojsmainheadersdir = $(includedir)/eo-js-@VMAJ@
dist_installed_eojsmainheaders_DATA = \
bindings/js/eo_js/eo_js_call_function.hh \
bindings/js/eo_js/eo_js_constructor.hh \
bindings/js/eo_js/eo_js_direction.hh \
bindings/js/eo_js/eo_js_event.hh \
bindings/js/eo_js/eo_js_namespace.hh \
bindings/js/eo_js/eo_js_struct.hh \
bindings/js/eo_js/eo_js_construct_from_eo.hh \
bindings/js/eo_js/Eo_Js.hh
## Install Eina-JS headers
installed_einajsheadersdir = $(includedir)/eina-js-@VMAJ@
dist_installed_einajsheaders_DATA = \
bindings/js/eina_js/Eina_Js.hh \
bindings/js/eina_js/eina_js_accessor.hh \
bindings/js/eina_js/eina_js_array.hh \
bindings/js/eina_js/eina_js_compatibility.hh \
bindings/js/eina_js/eina_js_container.hh \
bindings/js/eina_js/eina_js_error.hh \
bindings/js/eina_js/eina_js_get_value_from_c.hh \
bindings/js/eina_js/eina_js_get_value.hh \
bindings/js/eina_js/eina_js_iterator.hh \
bindings/js/eina_js/eina_js_list.hh \
bindings/js/eina_js/eina_js_log.hh \
bindings/js/eina_js/eina_js_node.hh \
bindings/js/eina_js/eina_js_value.hh
installed_efljsheadersdir = $(includedir)/efl-js-@VMAJ@
dist_installed_efljsheaders_DATA = \
bindings/js/efl_js/Efl_Js.hh
lib_LTLIBRARIES += lib/efl_js/libefl_js.la
lib_efl_js_libefl_js_la_SOURCES = \
bindings/js/eina_js/eina_js_container.cc \
bindings/js/eina_js/eina_js_value.cc \
bindings/js/eina_js/eina_js_error.cc \
bindings/js/eina_js/eina_js_accessor.cc \
bindings/js/eina_js/eina_js_log.cc \
bindings/js/eina_js/eina_js_iterator.cc \
bindings/js/eina_js/eina_js_compatibility.cc \
bindings/js/ecore_js/ecore_js_init.cc \
bindings/js/ecore_js/ecore_js_mainloop.cc \
bindings/js/ecore_js/ecore_js_timer.cc \
bindings/js/ecore_js/ecore_js_event.cc \
bindings/js/ecore_js/ecore_js_job.cc \
bindings/js/ecore_js/ecore_js_idle.cc \
bindings/js/ecore_js/ecore_js_animator.cc \
bindings/js/ecore_js/ecore_js_poller.cc \
bindings/js/ecore_js/ecore_js_throttle.cc \
bindings/js/eldbus_js/eldbus_js_core.cc \
bindings/js/eldbus_js/eldbus_js_connection.cc \
bindings/js/eldbus_js/eldbus_js_message.cc \
bindings/js/eldbus_js/eldbus_js_object_mapper.cc \
bindings/js/eio_js/eio_js.cc \
bindings/js/ethumb_js/ethumb_js_client.cc
nodist_lib_efl_js_libefl_js_la_SOURCES = \
bindings/js/efl_js/eolian_js_bindings.cc
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)
lib_efl_js_libefl_js_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/efl \
-I$(top_builddir)/src/lib/efl/interfaces/ \
-I$(top_builddir)/src/lib/evas/canvas/ \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/ecore_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
-I$(top_srcdir)/src/bindings/js/eldbus_js \
-I$(top_srcdir)/src/bindings/js/eio_js \
-I$(top_srcdir)/src/bindings/js/ethumb_js \
@EFL_JS_CFLAGS@ \
@EO_JS_CFLAGS@ \
@ECORE_CXX_CFLAGS@ \
@EO_CXX_CFLAGS@ \
@ECORE_JS_CFLAGS@ \
@EINA_JS_CFLAGS@ \
@ELDBUS_JS_CFLAGS@ \
@EIO_JS_CFLAGS@ \
@ETHUMB_JS_CFLAGS@ \
@EINA_CXX_CFLAGS@
lib_efl_js_libefl_js_la_LIBADD = @EFL_JS_LIBS@
lib_efl_js_libefl_js_la_DEPENDENCIES = @EFL_JS_INTERNAL_LIBS@
lib_efl_js_libefl_js_la_LIBTOOLFLAGS = --tag=disable-static
lib_efl_js_libefl_js_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
if HAVE_NODEJS
lib_efl_js_libefl_node_js_la_SOURCES = \
bindings/js/efl_js/efl_js.cc
lib_efl_js_libefl_node_js_la_CPPFLAGS = $(lib_efl_js_libefl_js_la_CPPFLAGS)
lib_efl_js_libefl_node_js_la_LIBADD = @USE_EFL_JS_LIBS@
lib_efl_js_libefl_node_js_la_DEPENDENCIES = @USE_EFL_JS_INTERNAL_LIBS@
lib_efl_js_libefl_node_js_la_LIBTOOLFLAGS = --tag=disable-static
lib_efl_js_libefl_node_js_la_LDFLAGS =
else
lib_efl_js_libefl_js_la_SOURCES += \
bindings/js/efl_js/efl_js.cc
endif
if EFL_ENABLE_TESTS
SUITE_RUNNER_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl_js\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/efl_js\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl_js\" \
@CHECK_CFLAGS@ \
@EFL_JS_CFLAGS@ \
@EINA_CXX_CFLAGS@ \
@EO_CXX_CFLAGS@ \
@EO_CFLAGS@ \
@ECORE_CFLAGS@ \
@ECORE_CXX_CFLAGS@ \
@ECORE_JS_CFLAGS@ \
@EINA_JS_CFLAGS@
if HAVE_NODEJS
TESTS += 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/ethumb_js_suite.js \
tests/efl_js/eio_js_suite.js \
tests/efl_js/benchmark_js_suite.js
check_LTLIBRARIES += tests/efl_js/libbenchmark_object.la
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
tests/efl_js/benchmark_object.node: tests/efl_js/libbenchmark_object.la
$(AM_V_CP)$(CP) $(top_builddir)/src/tests/efl_js/.libs/libbenchmark_object.so $(top_builddir)/src/tests/efl_js/benchmark_object.node
tests/efl_js/benchmark_js_suite.js: $(top_builddir)/src/lib/efl_js/efl.node tests/efl_js/benchmark_object.node
tests_efl_js_libbenchmark_object_la_SOURCES = tests/efl_js/benchmark_object_impl.cc
tests_efl_js_libbenchmark_object_la_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bindings/js/efl_js \
-I$(top_builddir)/src/tests/efl_js \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl_js\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/efl_js\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/efl_js\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl_js\" \
@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ \
@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \
@EO_JS_CFLAGS@ @EO_CXX_CFLAGS@
tests_efl_js_libbenchmark_object_la_LIBADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_libbenchmark_object_la_LDFLAGS = -rpath $(abs_top_builddir)/tests/efl_js @EFL_LTLIBRARY_FLAGS@
tests_efl_js_libbenchmark_object_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_libbenchmark_object_la_LIBTOOLFLAGS = --tag=disable-static
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
else
check_PROGRAMS += \
tests/efl_js/eina_js_suite \
tests/efl_js/eina_js_containers_suite \
tests/efl_js/ecore_js_suite \
tests/efl_js/eldbus_js_suite \
tests/efl_js/ethumb_js_suite \
tests/efl_js/eio_js_suite \
tests/efl_js/benchmark_js_suite
TESTS += tests/efl_js/eina_js_suite \
tests/efl_js/ecore_js_suite \
tests/efl_js/eldbus_js_suite \
tests/efl_js/ethumb_js_suite \
tests/efl_js/eio_js_suite \
tests/efl_js/benchmark_js_suite
tests_efl_js_eina_js_suite_SOURCES = \
tests/efl_js/eina_js_suite.cc
tests_efl_js_eina_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_eina_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_eina_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_eina_js_containers_suite_SOURCES = \
tests/efl_js/eina_js_containers_suite.cc
tests_efl_js_eina_js_containers_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_eina_js_containers_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_eina_js_containers_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_ecore_js_suite_SOURCES = \
tests/efl_js/ecore_js_suite.cc
tests_efl_js_ecore_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_ecore_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_ecore_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_eldbus_js_suite_SOURCES = \
tests/efl_js/eldbus_js_suite.cc
tests_efl_js_eldbus_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_eldbus_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_eldbus_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_ethumb_js_suite_SOURCES = \
tests/efl_js/ethumb_js_suite.cc
tests_efl_js_ethumb_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_ethumb_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_ethumb_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_eio_js_suite_SOURCES = \
tests/efl_js/eio_js_suite.cc
tests_efl_js_eio_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_eio_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_eio_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_efl_js_benchmark_js_suite_SOURCES = \
tests/efl_js/benchmark_js_suite.cc
tests_efl_js_benchmark_js_suite_CPPFLAGS = $(SUITE_RUNNER_CPPFLAGS)
tests_efl_js_benchmark_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_efl_js_benchmark_js_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
endif
endif
endif

View File

@ -14,6 +14,7 @@ bindings/eina_cxx/eina_clone_allocators.hh \
bindings/eina_cxx/eina_error.hh \ bindings/eina_cxx/eina_error.hh \
bindings/eina_cxx/eina_eo_concrete_fwd.hh \ bindings/eina_cxx/eina_eo_concrete_fwd.hh \
bindings/eina_cxx/eina_fold.hh \ bindings/eina_cxx/eina_fold.hh \
bindings/eina_cxx/eina_function.hh \
bindings/eina_cxx/eina_inarray.hh \ bindings/eina_cxx/eina_inarray.hh \
bindings/eina_cxx/eina_inlist.hh \ bindings/eina_cxx/eina_inlist.hh \
bindings/eina_cxx/eina_integer_sequence.hh \ bindings/eina_cxx/eina_integer_sequence.hh \
@ -21,7 +22,9 @@ bindings/eina_cxx/eina_iterator.hh \
bindings/eina_cxx/eina_lists_auxiliary.hh \ bindings/eina_cxx/eina_lists_auxiliary.hh \
bindings/eina_cxx/eina_list.hh \ bindings/eina_cxx/eina_list.hh \
bindings/eina_cxx/eina_log.hh \ bindings/eina_cxx/eina_log.hh \
bindings/eina_cxx/eina_logical.hh \
bindings/eina_cxx/eina_optional.hh \ bindings/eina_cxx/eina_optional.hh \
bindings/eina_cxx/eina_pp.hh \
bindings/eina_cxx/eina_ptrarray.hh \ bindings/eina_cxx/eina_ptrarray.hh \
bindings/eina_cxx/eina_ptrlist.hh \ bindings/eina_cxx/eina_ptrlist.hh \
bindings/eina_cxx/eina_range_types.hh \ bindings/eina_cxx/eina_range_types.hh \
@ -31,6 +34,7 @@ bindings/eina_cxx/eina_string_view.hh \
bindings/eina_cxx/eina_thread.hh \ bindings/eina_cxx/eina_thread.hh \
bindings/eina_cxx/eina_throw.hh \ bindings/eina_cxx/eina_throw.hh \
bindings/eina_cxx/eina_tuple.hh \ bindings/eina_cxx/eina_tuple.hh \
bindings/eina_cxx/eina_tuple_c.hh \
bindings/eina_cxx/eina_tuple_unwrap.hh \ bindings/eina_cxx/eina_tuple_unwrap.hh \
bindings/eina_cxx/eina_type_traits.hh \ bindings/eina_cxx/eina_type_traits.hh \
bindings/eina_cxx/eina_value.hh bindings/eina_cxx/eina_value.hh

View File

@ -347,3 +347,14 @@ installed_emotionluadir = $(datadir)/elua/modules/emotion
nodist_installed_emotionlua_DATA = $(generated_emotion_lua_all) nodist_installed_emotionlua_DATA = $(generated_emotion_lua_all)
endif endif
# TODO: gives undefined reference to emotion_object_class_get()
if HAVE_JS
generated_emotion_js_bindings = $(emotion_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_emotion_js_bindings)
GENERATED_JS_BINDINGS += $(generated_emotion_js_bindings)
endif

View File

@ -197,3 +197,13 @@ endif
EXTRA_DIST += tests/eo/eunit_tests.h lib/eo/eo_ptr_indirection.x EXTRA_DIST += tests/eo/eunit_tests.h lib/eo/eo_ptr_indirection.x
if HAVE_JS
generated_eo_js_bindings = $(eo_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_eo_js_bindings)
GENERATED_JS_BINDINGS += $(generated_eo_js_bindings)
endif

123
src/Makefile_Eolian_Js.am Normal file
View File

@ -0,0 +1,123 @@
if HAVE_JS
### Binary
bin_PROGRAMS += bin/eolian_js/eolian_js
bin_eolian_js_eolian_js_SOURCES = \
bin/eolian_js/main.cc
bin_eolian_js_eolian_js_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bin/eolian_js \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
@EOLIAN_JS_CFLAGS@ \
@EINA_CXX_CFLAGS@ \
@EOLIAN_CXX_CFLAGS@
bin_eolian_js_eolian_js_LDADD = @USE_EO_LIBS@ @USE_EOLIAN_LIBS@
bin_eolian_js_eolian_js_DEPENDENCIES = @USE_EO_INTERNAL_LIBS@ @USE_EOLIAN_INTERNAL_LIBS@
include Makefile_Eolian_Js_Helper.am
### Unit tests
if EFL_ENABLE_TESTS
if HAVE_NODEJS
TESTS += tests/eolian_js/eolian_js_suite.js
check_LTLIBRARIES += tests/eolian_js/libeolian_js_suite.la
tests/eolian_js/eolian_js_suite.js: tests/eolian_js/eolian_js_suite_mod.node
tests/eolian_js/eolian_js_suite_mod.node: tests/eolian_js/libeolian_js_suite.la
$(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
tests_eolian_js_libeolian_js_suite_la_SOURCES = \
tests/eolian_js/eolian_js_suite.cc \
tests/eolian_js/eolian_js_test_eolian_js_binding.cc \
tests/eolian_js/eolian_js_test_constructor_method_impl.c \
tests/eolian_js/eolian_js_test_test_object_impl.c
tests_eolian_js_libeolian_js_suite_la_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bin/eolian_js \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
-I$(top_builddir)/src/tests/eolian_js \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_js\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_js\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/eolian_js\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_js\" \
@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ \
@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \
@EO_JS_CFLAGS@ @EO_CXX_CFLAGS@
tests_eolian_js_libeolian_js_suite_la_LIBADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@
tests_eolian_js_libeolian_js_suite_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_EFL_JS_INTERNAL_LIBS@
tests_eolian_js_libeolian_js_suite_la_CFLAGS = $(tests_eolian_js_libeolian_js_suite_la_CXXFLAGS)
tests_eolian_js_libeolian_js_suite_la_LIBTOOLFLAGS = --tag=disable-static
tests_eolian_js_libeolian_js_suite_la_LDFLAGS = -rpath $(abs_top_builddir)/tests/eolian_js @EFL_LTLIBRARY_FLAGS@
# if compiler_o_lo == yes, lo, otherwise $(OBJEXT)
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
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
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
CLEANFILES += \
tests/eolian_js/constructor_method_class.eo.js.cc \
tests/eolian_js/constructor_method_class.eo.c \
tests/eolian_js/constructor_method_class.eo.h \
tests/eolian_js/test_object.eo.js.cc \
tests/eolian_js/test_object.eo.c \
tests/eolian_js/test_object.eo.h
else
check_PROGRAMS += tests/eolian_js/eolian_js_suite
TESTS += tests/eolian_js/eolian_js_suite
tests_eolian_js_eolian_js_suite_SOURCES = \
tests/eolian_js/eolian_js_suite.cc \
tests/eolian_js/eolian_js_test_eolian_js_binding.cc \
tests/eolian_js/eolian_js_test_constructor_method_impl.c \
tests/eolian_js/eolian_js_test_test_object_impl.c
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
tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_constructor_method_impl.$(OBJEXT): tests/eolian_js/constructor_method_class.eo.c
tests/eolian_js/tests_eolian_js_eolian_js_suite-eolian_js_test_test_object_impl.$(OBJEXT): tests/eolian_js/test_object.eo.c
CLEANFILES += \
tests/eolian_js/constructor_method_class.eo.js.cc \
tests/eolian_js/constructor_method_class.eo.c \
tests/eolian_js/constructor_method_class.eo.h \
tests/eolian_js/test_object.eo.js.cc \
tests/eolian_js/test_object.eo.c \
tests/eolian_js/test_object.eo.h
tests_eolian_js_eolian_js_suite_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bin/eolian_js \
-I$(top_srcdir)/src/bindings/js/eina_js \
-I$(top_srcdir)/src/bindings/js/eo_js \
-I$(top_builddir)/src/tests/eolian_js \
-I$(top_srcdir)/src/tests/efl_js \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_js\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_js\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/eolian_js\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_js\" \
@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_JS_CFLAGS@ @EO_JS_CFLAGS@ @EFL_JS_CFLAGS@ \
@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ @EINA_CXX_CFLAGS@ \
@EO_JS_CFLAGS@ @EO_CXX_CFLAGS@ @EFL_JS_CFLAGS@
tests_eolian_js_eolian_js_suite_LDADD = \
@CHECK_LIBS@ @USE_EO_LIBS@ @USE_EINA_LIBS@ @USE_EOLIAN_LIBS@ @USE_EFL_JS_LIBS@ @USE_EVAS_LIBS@ @USE_EFL_JS_LIBS@
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@
endif
endif
endif

View File

@ -0,0 +1,18 @@
#if HAVE_EOLIAN_JS
#EOLIAN_JS = @eolian_js@
#_EOLIAN_JS_DEP = @eolian_js@
#else
EOLIAN_JS = EFL_RUN_IN_TREE=1 $(top_builddir)/src/bin/eolian_js/eolian_js${EXEEXT}
_EOLIAN_JS_DEP = bin/eolian_js/eolian_js${EXEEXT}
#endif
AM_V_EOLJS = $(am__v_EOLJS_@AM_V@)
am__v_EOLJS_ = $(am__v_EOLJS_@AM_DEFAULT_V@)
am__v_EOLJS_0 = @echo " EOLJS " $@;
SUFFIXES += .eo.js.cc
%.eo.js.cc: %.eo $(_EOLIAN_JS_DEP)
$(AM_V_EOLJS)$(EOLIAN_JS) $(EOLIAN_FLAGS) -o $@ $<
CLEANFILES += $(BUILT_SOURCES)

View File

@ -2221,3 +2221,13 @@ $(NULL)
installed_evasfiltersdir = $(datadir)/evas/filters/lua installed_evasfiltersdir = $(datadir)/evas/filters/lua
dist_installed_evasfilters_DATA = $(evas_filters_lua) dist_installed_evasfilters_DATA = $(evas_filters_lua)
if HAVE_JS
generated_evas_js_bindings = $(evas_eolian_files:%.eo=%.eo.js.cc)
CLEANFILES += $(generated_evas_js_bindings)
GENERATED_JS_BINDINGS += $(generated_evas_js_bindings)
endif

139
src/bin/efl_js/efljslaunch Executable file
View File

@ -0,0 +1,139 @@
#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"
// Core node modules
var path = require('path');
var os = require('os');
var zlib = require('zlib');
var child_process = require('child_process');
// 3rd party modules
var fs = require('fs-extra');
var getopt = require('node-getopt');
var tar = require('tar');
function make_error_cb(message)
{
return function(e) {
console.error("Error %s: %s", message, e);
process.exit(1);
};
}
function remove_files(options)
{
if (options.verbose)
console.log("Removing temporary files");
fs.remove(options.project_folder);
}
function run_project(options)
{
if (options.verbose)
console.log("Running the project");
var current_dir = process.cwd();
process.chdir(options.project_root);
var proc = child_process.fork(options.metadata.Entry);
proc.on('exit', function(code){
if (options.verbose)
console.log('Child exited with code %s', code);
process.chdir(current_dir);
if (!options.keep)
remove_files(options);
});
}
function unpack_project_data(options)
{
if (options.verbose)
console.log("Unpacking project sources and assets");
var datafile = path.join(options.project_folder, "data.tar.gz");
var project_root = path.join(options.project_folder, "root");
options.project_root = project_root;
var input = fs.createReadStream(datafile);
var unzipper = zlib.createGunzip();
var extractor = tar.Extract({path: project_root, strip: 0});
input.on('error', make_error_cb("reading package data file."));
extractor.on('error', make_error_cb("unpacking package data file."));
if (!("only-extract" in options))
extractor.on('end', function(){ run_project(options); });
input.pipe(unzipper)
unzipper.pipe(extractor);
}
function read_metadata(options)
{
if (options.verbose)
console.log("Reading project metadata");
var project_folder = options.project_folder;
var metadata = JSON.parse(fs.readFileSync(path.join(project_folder, "meta.json")));
if (options.verbose)
console.log("Project: %s\nVersion: %s\nEntry point: %s", metadata.Name, metadata.Version, metadata.Entry);
if ("only-dump" in options)
process.exit(0);
options.metadata = metadata;
unpack_project_data(options);
}
function extract(filename, options)
{
if (options.verbose)
console.log("Extracting ", filename, "with options ", options);
var project_id = path.basename(filename, ".epk");
var project_folder = path.join(options['temp-dir'], project_id);
options.project_folder = project_folder;
options.project_id = project_id;
var input = fs.createReadStream(filename);
var extractor = tar.Extract({path: options['temp-dir'], strip: 0});
input.on('error', make_error_cb("reading package file."));
extractor.on('error', make_error_cb("unpacking package file."));
extractor.on('end', function(){ read_metadata(options); });
input.pipe(extractor);
}
function main() {
var options = getopt.create([
['d', 'only-dump', 'Only dump information about the package'],
['e', 'only-extract', 'Only extract the package, do not run'],
['h', 'help', 'Display this help'],
['k', 'keep', 'Do not remove the files after exiting'],
['t', 'temp-dir=ARG', 'Temporary dir to extract files'],
['v', 'verbose', 'Print information messages'],
]).bindHelp().parseSystem();
var filename = options.argv[0];
if (filename === undefined)
{
console.error("Must provide a package file.");
process.exit(1);
}
if (!('temp-dir' in options.options))
{
options.options["temp-dir"] = path.join(os.tmpdir(), "efljs_apps");
if (options.verbose)
console.log("Defaulting temp dir to ", options.options["temp-dir"]);
}
extract(filename, options.options);
}
main();

View File

@ -0,0 +1,7 @@
[Desktop Entry]
Name=EFL JS package launcher
Exec=efljslaunch %f
Type=Application
Categories=EFL
Terminal=true
MimeType=application/x-efljspackage;

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-efljspackage">
<comment xml:lang="en">EFL JS package</comment>
<glob pattern="*.epk"/>
</mime-type>
</mime-info>

251
src/bin/efl_js/efljspack Executable file
View File

@ -0,0 +1,251 @@
#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"
var zlib = require('zlib');
var path = require('path');
// external dependencies
var fs = require('fs-extra');
var tar = require('tar');
var fstream = require('fstream');
var getopt = require('node-getopt');
/*
* Packing a project.
* The efljs package has a similar format to debian packages. It is a
* tar package containing two files:
*
* meta.txt: Metadata information about this package.
* data.tar.gz: Gzipped data, with the project tree ready to be decompressed
* and run by the package launcher.
*
* During the build, a out/ directory is created in the project root to
* store the package and temporary files.
*/
// Creates a stub .project file and packs it.
function pack_single(sourcepath, options)
{
if (options.verbose)
console.log("Creating project file for single file app", sourcepath);
var dir_name = path.dirname(fs.realpathSync(sourcepath));
var filename = path.basename(sourcepath);
var projectRegex = /^(.*).js$/g;
var project_name = projectRegex.exec(filename)[1];
if (!validade_project_name(project_name))
{
console.error("Invalid project name. Must start with a letter.");
process.exit(0);
}
var project_filename = path.join(dir_name, project_name + ".project");
var fd = fs.openSync(project_filename, 'w');
var jsonData = {};
jsonData["Name"] = project_name;
jsonData["Entry"] = filename;
jsonData["Sources"] = [[filename, '.']];
jsonData["Version"] = "0.1";
fs.writeSync(fd, JSON.stringify(jsonData, null, 2));
fs.closeSync(fd);
pack_project(project_filename, options);
}
function generate_build_info(configuration, project_file, options)
{
build_info = {};
// project == project_dir
// /out == build_dir
// /data == data_dir
// /name-version == package_dir
build_info.package_id = configuration.Name + "-" + configuration.Version;
build_info.project_dir = path.dirname(project_file);
build_info.build_dir = path.join(build_info.project_dir, "out");
build_info.data_dir = path.join(build_info.build_dir, "data");
build_info.package_dir = path.join(build_info.build_dir, build_info.package_id);
build_info.data_file = path.join(build_info.package_dir, "data.tar.gz");
build_info.package_file = path.join(build_info.build_dir, build_info.package_id + ".epk")
build_info.metadata_file = path.join(build_info.package_dir, "meta.json");
if (options.verbose)
{
console.log("Project id: ", build_info.package_id);
console.log("Project source dir: ", build_info.project_dir);
console.log("Project build dir: ", build_info.build_dir);
console.log("Project data dir:", build_info.data_dir);
console.log("Project package dir:", build_info.package_dir);
}
return build_info;
}
// Project names must start with a letter and contain only
// letters, digits and underscores.
function validade_project_name(name)
{
return (/^[a-zA-Z][\w-]*$/).test(name)
}
function pack_project(project_file, options)
{
if (options.verbose)
console.log("Packing project from project file ", project_file);
var configuration = JSON.parse(fs.readFileSync(project_file));
if (!validade_project_name(configuration.Name))
{
console.error("Invalid project name. Must start with a letter.");
process.exit(0);
}
var build_info = generate_build_info(configuration, project_file, options);
try
{
fs.mkdirSync(build_info.build_dir);
fs.mkdirSync(build_info.data_dir);
fs.mkdirSync(build_info.package_dir);
}
catch (e)
{
console.warn("Warning: Project output directories not empty.");
}
create_metadata_file(configuration, build_info, options);
// If not explicitly named on configuration, add the entire directory
if (!('Sources' in configuration))
{
generate_source_list(configuration, build_info.project_dir, options);
}
create_project_tree(configuration.Sources, build_info, options);
pack_data_dir(build_info, options);
}
function create_project_tree(sources, build_info, options)
{
for (var i = sources.length - 1; i >= 0; i--) {
if (options.verbose)
console.log("Adding file ", sources[i], "to package.");
var source_file = path.join(build_info.project_dir, sources[i][0]);
var destination_dir = path.join(build_info.data_dir, sources[i][1]);
var destination_filename = path.basename(source_file);
var destination_file = path.join(destination_dir, destination_filename);
fs.copySync(source_file, destination_file);
};
}
function generate_source_list(configuration, project_dir, options)
{
console.log("Generating source list for project dir", build_info.project_dir);
var dir_entries = fs.readdirSync(project_dir);
var sources = [];
dir_entries.forEach(function(entry){
if (entry == "out")
return;
sources.push([entry, "."]);
});
configuration.Sources = sources;
}
function create_metadata_file(configuration, build_info, options)
{
if (options.verbose)
console.log("Creating metadata file", build_info.metadata_file);
var metadata = {};
metadata.Name = configuration.Name;
metadata.Entry = configuration.Entry;
metadata.Version = configuration.Version;
var output = fs.createWriteStream(build_info.metadata_file);
output.write(JSON.stringify(metadata, null, 2));
output.close();
}
function pack_data_dir(build_info, options)
{
if (options.verbose)
console.log("Packing data...");
pack_directory(build_info.data_dir, build_info.data_file, true, true, function(){
if (options.verbose)
console.log("Packed data");
pack_final_package(build_info, options);
});
}
function pack_final_package(build_info, options)
{
if (options.verbose)
console.log("Creating package ", build_info.package_file);
pack_directory(build_info.package_dir, build_info.package_file, false, false, function(){
if (options.verbose)
console.log("Created project package.");
});
}
function pack_directory(source_dir, target_file, strip_base_dir, should_gzip, callback)
{
var output = fs.createWriteStream(target_file);
var packer = tar.Pack({fromBase: strip_base_dir == true});
if (callback != undefined)
output.on('close', callback);
var reader = fstream.Reader({path: source_dir, type: "Directory"});
var destStr = reader.pipe(packer);
if(should_gzip)
destStr = destStr.pipe(zlib.createGzip());
destStr.pipe(output);
}
function main()
{
var options = getopt.create([
['v', 'verbose', 'Explain what is being done'],
['h', 'help', 'Display this help']
]).bindHelp().parseSystem();
filename = options.argv[0];
if (typeof filename === 'undefined')
{
console.error('Must provide a valid js or project file.');
process.exit(1);
}
if (endsWith(filename, ".js"))
{
pack_single(filename, options.options);
}
else if (endsWith(filename, ".project"))
{
pack_project(filename, options.options);
}
}
main();
//// Helper functions
function endsWith(str, suffix)
{
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

View File

@ -0,0 +1,156 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cerrno>
#include <Eo_Js.hh>
#include <Eina.hh>
#include <Eo.hh>
// #include <efl_js.hh>
using namespace std;
using namespace v8;
const char PATH_SEPARATOR =
#ifdef _WIN32
'\\';
#else
'/';
#endif
static std::string get_file_contents(const char *filename) {
std::ifstream in(filename, std::ios::in);
if (in) {
std::ostringstream contents;
contents << in.rdbuf();
in.close();
return contents.str();
} else {
throw(errno);
}
}
static std::string get_filename(std::string path)
{
int beginIdx = path.rfind(PATH_SEPARATOR);
return path.substr(beginIdx + 1);
}
static void show_usage(std::string name)
{
std::cerr << "Usage: " << get_filename(name) << " <option(s)> [SOURCE]\n" << std::endl
<< "Options:" << std::endl
<< "\t-h, --help\t\t Show this help message" << std::endl;
}
/*
* Basic console.log implementation with space-separated values,
* no substitution
*/
void Log(const FunctionCallbackInfo<Value>& args)
{
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
for (int i=0; i < args.Length(); i++)
{
if (i != 0)
std::cout << " ";
String::Utf8Value string(args[i]);
std::cout << *string;
}
std::cout << std::endl;
args.GetReturnValue().Set(v8::Null(isolate));
}
int main(int argc, char* argv[])
{
std::string script_source;
char *filename = 0;
for (int i=1; i < argc; i++)
{
if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0))
{
show_usage(argv[0]);
return 0;
}
else
{
filename = argv[i];
}
}
if (!filename)
{
std::cerr << "Error: No source provided." << std::endl;
show_usage(argv[0]);
return 1;
}
try
{
script_source = get_file_contents(filename);
} catch (int errno)
{
perror("Error: ");
return 1;
}
efl::eina::js::compatibility_initialize();
v8::V8::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), true);
v8::Isolate* isolate = efl::eina::js::compatibility_isolate_new();
{
Isolate::Scope isolate_scope(isolate);
HandleScope handleScope(isolate);
Local<Context> context = Context::New(isolate, NULL);
Context::Scope context_scope(context);
context->Enter();
// Setup the console and log
Local<Object> console = Object::New(isolate);
Local<FunctionTemplate> log = FunctionTemplate::New(isolate, Log);
console->Set(String::NewFromUtf8(isolate, "log"), log->GetFunction());
Local<Object> global = context->Global();
global->Set(String::NewFromUtf8(isolate, "console"), console);
// Set up the efl exports; Needed to enter the context before this
// due to creating Objects instead of Objects Templates
// WIP: Commented out due to potential missing v8 platform implementation issues
// Local<Object> efl_exports = Object::New(isolate);
// global->Set(String::NewFromUtf8(isolate, "efl"), efl_exports);
// efl_js::init(efl_exports);
// And now the user's script
Local<String> source = String::NewFromUtf8(isolate, script_source.c_str());
Local<Script> script = Script::Compile(source);
TryCatch tryCatch(isolate);
Local<Value> result = script->Run();
if (result.IsEmpty())
{
Local<Value> exception = tryCatch.Exception();
String::Utf8Value exception_str(exception);
printf("Exception: %s\n", *exception_str);
}
}
V8::Dispose();
return 0;
}

1
src/bin/eolian_js/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/eolian_js

View File

@ -0,0 +1,139 @@
#ifndef EOLIAN_KLASS_HH
#define EOLIAN_KLASS_HH
#include <Eina.hh>
#include <eolian/js/domain.hh>
#include <ostream>
inline std::string name(Eolian_Class const* klass)
{
return ::eolian_class_name_get(klass);
}
inline std::string full_name(Eolian_Class const* klass)
{
return ::eolian_class_full_name_get(klass);
}
inline std::string full_name_transformed(Eolian_Class const* klass)
{
auto r = full_name(klass);
std::replace(r.begin(), r.end(), '.', '_');
return r;
}
inline std::size_t namespace_size(Eolian_Class const* klass)
{
std::size_t size = 0;
for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass))
, last; first != last; ++first)
++size;
return size;
}
inline std::string type_class_name(Eolian_Type const* tp)
{
if (tp)
{
Eolian_Type_Type tpt = ::eolian_type_type_get(tp);
if (tpt == EOLIAN_TYPE_POINTER || tpt == EOLIAN_TYPE_ALIAS || tpt == EOLIAN_TYPE_REGULAR)
{
return type_class_name(::eolian_type_base_type_get(tp));
}
else if(tpt == EOLIAN_TYPE_CLASS)
{
Eolian_Class const* klass = ::eolian_type_class_get(tp);
if (klass)
{
Eina_Stringshare* klass_name = ::eolian_class_full_name_get(klass);
if (!klass_name)
throw std::runtime_error("Could not get Eo class name");
return klass_name;
} // TODO: else should throw std::runtime_error("Could not get Eo class");
}
else if(tpt == EOLIAN_TYPE_STRUCT)
{
auto struct_type_full_name = ::eolian_type_full_name_get(tp);
if (!struct_type_full_name)
throw std::runtime_error("Could not get struct name");
return struct_type_full_name;
}
}
return "";
}
inline void print_lower_case_namespace(Eolian_Class const* klass, std::ostream& os)
{
std::vector<std::string> namespace_;
for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass))
, last; first != last; ++first)
namespace_.push_back(&*first);
for(auto first = namespace_.begin(), last = namespace_.end()
; first != last; ++first)
{
std::string lower(*first);
std::transform(lower.begin(), lower.end(), lower.begin(), tolower);
os << lower;
if(std::next(first) != last) os << "::";
}
}
inline void print_eo_class(Eolian_Class const* klass, std::ostream& os)
{
assert(klass != 0);
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print_eo_class";
auto toupper = [] (unsigned char c) { return std::toupper(c); };
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print_eo_class";
std::vector<std::string> namespace_;
for(efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass))
, last; first != last; ++first)
namespace_.push_back(&*first);
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "namespace";
namespace_.push_back(name(klass));
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "class";
switch(eolian_class_type_get(klass))
{
case EOLIAN_CLASS_REGULAR:
case EOLIAN_CLASS_ABSTRACT:
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
namespace_.push_back("CLASS");
break;
case EOLIAN_CLASS_INTERFACE:
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
namespace_.push_back("INTERFACE");
break;
case EOLIAN_CLASS_MIXIN:
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
namespace_.push_back("MIXIN");
break;
default:
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "default ?";
std::abort();
}
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
for(auto first = namespace_.begin(), last = namespace_.end()
; first != last; ++first)
{
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
std::string upper(*first);
std::transform(upper.begin(), upper.end(), upper.begin(), toupper);
os << upper;
if(std::next(first) != last) os << "_";
}
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "";
}
inline bool is_evas(Eolian_Class const* klass)
{
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "is_evas";
efl::eina::iterator<const char> first (::eolian_class_namespaces_get(klass));
return first != efl::eina::iterator<const char>()
&& std::strcmp(&*first, "Evas") == 0;
}
#endif

View File

@ -0,0 +1,8 @@
#include <Eina.hh>
namespace eolian { namespace js {
extern efl::eina::log_domain domain;
} }

View File

@ -0,0 +1,44 @@
#ifndef EOLIAN_JS_FORMAT_HH
#define EOLIAN_JS_FORMAT_HH
#include <eolian/js/domain.hh>
#include <algorithm>
#include <string>
#include <cctype>
namespace eolian { namespace js {
namespace format {
std::string generic(std::string const& in)
{
std::string s = in;
auto i = s.find('_');
while (i != std::string::npos)
{
if (i <= 0 || i+1 >= s.size() ||
!::isalnum(s[i-1]) || !::isalnum(s[i+1]))
{
EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Entity '" << in
<< "' can't be conveniently converted to a JavaScript name.";
return in;
}
s[i+1] = static_cast<char>(::toupper(s[i+1]));
s.erase(i, 1);
i = s.find('_', i);
}
return s;
}
std::string constant(std::string in)
{
std::transform(in.begin(), in.end(), in.begin(), ::toupper);
return in;
}
}
} }
#endif

1090
src/bin/eolian_js/main.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include <eina_log.hh> #include <eina_log.hh>
#include <eina_optional.hh> #include <eina_optional.hh>
#include <eina_integer_sequence.hh> #include <eina_integer_sequence.hh>
#include <eina_pp.hh>
/** /**
* @page eina_cxx_main Eina C++ (BETA) * @page eina_cxx_main Eina C++ (BETA)

View File

@ -114,7 +114,10 @@ struct accessor_common_base
* @warning It is important to take care when using it, since the * @warning It is important to take care when using it, since the
* handle will be automatically release upon object destruction. * handle will be automatically release upon object destruction.
*/ */
Eina_Accessor* native_handle() const; Eina_Accessor* native_handle() const
{
return _impl;
}
/** /**
* @brief Swap content between both objects. * @brief Swap content between both objects.

View File

@ -32,6 +32,8 @@ public:
typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */ typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */ typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */
typedef typename _base_type::native_handle_type native_handle_type;
using _base_type::_base_type; using _base_type::_base_type;
using _base_type::clear; using _base_type::clear;
using _base_type::size; using _base_type::size;
@ -59,6 +61,7 @@ public:
using _base_type::ciend; using _base_type::ciend;
using _base_type::swap; using _base_type::swap;
using _base_type::max_size; using _base_type::max_size;
using _base_type::release_native_handle;
using _base_type::native_handle; using _base_type::native_handle;
friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs) 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>
using _base_type::native_handle; using _base_type::native_handle;
}; };
/**
* @internal
*/
struct _eo_array_access_traits : _ptr_array_access_traits
{
template <typename T>
struct iterator
{
typedef _ptr_eo_array_iterator<T> type;
};
template <typename T>
struct const_iterator : iterator<T const> {};
template <typename T>
static T& back(Eina_Array* array)
{
return *static_cast<T*>(static_cast<void*>(array->data[size<T>(array)-1]));
}
template <typename T>
static T const& back(Eina_Array const* array)
{
return _eo_array_access_traits::back<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static T& front(Eina_Array* array)
{
return *static_cast<T*>(static_cast<void*>(array->data[0]));
}
template <typename T>
static T const& front(Eina_Array const* array)
{
return _eo_array_access_traits::front<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static typename iterator<T>::type begin(Eina_Array* array)
{
return _ptr_eo_array_iterator<T>(array->data);
}
template <typename T>
static typename iterator<T>::type end(Eina_Array* array)
{
return _ptr_eo_array_iterator<T>(array->data + size<T>(array));
}
template <typename T>
static typename const_iterator<T>::type begin(Eina_Array const* array)
{
return _eo_array_access_traits::begin<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static typename const_iterator<T>::type end(Eina_Array const* array)
{
return _eo_array_access_traits::end<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static std::reverse_iterator<typename iterator<T>::type> rbegin(Eina_Array* array)
{
return std::reverse_iterator<_ptr_eo_array_iterator<T> >(_eo_array_access_traits::end<T>(array));
}
template <typename T>
static std::reverse_iterator<typename iterator<T>::type> rend(Eina_Array* array)
{
return std::reverse_iterator<_ptr_eo_array_iterator<T> >(_eo_array_access_traits::begin<T>(array));
}
template <typename T>
static std::reverse_iterator<typename const_iterator<T>::type> rbegin(Eina_Array const* array)
{
return std::reverse_iterator<_ptr_eo_array_iterator<T>const>(_eo_array_access_traits::end<T>(array));
}
template <typename T>
static std::reverse_iterator<typename const_iterator<T>::type> rend(Eina_Array const* array)
{
return std::reverse_iterator<_ptr_eo_array_iterator<T>const>(_eo_array_access_traits::begin<T>(array));
}
template <typename T>
static typename const_iterator<T>::type cbegin(Eina_Array const* array)
{
return _eo_array_access_traits::begin<T>(array);
}
template <typename T>
static typename const_iterator<T>::type cend(Eina_Array const* array)
{
return _eo_array_access_traits::end<T>(array);
}
template <typename T>
static std::reverse_iterator<typename const_iterator<T>::type> crbegin(Eina_Array const* array)
{
return _eo_array_access_traits::rbegin<T>(array);
}
template <typename T>
static std::reverse_iterator<typename const_iterator<T>::type> crend(Eina_Array const* array)
{
return _eo_array_access_traits::rend<T>(array);
}
};
template <typename T, typename CloneAllocator> template <typename T, typename CloneAllocator>
class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type> class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
: ptr_array<Eo, typename std::conditional : ptr_array<Eo, typename std::conditional
@ -156,7 +254,9 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */
explicit array(Eina_Array* handle) typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */
explicit array(native_handle_type handle)
: _base_type(handle) {} : _base_type(handle) {}
array(clone_allocator_type alloc) : _base_type(alloc) {} array(clone_allocator_type alloc) : _base_type(alloc) {}
array() {} array() {}
@ -318,6 +418,7 @@ public:
using _base_type::swap; using _base_type::swap;
using _base_type::max_size; using _base_type::max_size;
using _base_type::release_native_handle;
using _base_type::native_handle; using _base_type::native_handle;
friend bool operator==(array<T, CloneAllocator> const& lhs, array<T, CloneAllocator> const& rhs) 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
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
template <typename T, typename Enable = void>
class range_array : range_ptr_array<T>
{
typedef range_ptr_array<T> _base_type;
public:
typedef typename _base_type::value_type value_type;
typedef typename _base_type::reference reference;
typedef typename _base_type::const_reference const_reference;
typedef typename _base_type::const_iterator const_iterator;
typedef typename _base_type::iterator iterator;
typedef typename _base_type::pointer pointer;
typedef typename _base_type::const_pointer const_pointer;
typedef typename _base_type::size_type size_type;
typedef typename _base_type::difference_type difference_type;
typedef typename _base_type::reverse_iterator reverse_iterator;
typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
typedef typename _base_type::native_handle_type native_handle_type;
range_array& operator=(range_array&& other) = default;
using _base_type::_base_type;
using _base_type::size;
using _base_type::empty;
using _base_type::back;
using _base_type::front;
using _base_type::begin;
using _base_type::end;
using _base_type::rbegin;
using _base_type::rend;
using _base_type::cbegin;
using _base_type::cend;
using _base_type::crbegin;
using _base_type::crend;
using _base_type::release_native_handle;
using _base_type::native_handle;
};
template <typename T>
class range_array<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
: range_ptr_array<Eo>
{
typedef range_ptr_array<Eo> _base_type;
typedef range_array<T> _self_type;
public:
typedef T value_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef _ptr_eo_array_iterator<value_type const> const_iterator;
typedef _ptr_eo_array_iterator<value_type> iterator;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef typename _base_type::native_handle_type native_handle_type;
explicit range_array(native_handle_type handle)
: _base_type(handle) {}
range_array() {}
range_array(range_array<T> const& other)
: _base_type(other.native_handle())
{
}
range_array<T>& operator=(range_array<T>const& other)
{
_base_type::_handle = other._handle;
return *this;
}
range_array& operator=(range_array&& other) = default;
range_array(range_array&& other) = default;
using _base_type::size;
using _base_type::empty;
reference front()
{
return _eo_array_access_traits::front<value_type>(native_handle());
}
reference back()
{
return _eo_array_access_traits::back<value_type>(native_handle());
}
const_reference front() const { return const_cast<_self_type*>(this)->front(); }
const_reference back() const { return const_cast<_self_type*>(this)->back(); }
iterator begin()
{
return _eo_array_access_traits::begin<value_type>(native_handle());
}
iterator end()
{
return _eo_array_access_traits::end<value_type>(native_handle());
}
const_iterator begin() const
{
return const_cast<_self_type*>(this)->begin();
}
const_iterator end() const
{
return const_cast<_self_type*>(this)->end();
}
const_iterator cbegin() const
{
return begin();
}
const_iterator cend() const
{
return end();
}
reverse_iterator rbegin()
{
return _eo_array_access_traits::rbegin<value_type>(native_handle());
}
reverse_iterator rend()
{
return _eo_array_access_traits::rend<value_type>(native_handle());
}
const_reverse_iterator rbegin() const
{
return const_cast<_self_type*>(this)->rbegin();
}
const_reverse_iterator rend() const
{
return const_cast<_self_type*>(this)->rend();
}
const_reverse_iterator crbegin() const
{
return rbegin();
}
const_reverse_iterator crend() const
{
return rend();
}
using _base_type::swap;
using _base_type::release_native_handle;
using _base_type::native_handle;
friend bool operator==(range_array<T> const& rhs, range_array<T> const& lhs)
{
return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin());
}
};
} } } }
#endif #endif

View File

@ -154,7 +154,8 @@ struct malloc_clone_allocator
template <typename T> template <typename T>
static void deallocate_clone(T const* p) static void deallocate_clone(T const* p)
{ {
static_assert(std::is_pod<T>::value, "malloc_clone_allocator can only be used with POD types"); static_assert(std::is_pod<T>::value || std::is_void<T>::value
, "malloc_clone_allocator can only be used with POD types");
std::free(const_cast<T*>(p)); std::free(const_cast<T*>(p));
} }
}; };

View File

@ -0,0 +1,26 @@
#ifndef EFL_EINA_FUNCTION_HH
#define EFL_EINA_FUNCTION_HH
namespace efl { namespace eina { namespace _mpl {
template <typename T>
struct function_params;
template <typename R, typename... P>
struct function_params<R(*)(P...)>
{
typedef std::tuple<P...> type;
};
template <typename T>
struct function_return;
template <typename R, typename... P>
struct function_return<R(*)(P...)>
{
typedef R type;
};
} } }
#endif

View File

@ -1,6 +1,8 @@
#ifndef EINA_CXX_EINA_INTEGER_SEQUENCE_HH #ifndef EINA_CXX_EINA_INTEGER_SEQUENCE_HH
#define EINA_CXX_EINA_INTEGER_SEQUENCE_HH #define EINA_CXX_EINA_INTEGER_SEQUENCE_HH
#include <cstdlib>
/** /**
* @addtogroup Eina_Cxx_Data_Types_Group * @addtogroup Eina_Cxx_Data_Types_Group
* *

View File

@ -190,6 +190,8 @@ public:
typedef typename _base_type::reverse_iterator reverse_iterator; typedef typename _base_type::reverse_iterator reverse_iterator;
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
using _base_type::native_handle_type;
list& operator=(list&& other) = default; list& operator=(list&& other) = default;
list(list&& other) = default; list(list&& other) = default;
list() = default; list() = default;
@ -224,6 +226,7 @@ public:
using _base_type::max_size; using _base_type::max_size;
using _base_type::native_handle; using _base_type::native_handle;
using _base_type::accessor; using _base_type::accessor;
using _base_type::release_native_handle;
}; };
template <typename T, typename CloneAllocator> template <typename T, typename CloneAllocator>
@ -251,7 +254,9 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
explicit list(Eina_List* handle) using _base_type::native_handle_type;
explicit list(typename _self_type::native_handle_type handle)
: _base_type(handle) {} : _base_type(handle) {}
list(clone_allocator_type alloc) : _base_type(alloc) {} list(clone_allocator_type alloc) : _base_type(alloc) {}
list() {} list() {}
@ -295,6 +300,7 @@ public:
using _base_type::get_clone_allocator; using _base_type::get_clone_allocator;
using _base_type::pop_back; using _base_type::pop_back;
using _base_type::pop_front; using _base_type::pop_front;
using _base_type::release_native_handle;
void push_back(const_reference w) void push_back(const_reference w)
{ {
@ -464,6 +470,8 @@ public:
typedef typename _base_type::reverse_iterator reverse_iterator; typedef typename _base_type::reverse_iterator reverse_iterator;
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
using _base_type::native_handle_type;
using _base_type::_base_type; using _base_type::_base_type;
using _base_type::size; using _base_type::size;
using _base_type::empty; using _base_type::empty;
@ -501,9 +509,9 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef typename _base_type::native_handle_type native_handle_type; using _base_type::native_handle_type;
explicit range_list(native_handle_type handle) explicit range_list(typename _self_type::native_handle_type handle)
: _base_type(handle) {} : _base_type(handle) {}
range_list() {} range_list() {}
range_list(range_list<T> const& other) range_list(range_list<T> const& other)

View File

@ -0,0 +1,34 @@
#ifndef EFL_EINA_LOGICAL_HH
#define EFL_EINA_LOGICAL_HH
#include <type_traits>
namespace efl { namespace eina { namespace _mpl {
template <bool... N>
struct or_;
template <>
struct or_<> : std::integral_constant<bool, false> {};
template <bool B>
struct or_<B> : std::integral_constant<bool, B> {};
template <bool B1, bool B2, bool... Bs>
struct or_<B1, B2, Bs...> : std::integral_constant<bool, B1 || B2 || or_<Bs...>::value> {};
template <bool... N>
struct and_;
template <>
struct and_<> : std::integral_constant<bool, true> {};
template <bool B>
struct and_<B> : std::integral_constant<bool, B> {};
template <bool B1, bool B2, bool... Bs>
struct and_<B1, B2, Bs...> : std::integral_constant<bool, B1 && B2 && and_<Bs...>::value> {};
} } }
#endif

View File

@ -0,0 +1,8 @@
#ifndef EINA_PP_HH
#define EINA_PP_HH
#define EINA_STRINGIZE_IMPL(x) #x
#define EINA_STRINGIZE(x) EINA_STRINGIZE_IMPL(x)
#endif

View File

@ -295,10 +295,12 @@ struct range_ptr_array : _range_template<T, _ptr_array_access_traits>
typedef _range_template<T, _ptr_array_access_traits> _base_type; /**< Type for the base class. */ typedef _range_template<T, _ptr_array_access_traits> _base_type; /**< Type for the base class. */
typedef typename _base_type::value_type value_type; /**< The type of each element. */ typedef typename _base_type::value_type value_type; /**< The type of each element. */
typedef typename _base_type::native_handle_type native_handle_type;
/** /**
* @brief Creates a range from a native Eina array handle. * @brief Creates a range from a native Eina array handle.
*/ */
range_ptr_array(Eina_Array* array) range_ptr_array(native_handle_type array)
: _base_type(array) : _base_type(array)
{} {}
@ -391,7 +393,7 @@ struct _ptr_array_common_base
/** /**
* @internal * @internal
*/ */
T* _new_clone(T const& a) T* _new_clone(typename container_value_type<T>::type const& a)
{ {
return _get_clone_allocator().allocate_clone(a); return _get_clone_allocator().allocate_clone(a);
} }
@ -402,6 +404,7 @@ struct _ptr_array_common_base
struct _ptr_array_impl : CloneAllocator struct _ptr_array_impl : CloneAllocator
{ {
_ptr_array_impl() : _array( ::eina_array_new(32u) ) {} _ptr_array_impl() : _array( ::eina_array_new(32u) ) {}
_ptr_array_impl(Eina_Array* array) : _array(array) {}
_ptr_array_impl(CloneAllocator allocator) _ptr_array_impl(CloneAllocator allocator)
: clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {} : clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {}
@ -449,6 +452,8 @@ public:
typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr; typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr;
typedef Eina_Array* native_handle_type;
/** /**
* @brief Default constructor. Create an empty array. * @brief Default constructor. Create an empty array.
* *
@ -1210,6 +1215,13 @@ public:
*/ */
size_type max_size() const { return -1; } size_type max_size() const { return -1; }
Eina_Array* release_native_handle()
{
Eina_Array* tmp = this->_impl._array;
this->_impl._array = ::eina_array_new(32u);
return tmp;
}
/** /**
* @brief Get a handle for the wrapped Eina_Array. * @brief Get a handle for the wrapped Eina_Array.
* @return Handle for the native Eina array. * @return Handle for the native Eina array.

View File

@ -9,6 +9,7 @@
#include <eina_eo_concrete_fwd.hh> #include <eina_eo_concrete_fwd.hh>
#include <eina_iterator.hh> #include <eina_iterator.hh>
#include <eina_throw.hh> #include <eina_throw.hh>
#include <eina_range_types.hh>
#include <memory> #include <memory>
#include <iterator> #include <iterator>
@ -370,7 +371,7 @@ struct _ptr_list_common_base
/** /**
* @internal * @internal
*/ */
T* _new_clone(T const& a) T* _new_clone(typename container_value_type<T>::type const& a)
{ {
return _get_clone_allocator().allocate_clone(a); return _get_clone_allocator().allocate_clone(a);
} }
@ -413,11 +414,12 @@ class ptr_list : protected _ptr_list_common_base<T, CloneAllocator>
{ {
typedef _ptr_list_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */ typedef _ptr_list_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */
public: public:
typedef T value_type; /**< The type of each element. */ typedef typename container_value_type<T>::type
typedef T& reference; /**< Type for a reference to an element. */ value_type; /**< The type of each element. */
typedef T const& const_reference; /**< Type for a constant reference to an element. */ typedef value_type& reference; /**< Type for a reference to an element. */
typedef _ptr_list_iterator<T const> const_iterator; /**< Type for a iterator for this container. */ typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef _ptr_list_iterator<T> iterator; /**< Type for a constant iterator for this container. */ typedef _ptr_list_iterator<value_type const> const_iterator; /**< Type for a iterator for this container. */
typedef _ptr_list_iterator<value_type> iterator; /**< Type for a constant iterator for this container. */
typedef T* pointer; /**< Type for a pointer to an element. */ typedef T* pointer; /**< Type for a pointer to an element. */
typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ typedef T const* const_pointer; /**< Type for a constant pointer for an element. */
typedef std::size_t size_type; /**< Type for size information. */ typedef std::size_t size_type; /**< Type for size information. */
@ -427,6 +429,8 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */
typedef Eina_List* native_handle_type;
typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr; typedef std::unique_ptr<value_type, clone_allocator_deleter<clone_allocator_type> > _unique_ptr;
/** /**
@ -554,7 +558,7 @@ public:
*/ */
std::size_t size() const std::size_t size() const
{ {
return _ptr_list_access_traits::size<T>(this->_impl._list); return _ptr_list_access_traits::size<value_type>(this->_impl._list);
} }
/** /**
@ -566,7 +570,7 @@ public:
*/ */
bool empty() const bool empty() const
{ {
return _ptr_list_access_traits::empty<T>(this->_impl._list); return _ptr_list_access_traits::empty<value_type>(this->_impl._list);
} }
/** /**
@ -940,7 +944,7 @@ public:
*/ */
value_type& back() value_type& back()
{ {
return _ptr_list_access_traits::back<T>(this->_impl._list); return _ptr_list_access_traits::back<value_type>(this->_impl._list);
} }
/** /**
@ -952,7 +956,7 @@ public:
*/ */
value_type const& back() const value_type const& back() const
{ {
return _ptr_list_access_traits::back<T>(this->_impl._list); return _ptr_list_access_traits::back<value_type>(this->_impl._list);
} }
/** /**
@ -961,7 +965,7 @@ public:
*/ */
value_type& front() value_type& front()
{ {
return _ptr_list_access_traits::front<T>(this->_impl._list); return _ptr_list_access_traits::front<value_type>(this->_impl._list);
} }
/** /**
@ -973,7 +977,7 @@ public:
*/ */
value_type const& front() const value_type const& front() const
{ {
return _ptr_list_access_traits::front<T>(this->_impl._list); return _ptr_list_access_traits::front<value_type>(this->_impl._list);
} }
/** /**
@ -985,7 +989,7 @@ public:
*/ */
const_iterator begin() const const_iterator begin() const
{ {
return _ptr_list_access_traits::cbegin<T>(this->_impl._list); return _ptr_list_access_traits::cbegin<value_type>(this->_impl._list);
} }
/** /**
@ -997,7 +1001,7 @@ public:
*/ */
const_iterator end() const const_iterator end() const
{ {
return _ptr_list_access_traits::cend<T>(this->_impl._list); return _ptr_list_access_traits::cend<value_type>(this->_impl._list);
} }
/** /**
@ -1010,7 +1014,7 @@ public:
*/ */
iterator begin() iterator begin()
{ {
return _ptr_list_access_traits::begin<T>(this->_impl._list); return _ptr_list_access_traits::begin<value_type>(this->_impl._list);
} }
/** /**
@ -1026,7 +1030,7 @@ public:
*/ */
iterator end() iterator end()
{ {
return _ptr_list_access_traits::end<T>(this->_impl._list); return _ptr_list_access_traits::end<value_type>(this->_impl._list);
} }
/** /**
@ -1038,7 +1042,7 @@ public:
*/ */
const_reverse_iterator rbegin() const const_reverse_iterator rbegin() const
{ {
return _ptr_list_access_traits::rbegin<T>(this->_impl._list); return _ptr_list_access_traits::rbegin<value_type>(this->_impl._list);
} }
/** /**
@ -1050,7 +1054,7 @@ public:
*/ */
const_reverse_iterator rend() const const_reverse_iterator rend() const
{ {
return _ptr_list_access_traits::rend<T>(this->_impl._list); return _ptr_list_access_traits::rend<value_type>(this->_impl._list);
} }
/** /**
@ -1063,7 +1067,7 @@ public:
*/ */
reverse_iterator rbegin() reverse_iterator rbegin()
{ {
return _ptr_list_access_traits::rbegin<T>(this->_impl._list); return _ptr_list_access_traits::rbegin<value_type>(this->_impl._list);
} }
/** /**
@ -1080,7 +1084,7 @@ public:
*/ */
reverse_iterator rend() reverse_iterator rend()
{ {
return _ptr_list_access_traits::rend<T>(this->_impl._list); return _ptr_list_access_traits::rend<value_type>(this->_impl._list);
} }
/** /**
@ -1093,7 +1097,7 @@ public:
*/ */
const_iterator cbegin() const const_iterator cbegin() const
{ {
return _ptr_list_access_traits::cbegin<T>(this->_impl._list); return _ptr_list_access_traits::cbegin<value_type>(this->_impl._list);
} }
/** /**
@ -1106,7 +1110,7 @@ public:
*/ */
const_iterator cend() const const_iterator cend() const
{ {
return _ptr_list_access_traits::cend<T>(this->_impl._list); return _ptr_list_access_traits::cend<value_type>(this->_impl._list);
} }
/** /**
@ -1119,7 +1123,7 @@ public:
*/ */
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ {
return _ptr_list_access_traits::crbegin<T>(this->_impl._list); return _ptr_list_access_traits::crbegin<value_type>(this->_impl._list);
} }
/** /**
@ -1132,7 +1136,7 @@ public:
*/ */
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ {
return _ptr_list_access_traits::crend<T>(this->_impl._list); return _ptr_list_access_traits::crend<value_type>(this->_impl._list);
} }
/** /**
@ -1143,9 +1147,9 @@ public:
* the first element of the list. If the list is empty the returned * the first element of the list. If the list is empty the returned
* iterator is the same as the one returned by @ref iend(). * iterator is the same as the one returned by @ref iend().
*/ */
eina::iterator<T> ibegin() eina::iterator<value_type> ibegin()
{ {
return _ptr_list_access_traits::ibegin<T>(this->_impl._list); return _ptr_list_access_traits::ibegin<value_type>(this->_impl._list);
} }
/** /**
@ -1160,9 +1164,9 @@ public:
* @note Note that attempting to access this position causes undefined * @note Note that attempting to access this position causes undefined
* behavior. * behavior.
*/ */
eina::iterator<T> iend() eina::iterator<value_type> iend()
{ {
return _ptr_list_access_traits::iend<T>(this->_impl._list); return _ptr_list_access_traits::iend<value_type>(this->_impl._list);
} }
/** /**
@ -1174,7 +1178,7 @@ public:
*/ */
eina::iterator<T const> ibegin() const eina::iterator<T const> ibegin() const
{ {
return _ptr_list_access_traits::ibegin<T>(this->_impl._list); return _ptr_list_access_traits::ibegin<value_type>(this->_impl._list);
} }
/** /**
@ -1186,7 +1190,7 @@ public:
*/ */
eina::iterator<T const> iend() const eina::iterator<T const> iend() const
{ {
return _ptr_list_access_traits::iend<T>(this->_impl._list); return _ptr_list_access_traits::iend<value_type>(this->_impl._list);
} }
/** /**
@ -1199,7 +1203,7 @@ public:
*/ */
eina::iterator<T const> cibegin() const eina::iterator<T const> cibegin() const
{ {
return _ptr_list_access_traits::cibegin<T>(this->_impl._list); return _ptr_list_access_traits::cibegin<value_type>(this->_impl._list);
} }
/** /**
@ -1212,7 +1216,7 @@ public:
*/ */
eina::iterator<T const> ciend() const eina::iterator<T const> ciend() const
{ {
return _ptr_list_access_traits::ciend<T>(this->_impl._list); return _ptr_list_access_traits::ciend<value_type>(this->_impl._list);
} }
/** /**
@ -1230,6 +1234,13 @@ public:
*/ */
size_type max_size() const { return -1; } size_type max_size() const { return -1; }
Eina_List* release_native_handle()
{
Eina_List* tmp = this->_impl._list;
this->_impl._list = 0;
return tmp;
}
/** /**
* @brief Get a handle for the wrapped @c Eina_List. * @brief Get a handle for the wrapped @c Eina_List.
* @return Handle for the native Eina list. * @return Handle for the native Eina list.
@ -1275,9 +1286,9 @@ public:
* @brief Get a @ref eina::accessor for the list. * @brief Get a @ref eina::accessor for the list.
* @return <tt>eina::accessor</tt> to the list. * @return <tt>eina::accessor</tt> to the list.
*/ */
eina::accessor<T> accessor() eina::accessor<value_type> accessor()
{ {
return eina::accessor<T>(eina_list_accessor_new(this->_impl._list)); return eina::accessor<value_type>(eina_list_accessor_new(this->_impl._list));
} }
}; };

View File

@ -22,11 +22,12 @@ namespace efl { namespace eina {
template <typename T, typename Traits> template <typename T, typename Traits>
struct _const_range_template struct _const_range_template
{ {
typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */ typedef typename container_value_type<T>::type
typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */ value_type; /**< The type of each element. */
typedef T value_type; /**< The type of each element. */ typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */
typedef T& reference; /**< Type for a reference to an element. */ typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */
typedef T const& const_reference; /**< Type for a constant reference to an element. */ typedef value_type& reference; /**< Type for a reference to an element. */
typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef T* pointer; /**< Type for a pointer to an element. */ typedef T* pointer; /**< Type for a pointer to an element. */
typedef T const* const_pointer; /**< Type for a constant pointer to an element. */ typedef T const* const_pointer; /**< Type for a constant pointer to an element. */
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */
@ -49,6 +50,17 @@ struct _const_range_template
_const_range_template(native_handle_type handle) _const_range_template(native_handle_type handle)
: _handle(handle) {} : _handle(handle) {}
/**
* @brief Release the handle of the native Eina container.
* @return Handle for the native Eina container.
*/
native_handle_type release_native_handle()
{
auto h = _handle;
_handle = nullptr;
return h;
}
/** /**
* @brief Get a constant handle for the native Eina container. * @brief Get a constant handle for the native Eina container.
* @return Constant handle for the native Eina container. * @return Constant handle for the native Eina container.
@ -241,10 +253,13 @@ void swap(_const_range_template<T, Traits>& lhs, _const_range_template<T, Traits
template <typename T, typename Traits> template <typename T, typename Traits>
struct _mutable_range_template : _const_range_template<T, Traits> struct _mutable_range_template : _const_range_template<T, Traits>
{ {
typedef T value_type; /**< The type of each element. */ typedef typename container_value_type<T>::type
typedef typename Traits::template iterator<T>::type iterator; /**< Type for a iterator to the range. */ value_type; /**< The type of each element. */
typedef value_type& reference_type;
typedef value_type const& const_reference_type;
typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for a iterator to the range. */
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for constant reverse iterator to the range. */ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for constant reverse iterator to the range. */
typedef typename Traits::template native_handle<T>::type native_handle_type; /**< Type for the native handle of the container. */ typedef typename Traits::template native_handle<value_type>::type native_handle_type; /**< Type for the native handle of the container. */
typedef _const_range_template<T, Traits> _base_type; /**< Type for the base class. */ typedef _const_range_template<T, Traits> _base_type; /**< Type for the base class. */
/** /**
@ -253,6 +268,17 @@ struct _mutable_range_template : _const_range_template<T, Traits>
_mutable_range_template(native_handle_type handle) _mutable_range_template(native_handle_type handle)
: _base_type(handle) {} : _base_type(handle) {}
/**
* @brief Release the handle of the native Eina container.
* @return Handle for the native Eina container.
*/
native_handle_type release_native_handle()
{
auto h = _handle;
_handle = nullptr;
return h;
}
/** /**
* @brief Get a constant handle for the native Eina container. * @brief Get a constant handle for the native Eina container.
* @return Constant handle for the native Eina container. * @return Constant handle for the native Eina container.
@ -266,7 +292,7 @@ struct _mutable_range_template : _const_range_template<T, Traits>
* @brief Get a reference to the last element. * @brief Get a reference to the last element.
* @return Reference to the last element of the range. * @return Reference to the last element of the range.
*/ */
value_type& back() const reference_type back() const
{ {
return Traits::template back<value_type>(native_handle()); return Traits::template back<value_type>(native_handle());
} }
@ -275,7 +301,7 @@ struct _mutable_range_template : _const_range_template<T, Traits>
* @brief Get a reference to the first element. * @brief Get a reference to the first element.
* @return Reference to the first element of the range. * @return Reference to the first element of the range.
*/ */
value_type& front() const reference_type front() const
{ {
return Traits::template front<value_type>(native_handle()); return Traits::template front<value_type>(native_handle());
} }
@ -355,11 +381,12 @@ protected:
template <typename T, typename Traits> template <typename T, typename Traits>
struct _range_template : private std::conditional struct _range_template : private std::conditional
<std::is_const<T>::value <std::is_const<T>::value
, _const_range_template<typename std::remove_const<T>::type, Traits> , _const_range_template<typename nonconst_container_value_type<T>::type, Traits>
, _mutable_range_template<T, Traits> >::type , _mutable_range_template<typename nonconst_container_value_type<T>::type, Traits>
>::type
{ {
typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable; /**< Type that specifies if the elements can be modified. */ typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable; /**< Type that specifies if the elements can be modified. */
typedef typename std::remove_const<T>::type value_type; /**< The type of each element. */ typedef typename nonconst_container_value_type<T>::type value_type; /**< The type of each element. */
typedef typename std::conditional<is_mutable::value, _mutable_range_template<value_type, Traits> typedef typename std::conditional<is_mutable::value, _mutable_range_template<value_type, Traits>
, _const_range_template<value_type, Traits> >::type _base_type; /**< Type for the base class. */ , _const_range_template<value_type, Traits> >::type _base_type; /**< Type for the base class. */
typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */ typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */
@ -368,9 +395,9 @@ struct _range_template : private std::conditional
typedef value_type const& const_reference; /**< Type for a constant reference to an element. */ typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef value_type* pointer; /**< Type for a pointer to an element. */ typedef value_type* pointer; /**< Type for a pointer to an element. */
typedef value_type const* const_pointer; /**< Type for a constant pointer to an element. */ typedef value_type const* const_pointer; /**< Type for a constant pointer to an element. */
typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */ typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for constant reverse iterator to the range. */ typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for constant reverse iterator to the range. */
typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */ typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */
typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator to the range. */ typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator to the range. */
typedef typename _base_type::size_type size_type; /**< Type for size information. */ typedef typename _base_type::size_type size_type; /**< Type for size information. */
typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */ typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */
@ -388,6 +415,7 @@ struct _range_template : private std::conditional
: _base_type(handle) : _base_type(handle)
{} {}
using _base_type::release_native_handle;
using _base_type::native_handle; using _base_type::native_handle;
using _base_type::back; using _base_type::back;
using _base_type::front; using _base_type::front;

View File

@ -1,6 +1,11 @@
#ifndef EFL_EINA_EINA_TUPLE_HH_ #ifndef EFL_EINA_EINA_TUPLE_HH_
#define EFL_EINA_EINA_TUPLE_HH_ #define EFL_EINA_EINA_TUPLE_HH_
#include <eina_integer_sequence.hh>
#include <eina_logical.hh>
#include <tuple>
namespace efl { namespace eina { namespace _mpl { namespace efl { namespace eina { namespace _mpl {
template <typename A, typename... Args> template <typename A, typename... Args>
@ -21,15 +26,64 @@ struct push_front<C<Args...>, AArgs...>
typedef C<Args..., AArgs...> type; typedef C<Args..., AArgs...> type;
}; };
template <typename A> template <typename A, std::size_t N = 1>
struct pop_front; struct pop_front;
template <template <typename...> class C, typename T, typename... Args> template <template <typename...> class C, typename T, typename... Args>
struct pop_front<C<T, Args...> > struct pop_front<C<T, Args...>, 1>
{ {
typedef C<Args...> type; typedef C<Args...> type;
}; };
template <typename A, std::size_t N>
struct pop_front : pop_front<typename pop_front<A, 1>::type, N-1>
{
};
template <typename T, typename F, std::size_t... I>
void for_each_impl(T&& t, F&& f, eina::index_sequence<I...>)
{
std::initializer_list<int> l = { (f(std::get<I>(t)), 0)...};
static_cast<void>(l);
}
template <typename T, typename F>
void for_each(T&& t, F&& f)
{
_mpl::for_each_impl(t, f, eina::make_index_sequence
<std::tuple_size<typename std::remove_reference<T>::type>::value>());
}
template <typename T, typename Transform>
struct tuple_transform;
template <typename...T, typename Transform>
struct tuple_transform<std::tuple<T...>, Transform>
{
typedef std::tuple<typename Transform::template apply<T>::type...> type;
};
template <typename T, typename Tuple>
struct tuple_contains;
template <typename T, typename...Ts>
struct tuple_contains<T, std::tuple<Ts...> >
: _mpl::or_<std::is_same<T, Ts>::value...>
{
};
template <typename T, typename Tuple>
struct tuple_find : std::integral_constant<int, -1> {};
template <typename T, typename... Ts>
struct tuple_find<T, std::tuple<T, Ts...> > : std::integral_constant<std::size_t, 0> {};
template <typename T, typename T1, typename... Ts>
struct tuple_find<T, std::tuple<T1, Ts...> > : std::integral_constant
<std::size_t, 1 + tuple_find<T, std::tuple<Ts...> >::value> {};
} } } } } }
#endif #endif

View File

@ -0,0 +1,24 @@
#ifndef EFL_EINA_EINA_TUPLE_C_HH_
#define EFL_EINA_EINA_TUPLE_C_HH_
#include <tuple>
namespace efl { namespace eina { namespace _mpl {
template <typename T, T... Ts>
using tuple_c = std::tuple<std::integral_constant<T, Ts>...>;
template <typename T, T... Ts>
constexpr std::size_t tuple_c_size(tuple_c<T, Ts...> const&)
{
return sizeof...(Ts);
}
constexpr std::size_t tuple_c_size(std::tuple<> const&)
{
return 0;
}
} } }
#endif

View File

@ -64,6 +64,22 @@ struct if_ : if_c<U::value, T, F>
{ {
}; };
template <typename T>
struct container_value_type
{
typedef typename std::conditional<
std::is_void<T>::value
, T*, T>::type type;
};
template <typename T>
struct nonconst_container_value_type
{
typedef typename std::conditional<
std::is_void<T>::value
, T*, typename std::remove_const<T>::type>::type type;
};
/** /**
* @} * @}
*/ */

View File

@ -11,7 +11,6 @@ namespace efl { namespace eldbus { namespace _detail {
template <typename Callback, typename... Ins> template <typename Callback, typename... Ins>
void _callback_wrapper(void* data, Eldbus_Message const* message, Eldbus_Pending* pending) void _callback_wrapper(void* data, Eldbus_Message const* message, Eldbus_Pending* pending)
{ {
std::cout << "_callback_wrapper" << std::endl;
Callback* callback(static_cast<Callback*>(data)); Callback* callback(static_cast<Callback*>(data));
const char* errname, *errmsg; const char* errname, *errmsg;

View File

@ -187,6 +187,13 @@ struct concrete
Eo* _eo_raw; ///< The opaque <em>EO Object</em>. Eo* _eo_raw; ///< The opaque <em>EO Object</em>.
}; };
template<class CharT, class Traits>
inline std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, concrete const& eo)
{
return os << eo._eo_ptr();
}
inline bool operator==(concrete const& lhs, concrete const& rhs) inline bool operator==(concrete const& lhs, concrete const& rhs)
{ {
return lhs._eo_ptr() == rhs._eo_ptr(); return lhs._eo_ptr() == rhs._eo_ptr();

View File

@ -0,0 +1,58 @@
#ifndef EFL_ECORE_JS_HH
#define EFL_ECORE_JS_HH
#include <Ecore.hh>
#include <Ecore_File.h>
#include <Eina_Js.hh>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_ECORE_JS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_ECORE_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
namespace efl { namespace ecore { namespace js {
using ::efl::eina::js::compatibility_new;
using ::efl::eina::js::compatibility_return_type;
using ::efl::eina::js::compatibility_callback_info_type;
using ::efl::eina::js::compatibility_return;
using ::efl::eina::js::compatibility_get_pointer_internal_field;
using ::efl::eina::js::compatibility_set_pointer_internal_field;
EAPI void register_ecore_animator(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore_event(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
EAPI void register_ecore_file(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
EAPI void register_ecore_idle(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore_job(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore_mainloop(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore_poller(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore_throttle(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore_timer(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
EAPI void register_ecore(v8::Isolate *isolate,v8::Handle<v8::Object> exports);
} } }
#endif

View File

@ -0,0 +1,608 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
static Ecore_Animator* extract_animator(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Animator*>(ptr);
}
static v8::Local<v8::Object> wrap_animator(Ecore_Animator *animator,
v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_animator_del(extract_animator(info.This()));
return compatibility_return();
};
auto freeze = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_animator_freeze(extract_animator(info.This()));
return compatibility_return();
};
auto thaw = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_animator_thaw(extract_animator(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "freeze"),
compatibility_new<FunctionTemplate>(isolate, freeze)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "thaw"),
compatibility_new<FunctionTemplate>(isolate, thaw)->GetFunction());
ret->SetInternalField(0, compatibility_new<v8::External>(isolate,
animator));
return ret;
}
void register_pos_map_linear(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POS_MAP_LINEAR));
}
void register_pos_map_accelerate(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POS_MAP_ACCELERATE));
}
void register_pos_map_decelerate(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POS_MAP_DECELERATE));
}
void register_pos_map_sinusoidal(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POS_MAP_SINUSOIDAL));
}
void register_pos_map_accelerate_factor(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_POS_MAP_ACCELERATE_FACTOR));
}
void register_pos_map_decelerate_factor(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_POS_MAP_DECELERATE_FACTOR));
}
void register_pos_map_sinusoidal_factor(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_POS_MAP_SINUSOIDAL_FACTOR));
}
void register_pos_map_divisor_interp(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_POS_MAP_DIVISOR_INTERP));
}
void register_pos_map_bounce(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POS_MAP_BOUNCE));
}
void register_pos_map_spring(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POS_MAP_SPRING));
}
void register_pos_map_cubic_bezier(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_POS_MAP_CUBIC_BEZIER));
}
void register_animator_source_timer(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_ANIMATOR_SOURCE_TIMER));
}
void register_animator_frametime_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
ecore_animator_frametime_set(args[0]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_frametime_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Number;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_animator_frametime_get();
return compatibility_return(compatibility_new<Number>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_pos_map(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Number;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 4 || !args[0]->IsNumber() || !args[1]->IsNumber()
|| !args[2]->IsNumber() || !args[3]->IsNumber())
return compatibility_return();
Ecore_Pos_Map map;
switch ((int)(args[1]->NumberValue())) {
case ECORE_POS_MAP_LINEAR:
map = ECORE_POS_MAP_LINEAR;
break;
case ECORE_POS_MAP_ACCELERATE:
map = ECORE_POS_MAP_ACCELERATE;
break;
case ECORE_POS_MAP_DECELERATE:
map = ECORE_POS_MAP_DECELERATE;
break;
case ECORE_POS_MAP_SINUSOIDAL:
map = ECORE_POS_MAP_SINUSOIDAL;
break;
case ECORE_POS_MAP_ACCELERATE_FACTOR:
map = ECORE_POS_MAP_ACCELERATE_FACTOR;
break;
case ECORE_POS_MAP_DECELERATE_FACTOR:
map = ECORE_POS_MAP_DECELERATE_FACTOR;
break;
case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
map = ECORE_POS_MAP_SINUSOIDAL_FACTOR;
break;
case ECORE_POS_MAP_DIVISOR_INTERP:
map = ECORE_POS_MAP_DIVISOR_INTERP;
break;
case ECORE_POS_MAP_BOUNCE:
map = ECORE_POS_MAP_BOUNCE;
break;
case ECORE_POS_MAP_SPRING:
map = ECORE_POS_MAP_SPRING;
break;
case ECORE_POS_MAP_CUBIC_BEZIER:
map = ECORE_POS_MAP_CUBIC_BEZIER;
break;
default:
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto ret = ecore_animator_pos_map(args[0]->NumberValue(), map,
args[2]->NumberValue(),
args[3]->NumberValue());
return compatibility_return(compatibility_new<Number>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_pos_map_n(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Number;
using v8::NumberObject;
using v8::FunctionTemplate;
using v8::Array;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
|| !args[2]->IsArray())
return compatibility_return();
Ecore_Pos_Map map;
switch ((int)(args[1]->NumberValue())) {
case ECORE_POS_MAP_LINEAR:
map = ECORE_POS_MAP_LINEAR;
break;
case ECORE_POS_MAP_ACCELERATE:
map = ECORE_POS_MAP_ACCELERATE;
break;
case ECORE_POS_MAP_DECELERATE:
map = ECORE_POS_MAP_DECELERATE;
break;
case ECORE_POS_MAP_SINUSOIDAL:
map = ECORE_POS_MAP_SINUSOIDAL;
break;
case ECORE_POS_MAP_ACCELERATE_FACTOR:
map = ECORE_POS_MAP_ACCELERATE_FACTOR;
break;
case ECORE_POS_MAP_DECELERATE_FACTOR:
map = ECORE_POS_MAP_DECELERATE_FACTOR;
break;
case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
map = ECORE_POS_MAP_SINUSOIDAL_FACTOR;
break;
case ECORE_POS_MAP_DIVISOR_INTERP:
map = ECORE_POS_MAP_DIVISOR_INTERP;
break;
case ECORE_POS_MAP_BOUNCE:
map = ECORE_POS_MAP_BOUNCE;
break;
case ECORE_POS_MAP_SPRING:
map = ECORE_POS_MAP_SPRING;
break;
case ECORE_POS_MAP_CUBIC_BEZIER:
map = ECORE_POS_MAP_CUBIC_BEZIER;
break;
default:
return compatibility_return();
}
std::vector<double> v;
{
auto array = Array::Cast(*args[2]);
auto s = array->Length();
v.reserve(s);
for (decltype(s) i = 0;i != s;++i) {
auto e = array->Get(i);
if (!e->IsNumber())
return compatibility_return();
v.push_back(e->NumberValue());
}
}
auto isolate = args.GetIsolate();
auto ret = ecore_animator_pos_map_n(args[0]->NumberValue(), map,
v.size(), v.data());
return compatibility_return(compatibility_new<Number>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_source_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
Ecore_Animator_Source source;
switch ((int)(args[0]->NumberValue())) {
case ECORE_ANIMATOR_SOURCE_TIMER:
source = ECORE_ANIMATOR_SOURCE_TIMER;
break;
case ECORE_ANIMATOR_SOURCE_CUSTOM:
source = ECORE_ANIMATOR_SOURCE_CUSTOM;
break;
default:
return compatibility_return();
}
ecore_animator_source_set(source);
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_source_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_animator_source_get();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto isolate = args.GetIsolate();
auto f = new efl::eina::js::global_ref<Value>(isolate, args[0]);
auto cb = [](void *data) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_animator_add(cb, f);
return compatibility_return(wrap_animator(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_animator_timeline_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Handle;
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
using v8::Number;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsNumber()
|| !args[1]->IsFunction()) {
return compatibility_return();
}
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
auto cb = [](void *data, double pos) -> Eina_Bool {
auto persistent
= reinterpret_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args = compatibility_new<Number>(isolate, pos);
auto ret = Function::Cast(*o)->Call(o->ToObject(), 1, &args);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_animator_timeline_add(args[0]->NumberValue(), cb, f);
return compatibility_return(wrap_animator(ret, args.GetIsolate()),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_ecore_animator(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
register_pos_map_linear(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP_LINEAR"));
register_pos_map_accelerate(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_ACCELERATE"));
register_pos_map_decelerate(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_DECELERATE"));
register_pos_map_sinusoidal(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_SINUSOIDAL"));
register_pos_map_accelerate_factor(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_ACCELERATE"
"_FACTOR"));
register_pos_map_decelerate_factor(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_DECELERATE"
"_FACTOR"));
register_pos_map_sinusoidal_factor(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_SINUSOIDAL"
"_FACTOR"));
register_pos_map_divisor_interp(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP"
"_DIVISOR_INTERP"));
register_pos_map_bounce(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP_BOUNCE"));
register_pos_map_spring(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP_SPRING"));
register_pos_map_cubic_bezier(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POS_MAP_CUBIC"
"_BEZIER"));
register_animator_source_timer(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_ANIMATOR"
"_SOURCE_TIMER"));
register_animator_frametime_set(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator"
"_frametime_set"));
register_animator_frametime_get(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator"
"_frametime_get"));
register_animator_pos_map(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator_pos"
"_map"));
register_animator_pos_map_n(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator_pos_map"
"_n"));
register_animator_source_set(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator_source"
"_set"));
register_animator_source_get(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator_source"
"_get"));
register_animator_add(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator_add"));
register_animator_timeline_add(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_animator"
"_timeline_add"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,772 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
static Ecore_Event *extract_event(v8::Local<v8::Object> object)
{
return compatibility_get_pointer_internal_field<Ecore_Event*>(object, 0);
}
static v8::Local<v8::Object> wrap_event(Ecore_Event *event,
v8::Isolate *isolate)
{
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_event_del(extract_event(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, event);
return ret;
}
static Ecore_Event_Handler *extract_event_handler(v8::Local<v8::Object> object)
{
return compatibility_get_pointer_internal_field<Ecore_Event_Handler*>
(object, 0);
}
static v8::Local<v8::Object> wrap_event_handler(Ecore_Event_Handler *handler,
v8::Isolate *isolate)
{
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
using v8::Value;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto p = ecore_event_handler_del(extract_event_handler(info.This()));
delete static_cast<efl::eina::js::global_ref<Value>*>(p);
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, handler);
return ret;
}
static Ecore_Event_Filter *extract_event_filter(v8::Local<v8::Object> object)
{
return compatibility_get_pointer_internal_field<Ecore_Event_Filter*>
(object, 0);
}
static v8::Local<v8::Object> wrap_event_filter(Ecore_Event_Filter *filter,
v8::Isolate *isolate)
{
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
using v8::Value;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto p = ecore_event_filter_del(extract_event_filter(info.This()));
delete[] static_cast<efl::eina::js::global_ref<Value>*>(p);
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, filter);
return ret;
}
EAPI
void register_event_none(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_NONE));
}
EAPI
void register_event_signal_user(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_USER));
}
EAPI
void register_event_signal_hup(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_HUP));
}
EAPI
void register_event_signal_exit(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_EXIT));
}
EAPI
void register_event_signal_power(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_SIGNAL_POWER));
}
EAPI
void register_event_signal_realtime(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_EVENT_SIGNAL_REALTIME));
}
EAPI
void register_event_memory_state(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_MEMORY_STATE));
}
EAPI
void register_event_power_state(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_EVENT_POWER_STATE));
}
EAPI
void register_event_locale_changed(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_EVENT_LOCALE_CHANGED));
}
EAPI
void register_event_hostname_changed(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_EVENT_HOSTNAME_CHANGED));
}
EAPI
void register_event_system_timedate_changed(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED));
}
EAPI
void register_event_type_new(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_event_type_new();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_event_add(args[0]->NumberValue(), NULL, NULL, NULL);
return compatibility_return(wrap_event(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_handler_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::Value;
using v8::Function;
using v8::Handle;
using v8::Local;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsNumber()
|| !args[1]->IsFunction()) {
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto p = new efl::eina::js::global_ref<Value>(isolate, args[1]);
auto cb = [](void *d, int type, void */*event*/) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(d);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args = compatibility_new<Integer>(isolate, type);
auto ret = Function::Cast(*o)->Call(o->ToObject(), 1, &args);
auto bret = ret->IsBoolean() && ret->BooleanValue();
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_event_handler_add(args[0]->Int32Value(), cb, p);
return compatibility_return(wrap_event_handler(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_filter_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::Value;
using v8::Function;
using v8::Handle;
using v8::Local;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 3 || !args[0]->IsFunction()
|| !args[1]->IsFunction() || !args[2]->IsFunction()) {
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto p = new efl::eina::js::global_ref<Value>[3]{{isolate, args[0]},
{isolate, args[1]},
{isolate, args[2]}};
auto start_cb = [](void *data) -> void* {
auto p = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto isolate = v8::Isolate::GetCurrent();
auto o = p->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
return new efl::eina::js::global_ref<Value>{isolate, ret};
};
auto filter_cb = [](void *data, void *loop_data, int type,
void */*event*/) -> Eina_Bool {
typedef efl::eina::js::global_ref<Value> p_t;
auto p = static_cast<p_t*>(data) + 1;
auto isolate = v8::Isolate::GetCurrent();
auto o = p->handle();
Handle<Value> args[2]{
static_cast<p_t*>(loop_data)->handle(),
compatibility_new<Integer>(isolate, type)
};
auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
auto bret = ret->IsBoolean() && ret->BooleanValue();
return bret ? EINA_TRUE : EINA_FALSE;
};
auto end_cb = [](void *user_data, void *func_data) -> void {
typedef efl::eina::js::global_ref<Value> p_t;
auto loop_data = std::unique_ptr<p_t>(static_cast<p_t*>
(func_data));
auto p = static_cast<p_t*>(user_data) + 2;
auto o = p->handle();
Handle<Value> args = p->handle();
Function::Cast(*o)->Call(o->ToObject(), 1, &args);
};
auto ret = ecore_event_filter_add(start_cb, filter_cb, end_cb, p);
return compatibility_return(wrap_event_filter(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_current_type_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_event_current_type_get();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_memory_state_normal(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_MEMORY_STATE_NORMAL));
}
EAPI
void register_memory_state_low(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_MEMORY_STATE_LOW));
}
EAPI
void register_power_state_mains(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POWER_STATE_MAINS));
}
EAPI
void register_power_state_battery(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POWER_STATE_BATTERY));
}
EAPI
void register_power_state_low(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ECORE_POWER_STATE_LOW));
}
EAPI
void register_memory_state_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_memory_state_get();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_power_state_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_power_state_get();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_signal_user_handler_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::String;
using v8::Value;
using v8::Object;
using v8::Function;
using v8::Handle;
using v8::Local;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto isolate = args.GetIsolate();
auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
auto cb = [](void *d, int type, void *event) -> Eina_Bool {
auto p = static_cast<efl::eina::js::global_ref<Value>*>(d);
auto isolate = v8::Isolate::GetCurrent();
auto o = p->handle();
auto wrapped_event = compatibility_new<Object>(isolate);
{
auto n
= reinterpret_cast<Ecore_Event_Signal_User*>(event)->number;
wrapped_event->Set(compatibility_new<String>(isolate, "number"),
compatibility_new<Integer>(isolate, n));
}
Handle<Value> args[2]{
compatibility_new<Integer>(isolate, type),
wrapped_event
};
auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
auto bret = ret->IsBoolean() && ret->BooleanValue();
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER, cb, p);
return compatibility_return(wrap_event_handler(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_signal_exit_handler_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::Boolean;
using v8::String;
using v8::Value;
using v8::Object;
using v8::Function;
using v8::Handle;
using v8::Local;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto isolate = args.GetIsolate();
auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
auto cb = [](void *d, int type, void *ev) -> Eina_Bool {
auto p = static_cast<efl::eina::js::global_ref<Value>*>(d);
auto isolate = v8::Isolate::GetCurrent();
auto o = p->handle();
auto wrapped_event = compatibility_new<Object>(isolate);
{
auto event = reinterpret_cast<Ecore_Event_Signal_Exit*>(ev);
auto interrupt = event->interrupt;
auto quit = event->quit;
auto terminate = event->terminate;
wrapped_event->Set(compatibility_new<String>(isolate,
"interrupt"),
compatibility_new<Boolean>(isolate,
interrupt));
wrapped_event->Set(compatibility_new<String>(isolate, "quit"),
compatibility_new<Boolean>(isolate, quit));
wrapped_event->Set(compatibility_new<String>(isolate,
"terminate"),
compatibility_new<Boolean>(isolate,
terminate));
}
Handle<Value> args[2]{
compatibility_new<Integer>(isolate, type),
wrapped_event
};
auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
auto bret = ret->IsBoolean() && ret->BooleanValue();
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, cb, p);
return compatibility_return(wrap_event_handler(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_event_signal_realtime_handler_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::String;
using v8::Value;
using v8::Object;
using v8::Function;
using v8::Handle;
using v8::Local;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto isolate = args.GetIsolate();
auto p = new efl::eina::js::global_ref<Value>(isolate, args[0]);
auto cb = [](void *d, int type, void *ev) -> Eina_Bool {
auto p = static_cast<efl::eina::js::global_ref<Value>*>(d);
auto isolate = v8::Isolate::GetCurrent();
auto o = p->handle();
auto wrapped_event = compatibility_new<Object>(isolate);
{
auto n
= reinterpret_cast<Ecore_Event_Signal_Realtime*>(ev)->num;
wrapped_event->Set(compatibility_new<String>(isolate, "num"),
compatibility_new<Integer>(isolate, n));
}
Handle<Value> args[2]{
compatibility_new<Integer>(isolate, type),
wrapped_event
};
auto ret = Function::Cast(*o)->Call(o->ToObject(), 2, args);
auto bret = ret->IsBoolean() && ret->BooleanValue();
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_event_handler_add(ECORE_EVENT_SIGNAL_REALTIME, cb, p);
return compatibility_return(wrap_event_handler(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_ecore_event(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
register_event_none(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_EVENT_NONE"));
register_event_signal_user(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_SIGNAL_USER"));
register_event_signal_hup(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_SIGNAL_HUP"));
register_event_signal_exit(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_SIGNAL_EXIT"));
register_event_signal_power(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_SIGNAL_POWER"));
register_event_signal_realtime(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_SIGNAL_REALTIME"));
register_event_memory_state(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_MEMORY_STATE"));
register_event_power_state(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_POWER_STATE"));
register_event_locale_changed(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_LOCALE_CHANGED"));
register_event_hostname_changed(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_EVENT_HOSTNAME_CHANGED"));
register_event_system_timedate_changed(isolate, exports,
compatibility_new<v8::String>
(isolate,
"ECORE_EVENT_SYSTEM_TIMEDATE"
"_CHANGED"));
register_event_type_new(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_event_type_new"));
register_event_add(isolate, exports,
compatibility_new<v8::String>(isolate, "ecore_event_add"));
register_event_handler_add(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_event_handler_add"));
register_event_filter_add(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_event_filter_add"));
register_event_current_type_get(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_event_current_type_get"));
register_memory_state_normal(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_MEMORY_STATE_NORMAL"));
register_memory_state_low(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_MEMORY_STATE_LOW"));
register_power_state_mains(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_POWER_STATE_MAINS"));
register_power_state_battery(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_POWER_STATE_BATTERY"));
register_power_state_low(isolate, exports,
compatibility_new<v8::String>(isolate,
"ECORE_POWER_STATE_LOW"));
register_event_signal_user_handler_add(isolate, exports,
compatibility_new<v8::String>
(isolate,
"ecore_event_signal_user_handler"
"_add"));
register_event_signal_exit_handler_add(isolate, exports,
compatibility_new<v8::String>
(isolate,
"ecore_event_signal_exit_handler"
"_add"));
register_event_signal_realtime_handler_add(isolate, exports,
compatibility_new<v8::String>
(isolate,
"ecore_event_signal_realtime"
"_handler_add"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,294 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
static Ecore_Idler* extract_idler(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Idler*>(ptr);
}
static
v8::Local<v8::Object> wrap_idler(Ecore_Idler *idler, v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_idler_del(extract_idler(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->SetInternalField(0, compatibility_new<v8::External>(isolate, idler));
return ret;
}
static Ecore_Idle_Enterer* extract_idle_enterer(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Idle_Enterer*>(ptr);
}
static v8::Local<v8::Object> wrap_idle_enterer(Ecore_Idle_Enterer *idle_enterer,
v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
using v8::External;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_idle_enterer_del(extract_idle_enterer(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->SetInternalField(0,
compatibility_new<External>(isolate, idle_enterer));
return ret;
}
static Ecore_Idle_Exiter* extract_idle_exiter(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Idle_Exiter*>(ptr);
}
static v8::Local<v8::Object> wrap_idle_exiter(Ecore_Idle_Exiter *idle_exiter,
v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
using v8::External;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_idle_exiter_del(extract_idle_exiter(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->SetInternalField(0, compatibility_new<External>(isolate, idle_exiter));
return ret;
}
void register_idler_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
auto ret = ecore_idler_add([](void *data) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
}, f);
return compatibility_return(wrap_idler(ret, args.GetIsolate()), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_idle_enterer_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
auto ret = ecore_idle_enterer_add([](void *data) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
}, f);
return compatibility_return(wrap_idle_enterer(ret, args.GetIsolate()),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_idle_enterer_before_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
auto ret = ecore_idle_enterer_before_add([](void *data) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
}, f);
return compatibility_return(wrap_idle_enterer(ret, args.GetIsolate()),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_idle_exiter_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
auto ret = ecore_idle_exiter_add([](void *data) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
}, f);
return compatibility_return(wrap_idle_exiter(ret, args.GetIsolate()),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_ecore_idle(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
register_idler_add(isolate, exports,
compatibility_new<v8::String>(isolate, "ecore_idler_add"));
register_idle_enterer_add(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_idle_enterer"
"_add"));
register_idle_enterer_before_add(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_idle"
"_enterer_before"
"_add"));
register_idle_exiter_add(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_idle_exiter_add"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,76 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
namespace {
void register_init(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto init = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ::ecore_init();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, init)
->GetFunction());
}
void register_shutdown(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto shutdown = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_shutdown();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, shutdown)
->GetFunction());
}
}
EAPI
void register_ecore(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
efl::ecore::js::register_init(isolate, exports,
efl::eina::js::compatibility_new<v8::String>
(isolate, "ecore_init"));
efl::ecore::js::register_shutdown(isolate, exports,
efl::eina::js::compatibility_new<v8::String>
(isolate, "ecore_shutdown"));
register_ecore_animator(isolate, exports);
register_ecore_event(isolate, exports);
register_ecore_idle(isolate, exports);
register_ecore_job(isolate, exports);
register_ecore_mainloop(isolate, exports);
register_ecore_poller(isolate, exports);
register_ecore_throttle(isolate, exports);
register_ecore_timer(isolate, exports);
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,83 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
static Ecore_Job* extract_job(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Job*>(ptr);
}
static v8::Local<v8::Object> wrap_job(Ecore_Job *job, v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_job_del(extract_job(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->SetInternalField(0, compatibility_new<v8::External>(isolate, job));
return ret;
}
EAPI
void register_job_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[0]);
auto ret = ecore_job_add([](void *data) {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
persistent->dispose();
delete persistent;
}, f);
return compatibility_return(wrap_job(ret, args.GetIsolate()), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_ecore_job(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
register_job_add(isolate, exports,
compatibility_new<v8::String>(isolate, "ecore_job_add"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,207 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
namespace {
void register_callback_cancel(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Boolean;
global->Set(name, compatibility_new<Boolean>(isolate,
bool{ECORE_CALLBACK_CANCEL}));
}
void register_callback_renew(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Boolean;
global->Set(name, compatibility_new<Boolean>(isolate,
bool{ECORE_CALLBACK_RENEW}));
}
void register_callback_pass_on(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Boolean;
global->Set(name, compatibility_new<Boolean>(isolate,
bool{ECORE_CALLBACK_PASS_ON}));
}
void register_callback_done(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Boolean;
global->Set(name, compatibility_new<Boolean>(isolate,
bool{ECORE_CALLBACK_DONE}));
}
void register_mainloop_iterate(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
ecore_main_loop_iterate();
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_mainloop_iterate_may_block(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
auto ret = ecore_main_loop_iterate_may_block(args[0]->NumberValue());
return compatibility_return(compatibility_new<Integer>
(args.GetIsolate(), ret), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_mainloop_begin(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
ecore_main_loop_begin();
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_mainloop_quit(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
ecore_main_loop_quit();
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_mainloop_animator_ticked_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Boolean;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto ret = ecore_main_loop_animator_ticked_get();
return compatibility_return(compatibility_new<Boolean>
(args.GetIsolate(), ret), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_mainloop_nested_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Boolean;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto ret = ecore_main_loop_nested_get();
return compatibility_return(compatibility_new<Boolean>
(args.GetIsolate(), ret), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
}
EAPI
void register_ecore_mainloop(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
register_callback_cancel(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_CALLBACK_CANCEL"));
register_callback_renew(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_CALLBACK_RENEW"));
register_callback_pass_on(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_CALLBACK_PASS_ON"));
register_callback_done(isolate, exports,
compatibility_new<v8::String>
(isolate, "ECORE_CALLBACK_DONE"));
register_mainloop_iterate(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_mainloop_iterate"));
register_mainloop_iterate_may_block(isolate, exports,
compatibility_new<v8::String>
(isolate,
"ecore_mainloop_iterate_may_block"));
register_mainloop_begin(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_mainloop_begin"));
register_mainloop_quit(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_mainloop_quit"));
register_mainloop_animator_ticked_get(isolate, exports,
compatibility_new<v8::String>
(isolate,
"ecore_mainlop_animator_ticked_get"));
register_mainloop_nested_get(isolate, exports,
compatibility_new<v8::String>
(isolate, "ecore_mainloop_nested_get"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,190 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
namespace {
Ecore_Poller* extract_poller(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Poller*>(ptr);
}
v8::Local<v8::Object> wrap_poller(Ecore_Poller *poller,
v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_poller_del(extract_poller(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->SetInternalField(0, compatibility_new<v8::External>(isolate, poller));
return ret;
}
void register_poller_core(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name, compatibility_new<Integer>(isolate, ECORE_POLLER_CORE));
}
void register_poller_poll_interval_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
return compatibility_return();
Ecore_Poller_Type type;
switch ((int)(args[0]->NumberValue())) {
case ECORE_POLLER_CORE:
type = ECORE_POLLER_CORE;
break;
default:
return compatibility_return();
}
ecore_poller_poll_interval_set(type, args[1]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_poller_poll_interval_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
Ecore_Poller_Type type;
switch ((int)(args[0]->NumberValue())) {
case ECORE_POLLER_CORE:
type = ECORE_POLLER_CORE;
break;
default:
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto ret = ecore_poller_poll_interval_get(type);
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_poller_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::Value;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Function;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
|| !args[2]->IsFunction()) {
return compatibility_return();
}
Ecore_Poller_Type type;
switch ((int)(args[0]->NumberValue())) {
case ECORE_POLLER_CORE:
type = ECORE_POLLER_CORE;
break;
default:
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto f = new efl::eina::js::global_ref<Value>(isolate, args[2]);
auto cb = [](void *data) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_poller_add(type, args[1]->NumberValue(), cb, f);
return compatibility_return(wrap_poller(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
}
EAPI
void register_ecore_poller(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
register_poller_core(isolate, exports,
compatibility_new<v8::String>(isolate, "ECORE_POLLER_CORE"));
register_poller_poll_interval_set(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_poller"
"_poll_interval"
"_set"));
register_poller_poll_interval_get(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_poller"
"_poll_interval"
"_get"));
register_poller_add(isolate, exports,
compatibility_new<v8::String>(isolate, "ecore_poller_add"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,63 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
namespace efl { namespace ecore { namespace js {
namespace {
void register_throttle_adjust(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
ecore_throttle_adjust(args[0]->NumberValue());
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_throttle_get(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Number;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = ecore_throttle_get();
return compatibility_return(compatibility_new<Number>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
}
EAPI
void register_ecore_throttle(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
register_throttle_adjust(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_throttle_adjust"));
register_throttle_get(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_throttle_get"));
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,232 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore_Js.hh>
#include <memory>
#include <cstdlib>
namespace efl { namespace ecore { namespace js {
namespace {
Ecore_Timer* extract_timer(v8::Local<v8::Object> object)
{
auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
return reinterpret_cast<Ecore_Timer*>(ptr);
}
v8::Local<v8::Object> wrap_timer(Ecore_Timer *timer,
v8::Isolate *isolate)
{
using v8::Boolean;
using v8::String;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_timer_del(extract_timer(info.This()));
return compatibility_return();
};
auto freeze = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_timer_freeze(extract_timer(info.This()));
return compatibility_return();
};
auto freeze_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto ret = ecore_timer_freeze_get(extract_timer(info.This()));
return compatibility_return(compatibility_new<Boolean>
(info.GetIsolate(), bool(ret)),
info);
};
auto thaw = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
ecore_timer_thaw(extract_timer(info.This()));
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "freeze"),
compatibility_new<FunctionTemplate>(isolate, freeze)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "freeze_get"),
compatibility_new<FunctionTemplate>(isolate, freeze_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "thaw"),
compatibility_new<FunctionTemplate>(isolate, thaw)->GetFunction());
ret->SetInternalField(0, compatibility_new<v8::External>(isolate, timer));
return ret;
}
void register_timer_precision_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Number;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto ret = ecore_timer_precision_get();
return compatibility_return(compatibility_new<Number>
(args.GetIsolate(), ret), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_timer_precision_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
ecore_timer_precision_set(args[0]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_timer_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsNumber()
|| !args[1]->IsFunction()) {
return compatibility_return();
}
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
auto cb = [](void *data) -> Eina_Bool {
auto persistent = reinterpret_cast<efl::eina::js::global_ref<Value>*>(data);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_timer_add(args[0]->NumberValue(), cb, f);
return compatibility_return(wrap_timer(ret, args.GetIsolate()), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_timer_loop_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Local;
using v8::Value;
using v8::Undefined;
using v8::Function;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsNumber()
|| !args[1]->IsFunction()) {
return compatibility_return();
}
auto f = new efl::eina::js::global_ref<Value>(args.GetIsolate(), args[1]);
auto cb = [](void *d) -> Eina_Bool {
auto persistent = static_cast<efl::eina::js::global_ref<Value>*>(d);
auto o = persistent->handle();
auto ret = Function::Cast(*o)->Call(o->ToObject(), 0, NULL);
auto bret = ret->IsBoolean() && ret->BooleanValue();
if (!bret)
{
persistent->dispose();
delete persistent;
}
return bret ? EINA_TRUE : EINA_FALSE;
};
auto ret = ecore_timer_loop_add(args[0]->NumberValue(), cb, f);
return compatibility_return(wrap_timer(ret, args.GetIsolate()), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
}
EAPI
void register_ecore_timer(v8::Isolate *isolate,v8::Handle<v8::Object> exports)
{
register_timer_precision_get(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_timer_precision"
"_get"));
register_timer_precision_set(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_timer_precision"
"_set"));
register_timer_add(isolate, exports,
compatibility_new<v8::String>(isolate, "ecore_timer_add"));
register_timer_loop_add(isolate, exports,
compatibility_new<v8::String>(isolate,
"ecore_timer_loop_add"));
}
} } } // namespace efl { namespace ecore { namespace js {

View File

@ -0,0 +1,38 @@
#ifndef ECORE_JS_TIMER_HH
#define ECORE_JS_TIMER_HH
#include <Eina.hh>
#include <Eina_Js.hh>
namespace efl { namespace ecore { namespace js {
using ::efl::eina::js::compatibility_new;
using ::efl::eina::js::compatibility_return_type;
using ::efl::eina::js::compatibility_callback_info_type;
using ::efl::eina::js::compatibility_return;
using ::efl::eina::js::compatibility_get_pointer_internal_field;
using ::efl::eina::js::compatibility_set_pointer_internal_field;
using ::efl::eina::js::compatibility_persistent;
void register_timer_precision_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_timer_precision_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_timer_dump(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_timer_add(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_timer_loop_add(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
} } } // namespace efl::js
#endif /* ECORE_JS_TIMER_HH */

View File

@ -0,0 +1,30 @@
#ifndef EFL_EFL_JS_HH
#define EFL_EFL_JS_HH
#include <Eina.hh>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# define EAPI __declspec(dllexport)
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
namespace efl_js {
EAPI void init(v8::Handle<v8::Object> exports);
}
#endif

View File

@ -0,0 +1,241 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Efl.h>
#include <Efl_Config.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Eina.hh>
#include <Eina_Js.hh>
#include <Ecore_Js.hh>
#include <Eio_Js.hh>
#include <Eldbus_Js.hh>
#include <Ethumb_Js.hh>
#include <iostream>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# define EAPI __declspec(dllexport)
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
EAPI void eina_container_register(v8::Handle<v8::Object>, v8::Isolate* isolate);
EAPI void eina_log_register(v8::Handle<v8::Object>, v8::Isolate* isolate);
EAPI void eina_value_register(v8::Handle<v8::Object>, v8::Isolate* isolate);
EAPI void register_ecore_mainloop(v8::Handle<v8::Object> global, v8::Isolate* isolate);
namespace ecore {
EAPI void register_exe(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_idler(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
namespace idle {
EAPI void register_enterer(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_exiter(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}
EAPI void register_job(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_parent(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_poller(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_timer(v8::Handle<v8::Object> global, v8::Isolate* isolate);
namespace con {
EAPI void register_base(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_client(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_connector(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_server(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}
}
namespace efl { namespace network {
EAPI void register_url(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}}
EAPI void register_ecore_audio(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore_audio_in(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore_audio_in_sndfile(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore_audio_in_tone(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore_audio_out(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore_audio_out_pulse(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_ecore_audio_out_sndfile(v8::Handle<v8::Object> global, v8::Isolate* isolate);
namespace efl {
EAPI void register_control(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_file(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_image(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_player(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_text(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_text_properties(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}
namespace eo {
EAPI void register_abstract_class(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_base(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}
namespace evas {
EAPI void register_box(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_canvas(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_clickable_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_common_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_draggable_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_grid(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_image(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_line(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_object(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_object_smart(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_out(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_polygon(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_rectangle(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_scrollable_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_selectable_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_signal_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_smart_clipped(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_table(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_text(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_textblock(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_textgrid(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_zoomable_interface(v8::Handle<v8::Object> global, v8::Isolate* isolate);
namespace canvas3d {
EAPI void register_camera(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_light(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_material(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_mesh(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_node(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_object(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_scene(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_texture(v8::Handle<v8::Object> global, v8::Isolate* isolate);
} }
namespace edje {
EAPI void register_edit(v8::Handle<v8::Object> global, v8::Isolate* isolate);
EAPI void register_object(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}
namespace emotion {
EAPI void register_object(v8::Handle<v8::Object> global, v8::Isolate* isolate);
}
#ifdef HAVE_NODEJS
#include <eina_js_node.hh>
namespace {
#else
namespace efl_js {
#endif
EAPI void init(v8::Handle<v8::Object> exports)
{
::eina_init();
::ecore_init();
::ecore_file_init();
::ecore_evas_init();
::eo_init();
::eio_init();
::evas_init();
try
{
eina_container_register(exports, v8::Isolate::GetCurrent());
eina_log_register(exports, v8::Isolate::GetCurrent());
eina_value_register(exports, v8::Isolate::GetCurrent());
register_ecore_mainloop(exports, v8::Isolate::GetCurrent());
efl::ecore::js::register_ecore(v8::Isolate::GetCurrent(), exports);
efl::eio::js::register_eio(v8::Isolate::GetCurrent(), exports);
efl::eldbus::js::register_eldbus(v8::Isolate::GetCurrent(), exports);
efl::ethumb::js::register_ethumb(v8::Isolate::GetCurrent(), exports);
ecore::register_exe(exports, v8::Isolate::GetCurrent());
ecore::register_idler(exports, v8::Isolate::GetCurrent());
ecore::idle::register_enterer(exports, v8::Isolate::GetCurrent());
ecore::idle::register_exiter(exports, v8::Isolate::GetCurrent());
ecore::register_job(exports, v8::Isolate::GetCurrent());
ecore::register_parent(exports, v8::Isolate::GetCurrent());
ecore::register_poller(exports, v8::Isolate::GetCurrent());
ecore::register_timer(exports, v8::Isolate::GetCurrent());
ecore::con::register_base(exports, v8::Isolate::GetCurrent());
ecore::con::register_client(exports, v8::Isolate::GetCurrent());
ecore::con::register_connector(exports, v8::Isolate::GetCurrent());
ecore::con::register_server(exports, v8::Isolate::GetCurrent());
efl::network::register_url(exports, v8::Isolate::GetCurrent());
#if 1
register_ecore_audio(exports, v8::Isolate::GetCurrent());
register_ecore_audio_in(exports, v8::Isolate::GetCurrent());
register_ecore_audio_in_sndfile(exports, v8::Isolate::GetCurrent());
register_ecore_audio_in_tone(exports, v8::Isolate::GetCurrent());
register_ecore_audio_out(exports, v8::Isolate::GetCurrent());
register_ecore_audio_out_pulse(exports, v8::Isolate::GetCurrent());
register_ecore_audio_out_sndfile(exports, v8::Isolate::GetCurrent());
#endif
efl::register_control(exports, v8::Isolate::GetCurrent());
efl::register_file(exports, v8::Isolate::GetCurrent());
efl::register_image(exports, v8::Isolate::GetCurrent());
efl::register_player(exports, v8::Isolate::GetCurrent());
efl::register_text(exports, v8::Isolate::GetCurrent());
efl::register_text_properties(exports, v8::Isolate::GetCurrent());
eo::register_abstract_class(exports, v8::Isolate::GetCurrent());
eo::register_base(exports, v8::Isolate::GetCurrent());
#if 1
evas::register_box(exports, v8::Isolate::GetCurrent());
evas::register_canvas(exports, v8::Isolate::GetCurrent());
evas::register_clickable_interface(exports, v8::Isolate::GetCurrent());
evas::register_common_interface(exports, v8::Isolate::GetCurrent());
evas::register_draggable_interface(exports, v8::Isolate::GetCurrent());
evas::register_grid(exports, v8::Isolate::GetCurrent());
evas::register_image(exports, v8::Isolate::GetCurrent());
evas::register_line(exports, v8::Isolate::GetCurrent());
evas::register_object(exports, v8::Isolate::GetCurrent());
evas::register_object_smart(exports, v8::Isolate::GetCurrent());
evas::register_out(exports, v8::Isolate::GetCurrent());
evas::register_polygon(exports, v8::Isolate::GetCurrent());
evas::register_rectangle(exports, v8::Isolate::GetCurrent());
evas::register_scrollable_interface(exports, v8::Isolate::GetCurrent());
evas::register_selectable_interface(exports, v8::Isolate::GetCurrent());
evas::register_signal_interface(exports, v8::Isolate::GetCurrent());
evas::register_smart_clipped(exports, v8::Isolate::GetCurrent());
evas::register_table(exports, v8::Isolate::GetCurrent());
evas::register_text(exports, v8::Isolate::GetCurrent());
evas::register_textblock(exports, v8::Isolate::GetCurrent());
evas::register_textgrid(exports, v8::Isolate::GetCurrent());
evas::register_zoomable_interface(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_camera(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_light(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_material(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_mesh(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_node(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_object(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_scene(exports, v8::Isolate::GetCurrent());
evas::canvas3d::register_texture(exports, v8::Isolate::GetCurrent());
#endif
#if 1
edje::register_edit(exports, v8::Isolate::GetCurrent());
edje::register_object(exports, v8::Isolate::GetCurrent());
#endif
#if 1
emotion::register_object(exports, v8::Isolate::GetCurrent());
#endif
}
catch(...)
{
std::cout << "Exception" << std::endl;
}
}
#ifdef HAVE_NODEJS
}
NODE_MODULE(efl, init)
#else
} // namespace efl
#endif

View File

@ -0,0 +1,50 @@
#ifndef EFL_EINA_JS_HH
#define EFL_EINA_JS_HH
#include <Eina.hh>
#include <eo_concrete.hh>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_EINA_JS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_ECORE_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
#include <eina_js_container.hh>
#include <eina_js_accessor.hh>
#include <eina_js_array.hh>
#include <eina_js_compatibility.hh>
#include <eina_js_error.hh>
#include <eina_js_get_value_from_c.hh>
#include <eina_js_get_value.hh>
#include <eina_js_iterator.hh>
#include <eina_js_list.hh>
#include <eina_js_log.hh>
#include <eina_js_value.hh>
#include <eina_js_log.hh>
#undef EAPI
#define EAPI
#endif

View File

@ -0,0 +1,34 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eina.hh>
#include <Eina_Js.hh>
#include <iostream>
namespace efl { namespace eina { namespace js {
EAPI void register_destroy_accessor(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
typedef void (*deleter_t)(void*);
auto f = [](compatibility_callback_info_type info) -> compatibility_return_type
{
if (info.Length() != 1 || !info[0]->IsObject())
return compatibility_return();
v8::Handle<v8::Object> o = info[0]->ToObject();
deleter_t deleter = compatibility_get_pointer_internal_field<deleter_t>(o, 1);
deleter(compatibility_get_pointer_internal_field<>(o, 0));
return compatibility_return();
};
global->Set(name, compatibility_new<v8::FunctionTemplate>(isolate, f)->GetFunction());
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,87 @@
#ifndef EINA_JS_ACCESSOR_HH
#define EINA_JS_ACCESSOR_HH
#include <memory>
#include <eina_js_value.hh>
#include <eina_js_compatibility.hh>
#include <eina_js_get_value.hh>
#include <eina_js_get_value_from_c.hh>
#include <iostream>
namespace efl { namespace eina { namespace js {
template <typename T, typename A>
js::compatibility_return_type accessor_get(js::compatibility_callback_info_type info)
{
v8::Isolate* isolate = info.GetIsolate();
if (info.Length() != 1 || !info[0]->IsNumber())
return js::compatibility_return();
auto idx = js::get_value_from_javascript
(info[0], isolate, "", js::value_tag<std::size_t>());
std::string class_name;
if (info.Data()->IsString())
{
v8::String::Utf8Value str(info.Data());
class_name = *str;
}
void *ptr = compatibility_get_pointer_internal_field(info.Holder(), 0);
return compatibility_return
(::efl::eina::js::get_value_from_c
(js::wrap_value<T>(container_unwrap((*static_cast<A*>(ptr))[idx]), js::value_tag<T>{})
, isolate, class_name.c_str()), info);
};
/* Creates a copy from \p a accessor and exports it to be manipulated by the JS
code */
template <typename T, typename W>
inline v8::Local<v8::Object> export_accessor(::efl::eina::accessor<W> &a, v8::Isolate *isolate, const char* class_name)
{
typedef ::efl::eina::accessor<W> accessor_type;
static efl::eina::js::global_ref<v8::ObjectTemplate> obj_tpl
(isolate,
[&]()
{
auto obj_tpl = compatibility_new<v8::ObjectTemplate>(isolate);
(*obj_tpl)->SetInternalFieldCount(1);
// TODO: (*obj_tpl)->SetIndexedPropertyHandler(&accessor_get<accessor_type>);
(*obj_tpl)->Set(js::compatibility_new<v8::String>(isolate, "get")
, js::compatibility_new<v8::FunctionTemplate>(isolate
, &accessor_get<T, accessor_type>
, js::compatibility_new<v8::String>(isolate, class_name)));
return obj_tpl;
}());
auto instance = obj_tpl.handle()->NewInstance();
compatibility_set_pointer_internal_field(instance, 0, &a);
return instance;
}
/* Extracts and returns a copy from the internal accessor object from the JS
object */
template <typename T>
::efl::eina::accessor<T>& import_accessor(v8::Handle<v8::Object> o)
{
typedef ::efl::eina::accessor<T> accessor_type;
void* ptr = compatibility_get_pointer_internal_field(o, 0);
return *static_cast<accessor_type*>(ptr);
}
/* Registers the function to destroy the accessor objects to the JS code */
void register_destroy_accessor(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
} } } // namespace efl::js
#endif /* EINA_JS_ACCESSOR_HH */

View File

@ -0,0 +1,119 @@
#ifndef EINA_JS_ARRAY_HH
#define EINA_JS_ARRAY_HH
#include <iostream>
#include <iterator>
#include <eina_js_container.hh>
namespace efl { namespace eina { namespace js {
template <typename T, typename K, typename W>
struct eina_array : eina_container_common<efl::eina::array
<W
, typename std::conditional
<std::is_base_of<efl::eo::concrete, W>::value
, efl::eina::eo_clone_allocator
, efl::eina::malloc_clone_allocator
>::type>, T, K>
{
typedef eina_container_common<efl::eina::array<W
, typename std::conditional
<std::is_base_of<efl::eo::concrete, W>::value
, efl::eina::eo_clone_allocator
, efl::eina::malloc_clone_allocator
>::type>, T, K> base_type;
using base_type::base_type;
typedef typename base_type::container_type container_type;
eina_container_base* concat(eina_container_base const& other) const
{
return detail::concat(*this, other);
}
eina_container_base* slice(std::int64_t i, std::int64_t j) const
{
return detail::slice(*this, i, j);
}
v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t index, v8::Local<v8::Value> v)
{
return detail::set<T,W>(isolate, *this, index, v);
}
int push(v8::Isolate* isolate, v8::Local<v8::Value> v)
{
return detail::push<T,W>(isolate, *this, v);
}
v8::Local<v8::Value> pop(v8::Isolate* isolate)
{
return detail::pop<T,W,K>(isolate, *this);
}
js::container_type get_container_type() const { return array_container_type; }
};
template <typename T, typename K, typename W>
struct range_eina_array : eina_container_common<efl::eina::range_array<W>, T, K>
{
typedef eina_container_common<efl::eina::range_array<W>, T, K> base_type;
using base_type::base_type;
typedef typename base_type::container_type container_type;
typedef typename std::conditional
<std::is_base_of<efl::eo::concrete, W>::value
, efl::eina::eo_clone_allocator
, efl::eina::malloc_clone_allocator
>::type clone_allocator_type;
eina_container_base* concat(eina_container_base const& other) const
{
range_eina_array<T, K, W> const& rhs = static_cast<range_eina_array<T, K, W>const&>(other);
efl::eina::array<W, clone_allocator_type>
array(this->_container.begin(), this->_container.end());
array.insert(array.end(), rhs._container.begin(), rhs._container.end());
return new eina_array<T, K, W>(array.release_native_handle());
}
eina_container_base* slice(std::int64_t i, std::int64_t j) const
{
efl::eina::array<W, clone_allocator_type>
array(std::next(this->_container.begin(), i), std::next(this->_container.begin(), j));
return new eina_array<T, K, W>(array.release_native_handle());
}
js::container_type get_container_type() const { return array_container_type; }
};
// Problematic types.
template <>
struct eina_array<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
: empty_container_base
{ eina_array(Eina_Array const*){} };
template <>
struct eina_array<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
: empty_container_base
{ eina_array(Eina_Array const*){} };
template <>
struct eina_array<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
: empty_container_base
{ eina_array(Eina_Array const*){} };
template <>
struct eina_array<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
: empty_container_base
{ eina_array(Eina_Array const*){} };
template <>
struct range_eina_array<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
: empty_container_base
{ range_eina_array(Eina_Array const*){} };
template <>
struct range_eina_array<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
: empty_container_base
{ range_eina_array(Eina_Array const*){} };
template <>
struct range_eina_array<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
: empty_container_base
{ range_eina_array(Eina_Array const*){} };
template <>
struct range_eina_array<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
: empty_container_base
{ range_eina_array(Eina_Array const*){} };
} } }
#endif

View File

@ -0,0 +1,12 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eina.hh>
#include <Eina_Js.hh>
namespace efl { namespace eina { namespace js {
std::map<std::string, v8::Local<v8::Function>> constructors_map_;
} } }

View File

@ -0,0 +1,918 @@
#ifndef EFL_EINA_JS_COMPATIBILITY_HH
#define EFL_EINA_JS_COMPATIBILITY_HH
#include <type_traits>
#include <utility>
#include <map>
#include <string>
#include <cstdlib>
#ifdef HAVE_NODE_V8_H
#include <node/v8.h>
#elif defined(HAVE_NODEJS_DEPS_V8_V8_H)
#include <nodejs/deps/v8/v8.h>
#elif defined(HAVE_NODEJS_DEPS_V8_INCLUDE_V8_H)
#include <nodejs/deps/v8/include/v8.h>
#elif defined(HAVE_NODEJS_SRC_V8_H)
#include <nodejs/src/v8.h>
#elif defined(HAVE_V8_H)
#include <v8.h>
#else
#error We must have at least one v8 header to include
#endif
namespace v8 {
template <typename T>
struct FunctionCallbackInfo;
template <typename T>
struct PropertyCallbackInfo;
template <typename T>
#ifdef HAVE_V8_GLOBAL
struct Global;
#else
struct UniquePersistent;
#endif
class AccessorInfo;
class Arguments;
}
namespace efl { namespace eina { namespace js {
template <typename T>
struct value_tag
{
typedef T type;
};
template <typename T, typename... U>
struct complex_tag
{
T value;
typedef std::tuple<U...> inner_types;
};
template <typename T>
struct make_tag_traits
{
typedef typename std::remove_reference<T>::type a1;
typedef typename std::conditional
<std::is_pointer<T>::value
, typename std::remove_cv<T>::type
, T>::type type;
};
template <typename T, typename... U>
using make_complex_tag = complex_tag<typename make_tag_traits<T>::type
, typename make_tag_traits<U>::type...>;
template <typename T>
struct struct_tag
{
T value;
};
template <typename T>
using make_struct_tag = struct_tag<typename make_tag_traits<T>::type>;
template <typename T>
struct struct_ptr_tag
{
T value;
};
template <typename T>
using make_struct_ptr_tag = struct_ptr_tag<typename make_tag_traits<T>::type>;
template <typename T, typename... Ts>
struct remove_tag
{
typedef T type;
};
template <typename T, typename... U>
struct remove_tag<complex_tag<T, U...>>
{
typedef typename eina::js::remove_tag<T, U...>::type type;
};
template <typename T>
struct remove_tag<struct_tag<T>>
{
typedef typename eina::js::remove_tag<T>::type type;
};
template <typename T>
struct remove_tag<struct_ptr_tag<T>>
{
typedef typename eina::js::remove_tag<T>::type type;
};
template <typename T>
struct is_handable_by_value
{
static constexpr bool value = !std::is_class<T>::value || std::is_same<T, ::efl::eo::concrete>::value;
};
template <typename... T>
struct container_wrapper
{
typedef typename eina::js::remove_tag<T...>::type _notag_type;
typedef typename std::conditional<
std::is_convertible<_notag_type, Eo const* const>::value
, typename std::conditional<
std::is_const<typename std::remove_pointer<_notag_type>::type>::value
, ::efl::eo::concrete const
, ::efl::eo::concrete
>::type
, _notag_type
>::type type;
};
template <typename T>
T container_wrap(T&& v)
{
return std::forward<T>(v);
}
inline ::efl::eo::concrete container_wrap(Eo* v)
{
if(v)
eo_ref(v);
return ::efl::eo::concrete{v};
}
inline ::efl::eo::concrete container_wrap(Eo const* v)
{
if (v)
eo_ref(v);
return ::efl::eo::concrete{const_cast<Eo*>(v)};
}
template <typename T>
T& container_unwrap(T& v)
{
return v;
}
inline Eo* container_unwrap(::efl::eo::concrete& v)
{
return v._eo_ptr();
}
inline Eo* container_unwrap(::efl::eo::concrete const& v)
{
return v._eo_ptr();
}
template <typename T>
struct is_complex_tag : std::false_type {};
template <typename... T>
struct is_complex_tag<complex_tag<T...>> : std::true_type {};
template <typename T>
struct is_struct_tag : std::false_type {};
template <typename T>
struct is_struct_tag<struct_tag<T>> : std::true_type {};
template <typename T>
struct is_struct_ptr_tag : std::false_type {};
template <typename T>
struct is_struct_ptr_tag<struct_ptr_tag<T>> : std::true_type {};
template <typename T>
struct is_type_tag
{
static constexpr bool value =
is_complex_tag<T>::value
|| is_struct_tag<T>::value
|| is_struct_ptr_tag<T>::value;
};
// Class name getters
struct cls_name_getter_base {};
struct cls_name_getter_generated_base : cls_name_getter_base {};
/// Name getter for types that are not classes
struct nonclass_cls_name_getter : cls_name_getter_base
{
static char const* class_name() { return ""; }
};
// JS container base
enum container_type
{
list_container_type
, array_container_type
, container_type_size
};
struct eina_container_base
{
virtual ~eina_container_base() {}
virtual std::size_t size() const = 0;
virtual eina_container_base* concat(eina_container_base const& rhs) const = 0;
virtual eina_container_base* slice(std::int64_t i, std::int64_t j) const = 0;
virtual int index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const = 0;
virtual int last_index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const = 0;
virtual v8::Local<v8::Value> get(v8::Isolate*, std::size_t) const = 0;
virtual v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t index, v8::Local<v8::Value> v) = 0;
virtual int push(v8::Isolate* isolate, v8::Local<v8::Value> v) = 0;
virtual v8::Local<v8::Value> pop(v8::Isolate* isolate) = 0;
virtual v8::Local<v8::String> to_string(v8::Isolate*) const = 0;
virtual v8::Local<v8::String> join(v8::Isolate*, v8::Local<v8::Value> separator) const = 0;
virtual container_type get_container_type() const = 0;
virtual void* get_container_native_handle() = 0;
virtual void const* get_container_native_handle() const = 0;
};
// Containers forward declarations
// Array
template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
struct eina_array;
template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
struct range_eina_array;
EAPI v8::Handle<v8::Function> get_array_instance_template();
// List
template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
struct eina_list;
template <typename T, typename K = nonclass_cls_name_getter, typename W = typename container_wrapper<T>::type>
struct range_eina_list;
EAPI v8::Handle<v8::Function> get_list_instance_template();
// Accessor
template <typename T, typename W>
v8::Local<v8::Object> export_accessor(::efl::eina::accessor<W>&, v8::Isolate*, const char*);
template <typename T>
::efl::eina::accessor<T>& import_accessor(v8::Handle<v8::Object>);
// Wrap value functions
template <typename R, typename T>
typename std::remove_cv<typename std::remove_reference<R>::type>::type
wrap_value(T v, value_tag<R>
, typename std::enable_if<!is_type_tag<typename std::remove_cv<R>::type>::value>::type* = 0)
{
return v;
}
template <typename R, typename T>
R wrap_value(T const& v, value_tag<eina::js::struct_tag<T>>)
{
return R {v};
}
template <typename R, typename T>
R wrap_value(T v, value_tag<eina::js::struct_ptr_tag<T>>)
{
return R {v};
}
template <typename R, typename T, typename... U>
R wrap_value(T v, value_tag<eina::js::complex_tag<T, U...>>)
{
return R {v};
}
template <typename T = v8::External>
struct _libv8_isolate_test
{
using new_signature = v8::Local<T>(*)(v8::Isolate*, void*);
static const bool value = std::is_same<decltype(static_cast<new_signature>(&T::New)), new_signature>::value;
};
template <typename T = v8::FunctionTemplate, typename Enable = void>
struct _libv8_callback_info_test;
typedef v8::Handle<v8::Value>(*_libv8_invocation_callback)(v8::Arguments const&);
template <typename T>
struct _libv8_callback_info_test
<T, typename std::enable_if
<!std::is_same<decltype( & T::SetCallHandler)
, void (T::*)(_libv8_invocation_callback, v8::Handle<v8::Value>)>::value>::type>
: std::true_type
{
};
template <typename T>
struct _libv8_callback_info_test
<T, typename std::enable_if
<std::is_same<decltype( & T::SetCallHandler)
, void (T::*)(_libv8_invocation_callback, v8::Handle<v8::Value>)>::value>::type>
: std::false_type
{
};
template <typename T = v8::ObjectTemplate, typename Enable = void>
struct _libv8_property_callback_info_test
: std::true_type {};
typedef v8::Handle<v8::Value>(*_libv8_getter_callback)(v8::Local<v8::String>, v8::AccessorInfo const&);
typedef void(*_libv8_setter_callback)(v8::Local<v8::String>, v8::Local<v8::Value>, v8::AccessorInfo const&);
template <typename T>
struct _libv8_property_callback_info_test
<T, typename std::enable_if
<std::is_same<decltype( & T::SetAccessor)
, void (T::*)
(v8::Handle<v8::String>
, _libv8_getter_callback
, _libv8_setter_callback
, v8::Handle<v8::Value>
, v8::AccessControl
, v8::PropertyAttribute
, v8::Handle<v8::AccessorSignature>
)>::value>::type>
: std::false_type
{
};
static constexpr bool const v8_uses_isolate = _libv8_isolate_test<>::value;
static constexpr bool const v8_uses_callback_info = _libv8_callback_info_test<>::value;
static constexpr bool const v8_uses_property_callback_info = _libv8_property_callback_info_test<>::value;
using compatibility_return_type = std::conditional<v8_uses_callback_info, void, v8::Handle<v8::Value> >::type;
using compatibility_callback_info_type
= std::conditional<v8_uses_callback_info, v8::FunctionCallbackInfo<v8::Value> const&, v8::Arguments const&>
::type;
using compatibility_callback_info_pointer
= std::conditional<v8_uses_callback_info, v8::FunctionCallbackInfo<v8::Value> const*, v8::Arguments const*>
::type;
typedef compatibility_return_type(*compatibility_function_callback)(compatibility_callback_info_type);
using compatibility_accessor_getter_return_type
= std::conditional<v8_uses_property_callback_info, void, v8::Handle<v8::Value> >::type;
using compatibility_accessor_getter_callback_info_type
= std::conditional<v8_uses_property_callback_info
, v8::PropertyCallbackInfo<v8::Value> const&, v8::AccessorInfo const&>
::type;
using compatibility_accessor_setter_return_type
= void;
using compatibility_accessor_setter_callback_info_type
= std::conditional<v8_uses_property_callback_info
, v8::PropertyCallbackInfo<void> const&, v8::AccessorInfo const&>
::type;
using compatibility_indexed_property_getset_return_type
= std::conditional<v8_uses_property_callback_info, void, v8::Handle<v8::Value> >::type;
using compatibility_indexed_property_callback_info_type
= std::conditional<v8_uses_property_callback_info
, v8::PropertyCallbackInfo<v8::Value> const&, v8::AccessorInfo const&>
::type;
static_assert(v8_uses_property_callback_info == v8_uses_callback_info
&& v8_uses_callback_info == v8_uses_isolate, "");
template <typename T>
struct compatibility_type_tag {};
template <bool = v8_uses_isolate>
struct compatibility_string;
template <>
struct compatibility_string<true> : v8::String
{
template <typename... Args>
static v8::Local<v8::String> New(Args...args)
{
return NewFromUtf8(v8::Isolate::GetCurrent(), args...);
}
};
template <>
struct compatibility_string<false> : v8::String
{
};
template <typename...Args>
auto compatibility_new_impl(v8::Isolate*, std::true_type, compatibility_type_tag<v8::String>
, Args...args) ->
decltype(compatibility_string<>::New(args...))
{
return compatibility_string<>::New(args...);
}
template <typename...Args>
auto compatibility_new_impl(v8::Isolate*, std::false_type, compatibility_type_tag<v8::String>
, Args...args) ->
decltype(compatibility_string<>::New(args...))
{
return compatibility_string<>::New(args...);
}
template <typename...Args>
auto compatibility_new_impl(std::nullptr_t, std::true_type, compatibility_type_tag<v8::String>
, Args...args) ->
decltype(compatibility_string<>::New(args...))
{
return compatibility_string<>::New(args...);
}
template <typename...Args>
auto compatibility_new_impl(std::nullptr_t, std::false_type, compatibility_type_tag<v8::String>
, Args...args) ->
decltype(compatibility_string<>::New(args...))
{
return compatibility_string<>::New(args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(v8::Isolate* isolate, std::true_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(isolate, args...))
{
return T::New(isolate, args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(v8::Isolate*, std::false_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(args...))
{
return T::New(args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(std::nullptr_t, std::true_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(v8::Isolate::GetCurrent(), args...))
{
return T::New(v8::Isolate::GetCurrent(), args...);
}
template <typename T, typename...Args>
auto compatibility_new_impl(std::nullptr_t, std::false_type, compatibility_type_tag<T>
, Args...args) ->
decltype(T::New(args...))
{
return T::New(args...);
}
template <typename T, typename...Args>
auto compatibility_new(v8::Isolate* isolate, Args...args) ->
decltype(js::compatibility_new_impl<>
(isolate, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...))
{
return js::compatibility_new_impl(isolate, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...);
}
template <typename T, typename...Args>
auto compatibility_new(std::nullptr_t, Args...args) ->
decltype(js::compatibility_new_impl<>(nullptr, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...))
{
return js::compatibility_new_impl<>(nullptr, std::integral_constant<bool, v8_uses_isolate>()
, compatibility_type_tag<T>()
, args...);
}
#ifdef HAVE_V8_CREATE_PARAMS
namespace detail {
class array_buffer_allocator : public v8::ArrayBuffer::Allocator
{
public:
virtual void* Allocate(std::size_t length)
{
void* data = AllocateUninitialized(length);
return data ? std::memset(data, 0, length) : data;
}
virtual void* AllocateUninitialized(std::size_t length) { return std::malloc(length); }
virtual void Free(void* data, std::size_t) { std::free(data); }
};
}
inline v8::Isolate* compatibility_isolate_new()
{
static detail::array_buffer_allocator allocator;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = &allocator;
return v8::Isolate::New(create_params);
}
#else
inline v8::Isolate* compatibility_isolate_new()
{
return v8::Isolate::New();
}
#endif
template <typename T, typename U>
inline void compatibility_return_impl(T object, U const& info, std::true_type)
{
info.GetReturnValue().Set(object);
}
template <typename T>
inline v8::Handle<v8::Value>
compatibility_return_impl(T object, compatibility_callback_info_type, std::false_type)
{
return object;
}
template <typename T>
inline v8::Handle<v8::Value>
compatibility_return_impl(T object, compatibility_accessor_getter_callback_info_type, std::false_type)
{
return object;
}
template <typename T>
compatibility_return_type
compatibility_return(T object, compatibility_callback_info_type args)
{
return compatibility_return_impl(object, args, std::integral_constant<bool, v8_uses_callback_info>());
}
template <typename T>
compatibility_return_type
compatibility_return(T object, compatibility_accessor_getter_callback_info_type args)
{
return compatibility_return_impl(object, args, std::integral_constant<bool, v8_uses_property_callback_info>());
}
inline void compatibility_return_nil_impl(std::true_type) {}
inline v8::Handle<v8::Value>
compatibility_return_nil_impl(std::false_type)
{
return v8::Handle<v8::Value>();
}
inline
compatibility_return_type
compatibility_return()
{
return compatibility_return_nil_impl(std::integral_constant<bool, v8_uses_callback_info>());
}
struct _v8_isolate_throw_exception : v8::Isolate
{
v8::Handle<v8::Value> ThrowException_impl(v8::Handle<v8::Value> v)
{
using namespace v8;
return ThrowException(v);
}
};
inline void
compatibility_throw_impl(v8::Isolate* isolate, v8::Local<v8::Value> exception, std::true_type)
{
static_cast<_v8_isolate_throw_exception*>(isolate)->ThrowException_impl(exception);
}
inline v8::Handle<v8::Value>
compatibility_throw_impl(v8::Isolate* isolate, v8::Local<v8::Value> exception, std::false_type)
{
return static_cast<_v8_isolate_throw_exception*>(isolate)->ThrowException_impl(exception);
}
inline std::conditional<v8_uses_isolate, void, v8::Handle<v8::Value> >::type
compatibility_throw(v8::Isolate* isolate, v8::Local<v8::Value> exception)
{
return compatibility_throw_impl(isolate, exception, std::integral_constant<bool, v8_uses_isolate>());
}
inline void
compatibility_throw_impl(v8::Local<v8::Value> exception, std::true_type)
{
static_cast<_v8_isolate_throw_exception*>(v8::Isolate::GetCurrent())->ThrowException_impl(exception);
}
inline v8::Handle<v8::Value>
compatibility_throw_impl(v8::Local<v8::Value> exception, std::false_type)
{
return static_cast<_v8_isolate_throw_exception*>(v8::Isolate::GetCurrent())->ThrowException_impl(exception);
}
inline std::conditional<v8_uses_isolate, void, v8::Handle<v8::Value> >::type
compatibility_throw(v8::Local<v8::Value> exception)
{
return compatibility_throw_impl(exception, std::integral_constant<bool, v8_uses_isolate>());
}
template <typename T, typename U>
v8::Local<T> compatibility_cast(v8::Local<U> v);
template <typename T, typename U>
v8::Local<T> compatibility_cast(U* v);
template <typename Tag>
struct hack_private_member {
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
template <typename Tag>
typename hack_private_member<Tag>::type hack_private_member<Tag>::ptr;
template <typename Tag, typename Tag::type p>
struct rob_private_member : hack_private_member<Tag> {
/* fill it ... */
struct filler {
filler() { hack_private_member<Tag>::ptr = p; }
};
static filler filler_obj;
};
template<typename Tag, typename Tag::type p>
typename rob_private_member<Tag, p>::filler rob_private_member<Tag, p>::filler_obj;
template <typename T>
struct persistent_base_new { typedef T*(*type)(v8::Isolate*, T*); };
template class rob_private_member<persistent_base_new<v8::Value>, &v8::PersistentBase<v8::Value>::New>;
template <typename T>
v8::Local<T> make_persistent(v8::Isolate* isolate, v8::Handle<T> v)
{
v8::Value* p = hack_private_member<persistent_base_new<v8::Value>>::ptr
(isolate, *compatibility_cast<v8::Value>(v));
return compatibility_cast<T>(compatibility_cast<v8::Value>(p));
}
template <typename T, typename F>
v8::Local<T> make_weak(v8::Isolate* isolate, v8::Handle<T> v, F&& f)
{
v8::Value* p = hack_private_member<persistent_base_new<v8::Value>>::ptr
(isolate, *compatibility_cast<v8::Value>(v));
v8::PersistentBase<v8::Value>* persistent = static_cast<v8::PersistentBase<v8::Value>*>
(static_cast<void*>(&p));
auto callback = [](const v8::WeakCallbackInfo<typename std::remove_reference<F>::type>& data) -> void
{
typename std::remove_reference<F>::type* f = data.GetParameter();
(*f)();
delete f;
};
persistent->SetWeak(new typename std::remove_reference<F>::type(std::forward<F>(f)),
callback, v8::WeakCallbackType::kParameter);
return compatibility_cast<T>(compatibility_cast<v8::Value>(p));
}
template <typename T>
struct global_ref
{
global_ref() {}
global_ref(v8::Local<T> v)
: _value(make_persistent(nullptr, v))
{
}
global_ref(v8::Isolate* isolate, v8::Local<T> v)
: _value(make_persistent(isolate, v))
{
}
void dispose() const
{
v8::PersistentBase<T>* p = static_cast<v8::PersistentBase<T>*>(static_cast<void*>(&_value));
p->Reset();
}
v8::Handle<T> handle() const { return _value; }
private:
mutable v8::Local<T> _value;
};
template <typename T = std::integral_constant<bool, v8_uses_isolate> >
struct _v8_object_internal_field;
template <>
struct _v8_object_internal_field<std::true_type> : v8::Object
{
};
inline void* GetPointerFromInternalField(int) { return nullptr; }
inline void SetPointerInInternalField(int, void*) {}
template <>
struct _v8_object_internal_field<std::false_type> : v8::Object
{
void* GetAlignedPointerFromInternalField(int index)
{
return GetPointerFromInternalField(index);
}
void SetAlignedPointerInInternalField(int index, void* p)
{
SetPointerInInternalField(index, p);
}
};
template <typename T = void*>
inline T compatibility_get_pointer_internal_field(v8::Handle<v8::Object> object, std::size_t index)
{
return reinterpret_cast<T>
(static_cast<_v8_object_internal_field<>*>(*object)->GetAlignedPointerFromInternalField(index));
}
template <typename T>
inline void compatibility_set_pointer_internal_field(v8::Handle<v8::Object> object, std::size_t index
, T* pointer)
{
static_cast<_v8_object_internal_field<>*>(*object)->SetAlignedPointerInInternalField(index, pointer);
}
template <typename T = void, bool = v8_uses_isolate>
struct compatibility_handle_scope_impl;
template <typename T>
struct compatibility_handle_scope_impl<T, true> : v8::HandleScope
{
compatibility_handle_scope_impl()
: HandleScope(v8::Isolate::GetCurrent())
{}
compatibility_handle_scope_impl(v8::Isolate* isolate)
: HandleScope((assert(isolate != nullptr), isolate))
{}
};
template <typename T>
struct compatibility_handle_scope_impl<T, false> : v8::HandleScope
{
compatibility_handle_scope_impl()
{}
compatibility_handle_scope_impl(v8::Isolate*)
{}
};
using compatibility_handle_scope = compatibility_handle_scope_impl<>;
template <bool = v8_uses_isolate>
struct _v8_initialize_icu;
template <>
struct _v8_initialize_icu<true> : v8::V8
{
};
template <>
struct _v8_initialize_icu<false> : v8::V8
{
static bool InitializeICU(const char* = NULL)
{
return true;
}
};
inline void compatibility_initialize()
{
#ifdef HAVE_V8_CREATE_PARAMS
constexpr const char* argv[] = {""};
static_cast<_v8_initialize_icu<>*>(nullptr)->InitializeICU();
v8::V8::InitializeExternalStartupData(argv[0]);
v8::V8::Initialize();
#else
v8::V8::Initialize();
static_cast<_v8_initialize_icu<>*>(nullptr)->InitializeICU();
#endif
}
template <typename T, typename U>
v8::Local<T> compatibility_cast(v8::Local<U> v)
{
static_assert(sizeof(v8::Local<T>) == sizeof(v8::Local<U>), "");
v8::Local<T> l;
std::memcpy(&l, &v, sizeof(v8::Local<T>));
return l;
}
template <typename T, typename U>
v8::Local<T> compatibility_cast(U* v)
{
static_assert(sizeof(v8::Local<T>) == sizeof(U*), "");
v8::Local<T> l;
std::memcpy(&l, &v, sizeof(v8::Local<T>));
return l;
}
template <typename T = v8::Isolate, bool = v8_uses_isolate>
struct _v8_get_current_context;
template <typename T>
struct _v8_get_current_context<T, false> : v8::Context
{
};
template <typename T>
struct _v8_get_current_context<T, true> : T
{
static v8::Local<v8::Context> GetCurrent()
{
return T::GetCurrent()->GetCurrentContext();
}
};
template <typename T>
inline v8::Local<v8::Value>
new_v8_external_instance(v8::Handle<v8::Function>& ctor, T v, v8::Isolate* isolate)
{
// TODO: ensure v8::External ownership ??? (memory leak in case NewInstance throws)
v8::Handle<v8::Value> a[] = {efl::eina::js::compatibility_new<v8::External>(isolate, v)};
return ctor->NewInstance(1, a);
}
inline
compatibility_return_type cast_function(compatibility_callback_info_type args);
inline v8::Local<v8::Value>
new_v8_external_instance(v8::Handle<v8::Function>& ctor, Eo* v, v8::Isolate* isolate)
{
// TODO: ensure v8::External ownership ??? (memory leak in case NewInstance throws)
v8::Handle<v8::Value> a[] = {efl::eina::js::compatibility_new<v8::External>(isolate, v)};
auto obj = ctor->NewInstance(1, a);
obj->Set(compatibility_new<v8::String>(isolate, "cast"),
compatibility_new<v8::FunctionTemplate>(isolate, &cast_function)->GetFunction());
return obj;
}
inline v8::Local<v8::Object> compatibility_global()
{
return _v8_get_current_context<>::GetCurrent()->Global();
}
EAPI extern std::map<std::string, v8::Local<v8::Function>> constructors_map_;
inline v8::Handle<v8::Function> get_class_constructor(std::string const& class_name)
{
auto it = constructors_map_.find(class_name);
if (it == constructors_map_.end())
throw std::runtime_error("Class not found");
return it->second;
}
inline void register_class_constructor(std::string const& class_name,
v8::Handle<v8::Function> constructor_ptr)
{
// TODO: check if already exist?
constructors_map_[class_name] = constructor_ptr;
}
template<class T = v8::StackTrace>
typename std::enable_if<!v8_uses_isolate, v8::Local<T>>::type
compatibility_current_stack_trace(v8::Isolate*, int frame_limit,
v8::StackTrace::StackTraceOptions options)
{
return T::CurrentStackTrace(frame_limit, options);
}
template<class T = v8::StackTrace>
typename std::enable_if<v8_uses_isolate, v8::Local<T>>::type
compatibility_current_stack_trace(v8::Isolate *isolate, int frame_limit,
v8::StackTrace::StackTraceOptions options)
{
return T::CurrentStackTrace(isolate, frame_limit, options);
}
inline
compatibility_return_type cast_function(compatibility_callback_info_type args)
{
auto isolate = args.GetIsolate();
compatibility_handle_scope scope(isolate);
v8::Local<v8::Value> type;
if(args.Length() == 1 && (type = args[0])->IsString())
{
v8::Local<v8::Object> self = args.This();
v8::Local<v8::Value> external = self->GetInternalField(0);
Eo* eo = static_cast<Eo*>(v8::External::Cast(*external)->Value());
v8::String::Utf8Value str(type->ToString());
char* class_name = *str;
auto ctor = ::efl::eina::js::get_class_constructor(class_name);
return compatibility_return
(new_v8_external_instance(ctor, ::eo_ref(eo), isolate), args);
}
else
{
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected String type")));
return compatibility_return();
}
}
} } }
#endif

View File

@ -0,0 +1,495 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eina.hh>
#include <Eina.h>
#include <cstdlib>
#include <Eo.h>
#include <eina_integer_sequence.hh>
#include <eina_tuple.hh>
#include <eina_ptrlist.hh>
#include <Eina_Js.hh>
#include <tuple>
#include <iostream>
namespace efl { namespace eina { namespace js {
template <typename T>
struct tag { typedef T type; };
namespace {
global_ref<v8::ObjectTemplate> instance_persistents[container_type_size];
global_ref<v8::Function> instance_templates[container_type_size];
v8::Local<v8::Value> push(eina_container_base& self, v8::Isolate* isolate, v8::Local<v8::Value> value)
{
return v8::Integer::New(isolate, self.push(isolate, value));
}
v8::Local<v8::Value> pop(eina_container_base& self, v8::Isolate* isolate, v8::Local<v8::Value>)
{
return self.pop(isolate);
}
v8::Local<v8::Value> concat(eina_container_base& lhs, v8::Isolate* isolate, v8::Local<v8::Value> other)
{
const char* error_message = 0;
if(other->IsObject())
{
v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(other);
v8::String::Utf8Value constructor_name (obj->GetConstructorName());
if(obj->GetConstructorName()->Equals(efl::eina::js::compatibility_new<v8::String>(isolate, "eina_list"))
|| obj->GetConstructorName()->Equals(efl::eina::js::compatibility_new<v8::String>(isolate, "eina_array")))
{
eina_container_base& rhs = *static_cast<eina_container_base*>
(efl::eina::js::compatibility_get_pointer_internal_field(obj, 0));
std::type_info const& typeinfo_lhs = typeid(lhs)
, &typeinfo_rhs = typeid(rhs);
if(!typeinfo_lhs.before(typeinfo_rhs) && !typeinfo_rhs.before(typeinfo_lhs))
{
v8::Handle<v8::Value> a[] =
{efl::eina::js::compatibility_new<v8::External>(isolate, rhs.concat(lhs))};
assert(!!*instance_templates[lhs.get_container_type()].handle());
v8::Local<v8::Object> result =
instance_templates[lhs.get_container_type()].handle()->NewInstance(1, a);
return result;
}
else
error_message = "Containers are not of the same type.";
}
else
error_message = "Object to be concatenated is not a container.";
}
else
error_message = "Concatenation argument is not an container";
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError(eina::js::compatibility_new<v8::String>(isolate, error_message)));
return v8::Undefined(isolate);
}
v8::Local<v8::Value> slice(eina_container_base& self, v8::Isolate* isolate, v8::Local<v8::Value> begin
, v8::Local<v8::Value> end)
{
std::size_t i, j;
if(begin->IsUint32() || begin->IsInt32())
i = begin->IntegerValue();
else if (begin->IsUndefined())
i = 0;
else
return v8::Undefined(isolate);
if(end->IsUint32() || end->IsInt32())
j = end->IntegerValue();
else if (end->IsUndefined())
j = self.size();
else
return v8::Undefined(isolate);
v8::Handle<v8::Value> a[] = {efl::eina::js::compatibility_new<v8::External>(isolate, self.slice(i, j))};
v8::Local<v8::Object> result = instance_templates[self.get_container_type()].handle()
->NewInstance(1, a);
return result;
}
compatibility_accessor_getter_return_type length
(v8::Local<v8::String>, compatibility_accessor_getter_callback_info_type info)
{
v8::Local<v8::Object> self_obj = compatibility_cast<v8::Object>(info.This());
eina_container_base* self = static_cast<eina_container_base*>
(compatibility_get_pointer_internal_field(self_obj, 0));
return compatibility_return(js::get_value_from_c(self->size(), info.GetIsolate(), ""), info);
}
compatibility_indexed_property_getset_return_type index_get
(uint32_t index, compatibility_indexed_property_callback_info_type info)
{
v8::Local<v8::Object> self_obj = v8::Local<v8::Object>::Cast(info.This());
eina_container_base* self = static_cast<eina_container_base*>
(compatibility_get_pointer_internal_field(self_obj, 0));
return compatibility_return(self->get(info.GetIsolate(), index), info);
}
compatibility_indexed_property_getset_return_type index_set
(uint32_t index, v8::Local<v8::Value> value, compatibility_indexed_property_callback_info_type info)
{
v8::Local<v8::Object> self_obj = v8::Local<v8::Object>::Cast(info.This());
eina_container_base* self = static_cast<eina_container_base*>
(compatibility_get_pointer_internal_field(self_obj, 0));
return compatibility_return(self->set(info.GetIsolate(), index, value), info);
}
#define GENERATE_CONTAINER_CONSTRUCT_TYPE_IF(x) GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(x, x)
#define GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(x, y) if (!strcmp(class_name, #x)) \
return new Container<y, nonclass_cls_name_getter, typename container_wrapper<y>::type>();
template< template<typename, typename, typename> class Container>
eina_container_base* construct_container(const char* class_name)
{
GENERATE_CONTAINER_CONSTRUCT_TYPE_IF(int);
GENERATE_CONTAINER_CONSTRUCT_TYPE_IF(float);
GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(bool, Eina_Bool);
GENERATE_CONTAINER_CONSTRUCT_TYPE2_IF(string, char*);
return 0;
}
compatibility_return_type new_eina_list_internal(compatibility_callback_info_type args)
{
if(args.IsConstructCall())
{
if(args.Length() == 0)
{
eina_container_base* p = new eina_list<int>;
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(p));
}
else
{
if(args[0]->IsExternal())
{
eina_container_base* base = reinterpret_cast<eina_container_base*>
(v8::External::Cast(*args[0])->Value());
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(base));
}
else
std::abort();
}
}
else
std::abort();
return compatibility_return();
}
compatibility_return_type new_eina_list(compatibility_callback_info_type args)
{
if(args.IsConstructCall())
{
if(args.Length() == 0) // Default constructor, list of ints. Or should be list of Eo's?
{
eina_container_base* p = new eina_list<int>;
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(p));
return compatibility_return();
}
else if (args.Length() == 1 && args[0]->IsString())
{
v8::String::Utf8Value string(args[0]);
eina_container_base* p = construct_container<efl::eina::js::eina_list>(*string);
if (!p) {
return eina::js::compatibility_throw
(args.GetIsolate(), v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Invalid type for container.")));
}
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(p));
return compatibility_return();
}
}
return eina::js::compatibility_throw
(args.GetIsolate(), v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Wrong number of arguments for constructor call")));
}
compatibility_return_type new_eina_array_internal(compatibility_callback_info_type args)
{
if(args.IsConstructCall())
{
if(args.Length() == 0)
{
eina_container_base* p = new eina_array<int>;
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(p));
}
else
{
if(args[0]->IsExternal())
{
eina_container_base* base = reinterpret_cast<eina_container_base*>
(v8::External::Cast(*args[0])->Value());
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(base));
}
else
std::abort();
}
}
else
std::abort();
return compatibility_return();
}
compatibility_return_type new_eina_array(compatibility_callback_info_type args)
{
if(args.IsConstructCall())
{
if(args.Length() == 0)
{
eina_container_base* p = new eina_array<int>;
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(p));
return compatibility_return();
}
else if (args.Length() == 1 && args[0]->IsString())
{
v8::String::Utf8Value string(args[0]);
eina_container_base* p = construct_container<efl::eina::js::eina_array>(*string);
if (!p) {
return eina::js::compatibility_throw
(args.GetIsolate(), v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Invalid type for container.")));
}
compatibility_set_pointer_internal_field
(args.This(), 0, dynamic_cast<void*>(p));
return compatibility_return();
}
}
return eina::js::compatibility_throw
(args.GetIsolate(), v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Wrong number of arguments for constructor call")));
}
template <typename F>
struct function_params;
template <typename R, typename... Sig>
struct function_params<R(*)(Sig...)>
{
typedef std::tuple<Sig...> type;
};
template <typename F>
struct function_result;
template <typename R, typename... Sig>
struct function_result<R(*)(Sig...)>
{
typedef R type;
};
template <typename T>
struct is_persistent : std::false_type {};
template <typename...A>
struct is_persistent<v8::Persistent<A...> > : std::true_type {};
template <std::size_t I, typename Sig>
typename std::tuple_element<I, Sig>::type
get_element(v8::Isolate* isolate
, compatibility_callback_info_type args
, typename std::enable_if
<is_persistent<typename std::tuple_element<I, Sig>::type>::value>::type* = 0)
{
return typename std::tuple_element<I, Sig>::type(isolate, args[I]);
}
template <std::size_t I, typename Sig>
typename std::tuple_element<I, Sig>::type
get_element(v8::Isolate* /*isolate*/
, compatibility_callback_info_type args
, typename std::enable_if
<!is_persistent<typename std::tuple_element<I, Sig>::type>::value>::type* = 0)
{
return args[I];
}
template <typename Sig, typename R, typename T, typename F, std::size_t... N>
R call_impl(v8::Isolate* isolate
, compatibility_callback_info_type args
, T* self, F* f
, eina::index_sequence<N...>)
{
assert(self != 0);
return (*f)(*self, isolate, js::get_element<N, Sig>(isolate, args)...);
}
template <typename Sig, typename T, typename F, typename R>
compatibility_return_type call_generic_impl(compatibility_callback_info_type args, tag<R>)
{
T* self = static_cast<T*>
(compatibility_get_pointer_internal_field<>(args.This(), 0));
F* f = reinterpret_cast<F*>(v8::External::Cast(*args.Data())->Value());
return compatibility_return
(js::get_value_from_c
(js::call_impl<Sig, R>(args.GetIsolate(), args, self, f
, eina::make_index_sequence<std::tuple_size<Sig>::value>())
, args.GetIsolate(), "")
, args);
}
template <typename Sig, typename T, typename F>
compatibility_return_type call_generic_impl(compatibility_callback_info_type args, tag<void>)
{
T* self = static_cast<T*>
(compatibility_get_pointer_internal_field(args.This(), 0));
F* f = reinterpret_cast<F*>(v8::External::Cast(*args.Data())->Value());
js::call_impl<Sig, void>(args.GetIsolate(), args, self, f
, eina::make_index_sequence<std::tuple_size<Sig>::value>());
return compatibility_return();
}
template <typename Sig, typename R, typename T, typename F>
compatibility_return_type call_generic(compatibility_callback_info_type args)
{
return efl::eina::js::call_generic_impl<Sig, T, F>(args, tag<R>());
}
template <typename Sig, typename T, typename F, typename R>
compatibility_return_type call_function_impl(compatibility_callback_info_type args, tag<R>)
{
T* self = static_cast<T*>
(compatibility_get_pointer_internal_field(args.This(), 0));
F f = reinterpret_cast<F>(v8::External::Cast(*args.Data())->Value());
return compatibility_return
(/*js::get_value_from_c*/
(js::call_impl<Sig, R>(args.GetIsolate(), args, self, f
, eina::make_index_sequence<std::tuple_size<Sig>::value>())
/*, args.GetIsolate(), ""*/)
, args);
}
template <typename Sig, typename T, typename F>
compatibility_return_type call_function_impl(compatibility_callback_info_type args, tag<void>)
{
T* self = static_cast<T*>
(compatibility_get_pointer_internal_field(args.This(), 0));
F f = reinterpret_cast<F>(v8::External::Cast(*args.Data())->Value());
js::call_impl<Sig, void>(args.GetIsolate(), args, self, f
, eina::make_index_sequence<std::tuple_size<Sig>::value>());
return compatibility_return();
}
template <typename Sig, typename R, typename T, typename F>
compatibility_return_type call_function(compatibility_callback_info_type args)
{
return efl::eina::js::call_function_impl<Sig, T, F>(args, tag<R>());
}
template <typename T, typename F>
void register_(v8::Isolate* isolate, const char* name, F f, v8::Handle<v8::ObjectTemplate> template_
, typename std::enable_if<std::is_function<typename std::remove_pointer<F>::type>::value>::type* = 0)
{
template_->Set(compatibility_new<v8::String>(isolate, name)
, compatibility_new<v8::FunctionTemplate>
(isolate, &efl::eina::js::call_function
<typename eina::_mpl::pop_front<typename function_params<F>::type, 2u>::type
, typename function_result<F>::type, T, F>
, compatibility_new<v8::External>
(isolate, reinterpret_cast<void*>(f))));
}
template <typename T, typename...Sig, typename F>
void register_(v8::Isolate* isolate, const char* name, F&& f, v8::Handle<v8::ObjectTemplate> template_
, typename std::enable_if<!std::is_function<typename std::remove_pointer<F>::type>::value>::type* = 0)
{
using result_type = decltype
(std::declval<F>()
(std::declval<T&>(), std::declval<v8::Isolate*>()
, std::declval<Sig>()...)
);
template_->Set(compatibility_new<v8::String>(isolate, name)
, compatibility_new<v8::FunctionTemplate>
(isolate
, &efl::eina::js::call_generic<std::tuple<Sig...>, result_type, T, F>
, compatibility_new<v8::External>
(isolate, new F(std::forward<F>(f)))));
}
v8::Local<v8::ObjectTemplate> register_template(v8::Isolate* isolate, v8::Handle<v8::FunctionTemplate> constructor)
{
v8::Local<v8::ObjectTemplate> instance_t = constructor->InstanceTemplate();
instance_t->SetInternalFieldCount(1);
instance_t->SetIndexedPropertyHandler(& efl::eina::js::index_get, & efl::eina::js::index_set);
v8::Local<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();
prototype->SetAccessor(compatibility_new<v8::String>(isolate, "length"), &efl::eina::js::length);
using namespace std::placeholders;
js::register_<js::eina_container_base>
(isolate, "push", &js::push, prototype);
js::register_<js::eina_container_base>
(isolate, "pop", &js::pop, prototype);
js::register_<js::eina_container_base>
(isolate, "concat", &js::concat, prototype);
js::register_<js::eina_container_base>
(isolate, "slice", &js::slice, prototype);
js::register_<js::eina_container_base>
(isolate, "toString", std::bind(&js::eina_container_base::to_string, _1, _2), prototype);
js::register_<js::eina_container_base, v8::Local<v8::Value> >
(isolate, "join", std::bind(&js::eina_container_base::join, _1, _2, _3), prototype);
js::register_<js::eina_container_base, v8::Local<v8::Value> >
(isolate, "indexOf", std::bind(&js::eina_container_base::index_of, _1, _2, _3), prototype);
js::register_<js::eina_container_base, v8::Local<v8::Value> >
(isolate, "lastIndexOf", std::bind(&js::eina_container_base::last_index_of, _1, _2, _3), prototype);
return instance_t;
}
void register_class(v8::Isolate* isolate, container_type type, const char* class_name
, compatibility_function_callback callback)
{
v8::Handle<v8::FunctionTemplate> constructor
= compatibility_new<v8::FunctionTemplate>(isolate, callback);
constructor->SetClassName(compatibility_new<v8::String>(isolate, class_name));
v8::Local<v8::ObjectTemplate> instance_t = efl::eina::js::register_template(isolate, constructor);
efl::eina::js::instance_persistents[type] = global_ref<v8::ObjectTemplate>{isolate, instance_t};
efl::eina::js::instance_templates[type] = global_ref<v8::Function>{isolate, constructor->GetFunction()};
}
void register_class(v8::Isolate* isolate, container_type, const char* class_name_
, const char* constructor_name_
, compatibility_function_callback callback
, v8::Handle<v8::Object> exports)
{
v8::Handle<v8::FunctionTemplate> constructor
= compatibility_new<v8::FunctionTemplate>(isolate, callback);
auto class_name = compatibility_new<v8::String>(isolate, class_name_);
auto constructor_name = compatibility_new<v8::String>(isolate, constructor_name_);
constructor->SetClassName(class_name);
v8::Local<v8::ObjectTemplate> instance_t = efl::eina::js::register_template(isolate, constructor);
(void)instance_t;
exports->Set(constructor_name, constructor->GetFunction());
}
}
EAPI v8::Handle<v8::Function> get_list_instance_template()
{
return efl::eina::js::instance_templates[efl::eina::js::list_container_type].handle();
}
EAPI v8::Handle<v8::Function> get_array_instance_template()
{
return efl::eina::js::instance_templates[efl::eina::js::array_container_type].handle();
}
} } }
EAPI void eina_container_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate)
{
efl::eina::js::register_class(isolate, efl::eina::js::list_container_type
, "eina_list", &efl::eina::js::new_eina_list_internal);
efl::eina::js::register_class(isolate, efl::eina::js::list_container_type
, "eina_list", "List", &efl::eina::js::new_eina_list, exports);
efl::eina::js::register_class(isolate, efl::eina::js::array_container_type
, "eina_array", &efl::eina::js::new_eina_array_internal);
efl::eina::js::register_class(isolate, efl::eina::js::array_container_type
, "eina_array", "Array", &efl::eina::js::new_eina_array, exports);
}

View File

@ -0,0 +1,351 @@
#ifndef EINA_JS_CONTAINER_HH
#define EINA_JS_CONTAINER_HH
#include <algorithm>
#include <eina_js_compatibility.hh>
#include <eina_js_get_value.hh>
#include <eina_js_get_value_from_c.hh>
struct _Elm_Calendar_Mark;
struct Elm_Gen_Item;
struct _Eina_Rectangle;
struct _Evas_Textblock_Rectangle;
struct _Elm_Map_Overlay;
namespace efl { namespace eina { namespace js {
namespace detail {
template <typename T>
eina_container_base* concat(T const& self, eina_container_base const& other)
{
T const& rhs = static_cast<T const&>(other);
typedef typename T::container_type container_type;
container_type container(self._container.begin(), self._container.end());
container.insert(container.end(), rhs._container.begin(), rhs._container.end());
return new T(container.release_native_handle());
}
template <typename T>
eina_container_base* slice(T const& self, std::int64_t i, std::int64_t j)
{
typedef typename T::container_type container_type;
container_type container(std::next(self._container.begin(), i), std::next(self._container.begin(), j));
return new T(container.release_native_handle());
}
// T, W from the container instantiation
template<typename T, typename W, typename C>
int push(v8::Isolate* isolate, C& self, v8::Local<v8::Value> v)
{
try
{
W value = container_wrap(get_value_from_javascript(v, isolate, "", value_tag<T>()));
self._container.push_back(value);
}
catch (std::logic_error const&)
{
return -1;
}
return self.size();
}
template<typename T, typename W, typename K, typename C>
v8::Local<v8::Value> pop(v8::Isolate* isolate, C& self)
{
if (self._container.empty())
return v8::Undefined(isolate);
auto value = eina::js::get_value_from_c(
eina::js::wrap_value<T>(eina::js::container_unwrap(self._container.back()), eina::js::value_tag<T>{})
, isolate
, K::class_name());
self._container.pop_back();
return value;
}
template<typename T, typename W, typename C>
v8::Local<v8::Value> set(v8::Isolate* isolate, C& self, std::size_t index, v8::Local<v8::Value> v)
{
using notag_type = typename remove_tag<T>::type;
try
{
W value = container_wrap(get_value_from_javascript(v, isolate, "", value_tag<T>()));
if (index >= self.size())
{
std::size_t items_to_add = index - self.size() + 1;
for (int i = items_to_add; i; i--)
{
self._container.push_back(container_wrap(notag_type{}));
}
}
auto v2 = std::next(self._container.begin(), index);
*v2 = value;
}
catch (std::logic_error const&)
{
return v8::Undefined(isolate);
}
return v;
}
}
template <typename InputIterator, typename T>
inline InputIterator find_element(InputIterator first, InputIterator last, T const& value, typename std::enable_if<is_handable_by_value<T>::value>::type* = 0)
{
return std::find(first, last, value);
}
template <typename InputIterator, typename T>
inline InputIterator find_element(InputIterator first, InputIterator last, T const& value, typename std::enable_if<!is_handable_by_value<T>::value>::type* = 0)
{
return std::find_if(first, last, [&](T const& e){ return &e == &value; });
}
template <typename InputIterator>
inline InputIterator find_element(InputIterator first, InputIterator last, char * value)
{
return std::find_if(first, last, [=](char* e){ return strcmp(e, value) == 0; });
}
template <typename CharT, typename T>
inline void stream_element(std::basic_ostream<CharT>& s, T const& value, typename std::enable_if<is_handable_by_value<T>::value>::type* = 0)
{
s << value;
}
template <typename CharT, typename T>
inline void stream_element(std::basic_ostream<CharT>& s, T const& value, typename std::enable_if<!is_handable_by_value<T>::value>::type* = 0)
{
s << &value;
}
template <typename CharT>
inline void stream_element(std::basic_ostream<CharT>& s, Eina_Bool value)
{
s << (value ? "true" : "false");
}
template <typename C, typename T, typename K>
struct eina_container_common;
template <typename C, typename V, typename T, typename K, typename Enable = void>
struct eina_container_type_specific
: eina_container_base
{
v8::Local<v8::Value> get(v8::Isolate* isolate, std::size_t index) const
{
if(index >= this->size())
return v8::Undefined(isolate);
return eina::js::get_value_from_c(
eina::js::wrap_value<T>(eina::js::container_unwrap(*std::next(container_get().begin(), index)), eina::js::value_tag<T>{})
, isolate
, K::class_name());
}
int index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const
{
try
{
V value = container_wrap(get_value_from_javascript(
v, isolate, K::class_name(), eina::js::value_tag<T>{}, false));
typedef typename C::const_iterator iterator;
iterator first = container_get().cbegin()
, last = container_get().cend()
, found = find_element(first, last, value);
if(found == last)
return -1;
else
return std::distance(first, found);
}
catch (std::logic_error const&)
{
return -1;
}
}
int last_index_of(v8::Isolate* isolate, v8::Local<v8::Value> v) const
{
try
{
V value = container_wrap(get_value_from_javascript(
v, isolate, K::class_name(), eina::js::value_tag<T>{}, false));
auto last = container_get().crend()
, found = find_element(container_get().crbegin(), last, value);
if(found == last)
return -1;
else
return std::distance(container_get().cbegin(), found.base()) -1;
}
catch (std::logic_error const&)
{
return -1;
}
}
void* get_container_native_handle()
{
void const* h = container_get().native_handle();
return const_cast<void*>(h);
}
void const* get_container_native_handle() const
{
return container_get().native_handle();
}
C& container_get() { return static_cast<eina_container_common<C, T, K>&>(*this)._container; }
C const& container_get() const { return static_cast<eina_container_common<C, T, K>const&>(*this)._container; }
};
template <typename C, typename T, typename K>
struct eina_container_common : eina_container_type_specific<C, typename C::value_type, T, K>
{
eina_container_common() : _container() {}
eina_container_common(typename C::native_handle_type raw) : _container(raw) {}
std::size_t size() const { return _container.size(); }
v8::Local<v8::String> to_string(v8::Isolate* isolate) const
{
return join(isolate, compatibility_new<v8::String>(isolate, ","));
}
v8::Local<v8::String> join(v8::Isolate* isolate, v8::Local<v8::Value> separator_js) const
{
std::string separator = ",";
typedef typename container_type::const_iterator iterator;
std::stringstream s;
if (separator_js->IsString())
{
v8::String::Utf8Value str(separator_js);
if (*str)
{
separator = *str;
}
else
{
eina::js::compatibility_throw(
isolate, v8::Exception::TypeError(
eina::js::compatibility_new<v8::String>(isolate, "Invalid separator.")));
return compatibility_new<v8::String>(isolate, "");
}
}
else if (!separator_js->IsUndefined()) // Called join without arguments.
{
eina::js::compatibility_throw(
isolate, v8::Exception::TypeError(
eina::js::compatibility_new<v8::String>(isolate, "Separator must be a string.")));
return compatibility_new<v8::String>(isolate, "");
}
for(iterator first = _container.begin()
, last = _container.end()
, last_elem = std::next(last, -1); first != last; ++first)
{
stream_element(s, *first);
if(first != last_elem)
s << separator;
}
return compatibility_new<v8::String>(isolate, s.str().c_str());
}
// Default implementation of some methods
int push(v8::Isolate* isolate, v8::Local<v8::Value>)
{
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Push method was not implemented.")));
return -1;
}
v8::Local<v8::Value> pop(v8::Isolate* isolate)
{
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Pop method was not implemented.")));
return v8::Undefined(isolate);
}
v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t, v8::Local<v8::Value>)
{
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Indexed attribution was not implemented.")));
return v8::Undefined(isolate);
}
C _container;
typedef C container_type;
};
// Specialization for problematic types
struct empty_container_base
: eina_container_base
{
empty_container_base() {}
virtual ~empty_container_base() {}
std::size_t size() const
{
return 0;
}
eina_container_base* concat(eina_container_base const& ) const
{
return new empty_container_base;
}
eina_container_base* slice(std::int64_t , std::int64_t ) const
{
return new empty_container_base;
}
int index_of(v8::Isolate*, v8::Local<v8::Value>) const
{
return -1;
}
int last_index_of(v8::Isolate*, v8::Local<v8::Value>) const
{
return -1;
}
v8::Local<v8::Value> get(v8::Isolate* isolate, std::size_t) const
{
return v8::Undefined(isolate);
}
v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t, v8::Local<v8::Value>)
{
return v8::Undefined(isolate);
}
int push(v8::Isolate*, v8::Local<v8::Value>)
{
return -1;
}
v8::Local<v8::Value> pop(v8::Isolate* isolate)
{
return v8::Undefined(isolate);
}
v8::Local<v8::String> to_string(v8::Isolate* isolate) const
{
return compatibility_new<v8::String>(isolate, "");
}
v8::Local<v8::String> join(v8::Isolate* isolate, v8::Local<v8::Value>) const
{
return compatibility_new<v8::String>(isolate, "");
}
container_type get_container_type() const
{
throw std::runtime_error("get_container_type of container with unmanagable type");
return container_type_size;
}
void* get_container_native_handle()
{
return nullptr;
}
void const* get_container_native_handle() const
{
return nullptr;
}
};
} } }
EAPI void eina_container_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate);
#endif

View File

@ -0,0 +1,24 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eina_Js.hh>
namespace efl { namespace eina {namespace js {
EAPI
js::compatibility_return_type convert_error_to_javascript_exception(v8::Isolate *isolate)
{
Eina_Error err = eina_error_get();
if (!err)
return compatibility_return();
v8::Local<v8::Object> je = eina::js::compatibility_new<v8::Object>(isolate);
je->Set(compatibility_new<v8::String>(isolate, "code"),
compatibility_new<v8::String>(isolate, "Eina_Error"));
je->Set(compatibility_new<v8::String>(isolate, "value"),
compatibility_new<v8::String>(isolate, eina_error_msg_get(err)));
return compatibility_throw(isolate, je);
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,25 @@
#ifndef EINA_JS_ERROR_HH
#define EINA_JS_ERROR_HH
#include <eina_js_compatibility.hh>
namespace efl { namespace eina { namespace js {
/**
* Converts the error value set through Eina's error tool to a JavaScript
* exception.
*
* The exception object will have a `code` string field with the `"Eina_Error"`
* string value and a `value` string field with the value extracted from
* `eina_error_msg_get`.
*
* It won't reset the error to NULL, so you can still access the error object,
* but if you keep calling this function without clearing the error, a new
* exception will be generated for each call after some error is reached. We,
* therefore, suggest you to call `eina_error_set(0)` afterwards.
*/
js::compatibility_return_type convert_error_to_javascript_exception(v8::Isolate *isolate);
} } } // namespace efl::eina::js
#endif /* EINA_JS_ERROR_HH */

View File

@ -0,0 +1,449 @@
#ifndef EFL_EINA_JS_GET_VALUE_HH
#define EFL_EINA_JS_GET_VALUE_HH
#include <eina_js_compatibility.hh>
#include <type_traits>
#include <cstdlib>
#include <iostream>
#include <typeinfo>
namespace efl { namespace eina { namespace js {
template <typename T>
inline int get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<T>
, bool throw_js_exception = true
, typename std::enable_if<(std::is_integral<T>::value && !std::is_same<T, Eina_Bool>::value)>::type* = 0)
{
if(v->IsInt32())
return v->Int32Value();
else if(v->IsUint32())
return v->Uint32Value();
else
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Integral type")));
throw std::logic_error("");
}
return 0;
}
inline char* get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<char*>
, bool throw_js_exception = true)
{
if(v->IsNull())
return nullptr;
else if(v->IsString())
{
v8::String::Utf8Value str(v->ToString());
char* string = strdup(*str); // TODO: leaks
return string;
}
else
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected String type")));
throw std::logic_error("");
}
return 0;
}
inline const char* get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char* class_name
, value_tag<const char*>
, bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<char*>(), throw_js_exception);
}
inline Eo* get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<Eo*>
, bool throw_js_exception = true)
{
if(v->IsNull())
return nullptr;
else if(v->IsObject())
{
v8::Local<v8::Object> object = v->ToObject();
if(object->InternalFieldCount() == 1)
{
v8::Local<v8::Value> r = object->GetInternalField(0);
if(v8::External* external = v8::External::Cast(*r))
{
return static_cast<Eo*>(external->Value());
}
}
}
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian object type")));
throw std::logic_error("");
return nullptr;
}
inline Eo* get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char* class_name
, value_tag<Eo* const>
, bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<Eo*>(), throw_js_exception);
}
template <typename T>
inline T get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<struct_ptr_tag<T>>
, bool throw_js_exception = true)
{
if(v->IsNull())
return nullptr;
else if(v->IsObject())
{
v8::Local<v8::Object> object = v->ToObject();
if(object->InternalFieldCount() == 1)
{
return compatibility_get_pointer_internal_field<T>(object, 0);
}
}
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian struct type")));
throw std::logic_error("");
return nullptr;
}
template <typename T>
inline T get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char* class_name
, value_tag<struct_tag<T>>
, bool throw_js_exception = true)
{
T* ptr = get_value_from_javascript(v, isolate, class_name, value_tag<struct_ptr_tag<T*>>(), throw_js_exception);
if (ptr)
return *ptr;
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Conversion of null pointer to by-value struct.")));
throw std::logic_error("");
return T{};
}
template <typename T>
inline T get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<T>
, bool throw_js_exception = true
, typename std::enable_if<std::is_enum<T>::value>::type* = 0)
{
if(v->IsInt32())
return static_cast<T>(v->Int32Value());
else if(v->IsUint32())
return static_cast<T>(v->Uint32Value());
else
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected enumeration type")));
throw std::logic_error("");
}
return T();
}
inline Eina_Bool get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<Eina_Bool>
, bool throw_js_exception = true)
{
if(v->IsBoolean() || v->IsBooleanObject())
{
return v->BooleanValue() ? EINA_TRUE : EINA_FALSE;
}
else
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Boolean type")));
throw std::logic_error("");
}
return 0;
}
template <typename T>
inline double get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, const char*
, value_tag<T>
, bool throw_js_exception = true
, typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
{
if(v->IsNumber())
{
return v->NumberValue();
}
else
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected floating point type")));
throw std::logic_error("");
}
return 0.0;
}
template <typename T>
inline T get_value_from_javascript
(v8::Local<v8::Value>, v8::Isolate* isolate, const char*, value_tag<T>
, bool throw_js_exception = true
, typename std::enable_if<
!std::is_floating_point<T>::value &&
!std::is_integral<T>::value &&
!std::is_enum<T>::value &&
!js::is_struct_tag<T>::value &&
!js::is_struct_ptr_tag<T>::value &&
!js::is_complex_tag<T>::value &&
!std::is_same<T, Eina_Accessor*>::value &&
!std::is_same<T, Eina_Array*>::value &&
!std::is_same<T, Eina_Iterator*>::value &&
!std::is_same<T, Eina_Hash*>::value &&
!std::is_same<T, Eina_List*>::value &&
!std::is_same<T, const Eina_Accessor*>::value &&
!std::is_same<T, const Eina_Array*>::value &&
!std::is_same<T, const Eina_Iterator*>::value &&
!std::is_same<T, const Eina_Hash*>::value &&
!std::is_same<T, const Eina_List*>::value
>::type* = 0)
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Not implemented yet")));
throw std::logic_error("");
}
// TODO: Fix for const types
template <typename T, typename K>
inline Eina_Accessor* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char*,
value_tag<complex_tag<Eina_Accessor *, T, K>>,
bool throw_js_exception = true)
{
if(v->IsNull())
return nullptr;
else if(v->IsObject())
{
using wrapped_type = typename container_wrapper<T>::type;
v8::Local<v8::Object> object = v->ToObject();
auto& acc = import_accessor<wrapped_type>(object);
return acc.native_handle();
}
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian accessor type")));
throw std::logic_error("");
}
template <typename...I>
inline const Eina_Accessor* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char* class_name,
value_tag<complex_tag<const Eina_Accessor *, I...>>,
bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Accessor *, I...>>{}, throw_js_exception);
}
template <typename...I>
inline Eina_Array* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char*,
value_tag<complex_tag<Eina_Array *, I...>>,
bool throw_js_exception = true)
{
if(v->IsNull())
return nullptr;
else if(v->IsObject())
{
v8::Local<v8::Object> object = v->ToObject();
if(object->InternalFieldCount() == 1)
{
eina_container_base* cbase = compatibility_get_pointer_internal_field<eina_container_base*>(object, 0);
return static_cast<Eina_Array*>(cbase->get_container_native_handle());
}
}
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian list type")));
throw std::logic_error("");
return nullptr;
}
template <typename...I>
inline const Eina_Array* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char* class_name,
value_tag<complex_tag<const Eina_Array *, I...>>,
bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Array *, I...>>{}, throw_js_exception);
}
template <typename...I>
inline Eina_Iterator* get_value_from_javascript(
v8::Local<v8::Value>,
v8::Isolate* isolate,
const char*,
value_tag<complex_tag<Eina_Iterator *, I...>> tag,
bool throw_js_exception = true)
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Not implemented yet")));
throw std::logic_error("");
}
template <typename...I>
inline const Eina_Iterator* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char* class_name,
value_tag<complex_tag<const Eina_Iterator *, I...>>,
bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Iterator *, I...>>{}, throw_js_exception);
}
template <typename T, typename...U>
inline Eina_Hash* get_value_from_javascript(
v8::Local<v8::Value>,
v8::Isolate* isolate,
const char*,
value_tag<complex_tag<Eina_Hash *, T, U...>> tag,
bool throw_js_exception = true)
{
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Not implemented yet")));
throw std::logic_error("");
}
template <typename T, typename...U>
inline const Eina_Hash* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char* class_name,
value_tag<complex_tag<const Eina_Hash *, T, U...>>,
bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_Hash *, T, U...>>{}, throw_js_exception);
}
template <typename...I>
inline Eina_List* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char*,
value_tag<complex_tag<Eina_List *, I...>> /*tag*/,
bool throw_js_exception = true)
{
if(v->IsNull())
return nullptr;
else if(v->IsObject())
{
v8::Local<v8::Object> object = v->ToObject();
if(object->InternalFieldCount() == 1)
{
eina_container_base* cbase = compatibility_get_pointer_internal_field<eina_container_base*>(object, 0);
return static_cast<Eina_List*>(cbase->get_container_native_handle());
}
}
if (throw_js_exception)
eina::js::compatibility_throw
(isolate, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(isolate, "Type expected is different. Expected Eolian list type")));
throw std::logic_error("");
return nullptr;
}
template <typename...I>
inline const Eina_List* get_value_from_javascript(
v8::Local<v8::Value> v,
v8::Isolate* isolate,
const char* class_name,
value_tag<complex_tag<const Eina_List *, I...>>,
bool throw_js_exception = true)
{
return get_value_from_javascript(v, isolate, class_name, value_tag<complex_tag<Eina_List *, I...>>{}, throw_js_exception);
}
inline const void* get_value_from_javascript
(v8::Local<v8::Value>,
v8::Isolate*,
const char*,
value_tag<const void *>)
{
return nullptr;
}
typedef void (*Evas_Smart_Cb)(void*, _Eo_Opaque*, void*);
inline Evas_Smart_Cb get_value_from_javascript (
v8::Local<v8::Value>,
v8::Isolate*,
const char*,
value_tag<Evas_Smart_Cb>)
{
return nullptr;
}
} } }
#endif

View File

@ -0,0 +1,261 @@
#ifndef EFL_EINA_JS_GET_VALUE_FROM_C_HH
#define EFL_EINA_JS_GET_VALUE_FROM_C_HH
#include <eina_js_compatibility.hh>
#include <type_traits>
#include <cstdlib>
#include <typeinfo>
#include <memory>
namespace efl { namespace eina { namespace js {
template <typename T> struct print_tag {};
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(T v, v8::Isolate* isolate, const char*
, typename std::enable_if<std::is_integral<typename std::remove_reference<T>::type>::value && !std::is_same<T, Eina_Bool>::value>::type* = 0)
{
return eina::js::compatibility_new<v8::Integer>(isolate, v);
}
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(T v, v8::Isolate* isolate, const char*
, typename std::enable_if<std::is_enum<typename std::remove_reference<T>::type>::value>::type* = 0)
{
return eina::js::compatibility_new<v8::Integer>(isolate, v);
}
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(T v, v8::Isolate* isolate, const char*
, typename std::enable_if<std::is_same<typename std::remove_reference<T>::type, Eina_Bool>::value>::type* = 0)
{
return eina::js::compatibility_new<v8::Boolean>(isolate, v);
}
template <typename T>
inline v8::Local<T>
get_value_from_c(v8::Local<T> v, v8::Isolate*, const char*)
{
return v;
}
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(T v, v8::Isolate* isolate, const char*
, typename std::enable_if<std::is_floating_point<typename std::remove_reference<T>::type>::value>::type* = 0)
{
return eina::js::compatibility_new<v8::Number>(isolate, v);
}
inline v8::Local<v8::Value>
get_value_from_c(const char* v, v8::Isolate* isolate, const char*)
{
if (!v)
return v8::Null(isolate);
return eina::js::compatibility_new<v8::String>(isolate, v);
}
inline v8::Local<v8::Value>
get_value_from_c(char* v, v8::Isolate* isolate, const char* class_name)
{
return js::get_value_from_c(const_cast<const char*>(v), isolate, class_name);
}
inline v8::Local<v8::Value>
get_value_from_c(void*, v8::Isolate*, const char*)
{
// TODO: create Extern?
std::cerr << "aborting because we don't know the type void*" << std::endl;
std::abort();
}
inline v8::Local<v8::Value>
get_value_from_c(const void*, v8::Isolate*, const char*)
{
// TODO: create Extern?
std::cerr << "aborting because we don't know the type void*" << std::endl;
std::abort();
}
// For function pointer types
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(T, v8::Isolate*, const char*
, typename std::enable_if
<std::is_pointer<typename std::remove_reference<T>::type>::value
&& std::is_function<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value
>::type* = 0)
{
// TODO: create Extern?
std::cerr << "aborting because we don't know the type " << typeid(print_tag<T>).name() << std::endl;
std::abort();
}
// For all non-pointer types that are not handled
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(T, v8::Isolate*, const char*
, typename std::enable_if
<!std::is_pointer<typename std::remove_reference<T>::type>::value
&& !std::is_integral<typename std::remove_reference<T>::type>::value
&& !std::is_floating_point<typename std::remove_reference<T>::type>::value
&& !std::is_enum<typename std::remove_reference<T>::type>::value
&& !std::is_same<typename std::remove_reference<T>::type, Eina_Bool>::value
&& !js::is_struct_tag<typename std::remove_reference<T>::type>::value
&& !js::is_struct_ptr_tag<typename std::remove_reference<T>::type>::value
&& !js::is_complex_tag<typename std::remove_reference<T>::type>::value
>::type* = 0)
{
std::cerr << "aborting because we don't know the type " << typeid(print_tag<T>).name() << std::endl;
std::abort();
}
// For all non-handled pointer types (which are not function pointers):
// - we try to dereference it in the SFINAE
// - if it matches we call get_value_from_c for the dereferenced type
// - if it fails (probably because it is opaque) the void* or const void*
// overload will take place (implicit conversion)
template <typename T>
inline auto
get_value_from_c(T object, v8::Isolate* isolate, const char* class_name
, typename std::enable_if<
(std::is_pointer<typename std::remove_reference<T>::type>::value
&& !std::is_function<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value
)
&& !(std::is_same<typename std::remove_reference<T>::type, char*>::value ||
std::is_same<typename std::remove_reference<T>::type, const char*>::value ||
std::is_same<typename std::remove_reference<T>::type, void*>::value ||
std::is_same<typename std::remove_reference<T>::type, const void*>::value ||
std::is_same<typename std::remove_reference<T>::type, Eo*>::value ||
std::is_same<typename std::remove_reference<T>::type, const Eo*>::value
)>::type* = 0) -> decltype(get_value_from_c(*object, isolate, class_name))
{
std::cerr << "dereferencing " << typeid(print_tag<T>).name() << std::endl;
return get_value_from_c(*object, isolate, class_name);
}
inline v8::Local<v8::Value>
get_value_from_c(Eo* v, v8::Isolate* isolate, const char* class_name)
{
auto ctor = ::efl::eina::js::get_class_constructor(class_name);
return new_v8_external_instance(ctor, v, isolate);
}
inline v8::Local<v8::Value>
get_value_from_c(const Eo* v, v8::Isolate* isolate, const char* class_name)
{
// TODO: implement const objects?
auto ctor = ::efl::eina::js::get_class_constructor(class_name);
return new_v8_external_instance(ctor, const_cast<Eo*>(v), isolate);
}
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(struct_ptr_tag<T> v, v8::Isolate* isolate, const char* class_name)
{
// TODO: implement const structs?
auto ctor = ::efl::eina::js::get_class_constructor(class_name);
return new_v8_external_instance(ctor, const_cast<typename std::remove_const<T>::type>(v.value), isolate);
}
template <typename T>
inline v8::Local<v8::Value>
get_value_from_c(struct_tag<T> v, v8::Isolate* isolate, const char* class_name)
{
return get_value_from_c(struct_ptr_tag<T*>{new T(v.value)}, isolate, class_name);
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<Eina_Accessor *, T, K> v, v8::Isolate* isolate, const char*)
{
using wrapped_type = typename container_wrapper<T>::type;
auto a = new ::efl::eina::accessor<wrapped_type>{v.value};
return export_accessor<T>(*a , isolate, K::class_name());
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<const Eina_Accessor *, T, K> v, v8::Isolate* isolate, const char* class_name)
{
// TODO implement const accessor?
return get_value_from_c(efl::eina::js::complex_tag<Eina_Accessor*, T, K>{const_cast<Eina_Accessor*>(v.value)}, isolate, class_name);
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<Eina_Array *, T, K> v, v8::Isolate* isolate, const char*)
{
// TODO: use unique_ptr for eina_array to avoid leak ?
auto o = new ::efl::eina::js::range_eina_array<T, K>(v.value);
auto ctor = get_array_instance_template();
return new_v8_external_instance(ctor, o, isolate);
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<const Eina_Array *, T, K> v, v8::Isolate* isolate, const char* class_name)
{
// TODO: implement const array?
return get_value_from_c(efl::eina::js::complex_tag<Eina_Array *, T, K>{const_cast<Eina_Array*>(v.value)}, isolate, class_name);
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<Eina_Iterator *, T, K>, v8::Isolate*, const char*)
{
std::cerr << "get_value_from_c for Eina_Iterator not implemented. Aborting..." << std::endl;
std::abort();
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<const Eina_Iterator *, T, K>, v8::Isolate*, const char*)
{
std::cerr << "get_value_from_c for Eina_Iterator not implemented. Aborting..." << std::endl;
std::abort();
}
template <typename T, typename U, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<Eina_Hash *, T, U, K>, v8::Isolate*, const char*)
{
std::cerr << "get_value_from_c for Eina_Hash not implemented. Aborting..." << std::endl;
std::abort();
}
template <typename T, typename U, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<const Eina_Hash *, T, U, K>, v8::Isolate*, const char*)
{
std::cerr << "get_value_from_c for Eina_Hash not implemented. Aborting..." << std::endl;
std::abort();
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<Eina_List *, T, K> v, v8::Isolate* isolate, const char*)
{
// TODO: ensure eina_list ownership ???
auto o = new ::efl::eina::js::range_eina_list<T, K>(v.value);
auto ctor = get_list_instance_template();
return new_v8_external_instance(ctor, o, isolate);
}
template <typename T, typename K>
inline v8::Local<v8::Value>
get_value_from_c(efl::eina::js::complex_tag<const Eina_List *, T, K> v, v8::Isolate* isolate, const char* class_name)
{
// TODO: implement const list?
return get_value_from_c(efl::eina::js::complex_tag<Eina_List *, T, K>{const_cast<Eina_List*>(v.value)}, isolate, class_name);
}
} } }
#endif

View File

@ -0,0 +1,32 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eina.hh>
#include <Eina_Js.hh>
namespace efl { namespace eina { namespace js {
EAPI
void register_destroy_iterator(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
typedef void (*deleter_t)(void*);
auto f = [](compatibility_callback_info_type info) -> compatibility_return_type
{
if (info.Length() != 1 || !info[0]->IsObject())
return compatibility_return();
v8::Handle<v8::Object> o = info[0]->ToObject();
deleter_t deleter = compatibility_get_pointer_internal_field<deleter_t>(o, 1);
deleter(compatibility_get_pointer_internal_field<>(o, 0));
return compatibility_return();
};
global->Set(name, compatibility_new<v8::FunctionTemplate>(isolate, f)->GetFunction());
}
} } } // namespace efl { namespace js {

View File

@ -0,0 +1,81 @@
#ifndef EINA_JS_ITERATOR_HH
#define EINA_JS_ITERATOR_HH
#include <type_traits>
#include <eina_js_value.hh>
namespace efl { namespace eina { namespace js {
/* Exports the \p iterator to be manipulated by the JS code. The iterator should
remain alive as long as there is JS code referencing it. The JS code is able
to destroy the iterator by itself if you register the appropriate function
through `register_destroy_iterator`.
The exported JS object models part the [iterator concept from ECMAScript
6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol).
The iterator will have the `next` function, but the returned object won't
have a `done` attribute, because the eina_iterator itself doesn't expose this
information.*/
template<class T>
v8::Local<v8::Object> export_iterator(::efl::eina::iterator<T> *i,
v8::Isolate *isolate)
{
typedef ::efl::eina::iterator<T> value_type;
typedef value_type *ptr_type;
typedef void (*deleter_t)(void*);
auto obj_tpl = compatibility_new<v8::ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(2);
auto ret = obj_tpl->NewInstance();
auto next = [](js::compatibility_callback_info_type info) -> compatibility_return_type
{
if (info.Length() != 0)
return compatibility_return();
void *ptr = compatibility_get_pointer_internal_field(info.This(), 0);
auto &value = *static_cast<ptr_type>(ptr);
v8::Local<v8::Object> o = compatibility_new<v8::Object>(info.GetIsolate());
o->Set(compatibility_new<v8::String>(info.GetIsolate(), "value"),
value_cast<v8::Local<v8::Value>>(*value, info.GetIsolate()));
++value;
return compatibility_return(o, info);
};
ret->Set(compatibility_new<v8::String>(isolate, "next"),
compatibility_new<v8::FunctionTemplate>(isolate, next)->GetFunction());
{
deleter_t deleter = [](void *i) {
delete static_cast<ptr_type>(i);
};
compatibility_set_pointer_internal_field(ret, 0, i);
compatibility_set_pointer_internal_field
(ret, 1, reinterpret_cast<void*>(deleter));
}
return ret;
}
/* Extracts and returns a copy from the internal iterator object from the JS
object. */
template<class T>
::efl::eina::iterator<T> *import_iterator(v8::Handle<v8::Object> o)
;
// {
// typedef ::efl::eina::iterator<T> value_type;
// typedef value_type *ptr_type;
// return reinterpret_cast<ptr_type>(o->GetAlignedPointerFromInternalField(0));
// }
void register_destroy_iterator(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
} } } // namespace efl::js
#endif /* EINA_JS_ITERATOR_HH */

View File

@ -0,0 +1,132 @@
#ifndef EINA_JS_LIST_HH
#define EINA_JS_LIST_HH
#include <iostream>
#include <eina_js_container.hh>
#include <eina_js_compatibility.hh>
#include <iterator>
namespace efl { namespace eina { namespace js {
template <typename T, typename K, typename W>
struct eina_list : eina_container_common<efl::eina::list
<W
, typename std::conditional
<std::is_base_of<efl::eo::concrete, W>::value
, efl::eina::eo_clone_allocator
, efl::eina::malloc_clone_allocator
>::type>, T, K>
{
typedef eina_container_common<efl::eina::list<W
, typename std::conditional
<std::is_base_of<efl::eo::concrete, W>::value
, efl::eina::eo_clone_allocator
, efl::eina::malloc_clone_allocator
>::type>, T, K> base_type;
using base_type::base_type;
typedef typename base_type::container_type container_type;
eina_container_base* concat(eina_container_base const& other) const
{
return detail::concat(*this, other);
}
eina_container_base* slice(std::int64_t i, std::int64_t j) const
{
return detail::slice(*this, i, j);
}
v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t index, v8::Local<v8::Value> v)
{
return detail::set<T,W>(isolate, *this, index, v);
}
int push(v8::Isolate* isolate, v8::Local<v8::Value> v)
{
return detail::push<T,W>(isolate, *this, v);
}
v8::Local<v8::Value> pop(v8::Isolate* isolate)
{
return detail::pop<T,W,K>(isolate, *this);
}
js::container_type get_container_type() const { return list_container_type; }
};
template <typename T, typename K, typename W>
struct range_eina_list : eina_container_common<typename efl::eina::range_list<W>, T, K>
{
typedef eina_container_common<efl::eina::range_list<W>, T, K> base_type;
using base_type::base_type;
typedef typename base_type::container_type container_type;
typedef typename std::conditional
<std::is_base_of<efl::eo::concrete, W>::value
, efl::eina::eo_clone_allocator
, efl::eina::malloc_clone_allocator
>::type clone_allocator_type;
eina_container_base* concat(eina_container_base const& other) const
{
range_eina_list<T, K, W>const& rhs = static_cast<range_eina_list<T, K, W>const&>(other);
efl::eina::list<W, clone_allocator_type>
list(this->_container.begin(), this->_container.end());
list.insert(list.end(), rhs._container.begin(), rhs._container.end());
return new eina::js::eina_list<T, K, W>(list.release_native_handle());
}
eina_container_base* slice(std::int64_t i, std::int64_t j) const
{
efl::eina::list<W, clone_allocator_type>
list(std::next(this->_container.begin(), i), std::next(this->_container.begin(), j));
return new eina::js::eina_list<T, K, W>(list.release_native_handle());
}
v8::Local<v8::Value> set(v8::Isolate* isolate, std::size_t, v8::Local<v8::Value>)
{
return v8::Undefined(isolate);
}
int push(v8::Isolate*, v8::Local<v8::Value>)
{
return this->size();
}
v8::Local<v8::Value> pop(v8::Isolate* isolate)
{
return v8::Undefined(isolate);
}
js::container_type get_container_type() const { return list_container_type; }
};
// Problematic types.
template <>
struct eina_list<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
: empty_container_base
{ eina_list(Eina_List const*){} };
template <>
struct eina_list<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
: empty_container_base
{ eina_list(Eina_List const*){} };
template <>
struct eina_list<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
: empty_container_base
{ eina_list(Eina_List const*){} };
template <>
struct eina_list<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
: empty_container_base
{ eina_list(Eina_List const*){} };
template <>
struct range_eina_list<_Elm_Calendar_Mark*, js::nonclass_cls_name_getter, _Elm_Calendar_Mark>
: empty_container_base
{ range_eina_list(Eina_List const*){} };
template <>
struct range_eina_list<Elm_Gen_Item*, js::nonclass_cls_name_getter, Elm_Gen_Item>
: empty_container_base
{ range_eina_list(Eina_List const*){} };
template <>
struct range_eina_list<_Evas_Textblock_Rectangle*, js::nonclass_cls_name_getter, _Evas_Textblock_Rectangle>
: empty_container_base
{ range_eina_list(Eina_List const*){} };
template <>
struct range_eina_list<_Elm_Map_Overlay*, js::nonclass_cls_name_getter, _Elm_Map_Overlay>
: empty_container_base
{ range_eina_list(Eina_List const*){} };
} } }
#endif

View File

@ -0,0 +1,742 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string>
#include <map>
#include <Eina_Js.hh>
namespace efl { namespace eina { namespace js {
v8::Local<v8::String> to_v8_string(v8::Isolate *isolate, const char *fmt,
va_list args)
{
using v8::String;
#if 0
/* TODO: unfortunately, the elegant and exception-safe version isn't
compiling (yet!) */
efl::eina::stringshare s(eina_stringshare_vprintf(fmt, args),
efl::eina::steal_stringshare_ref);
return compatibility_new<String>(isolate, s.data(), String::kNormalString,
s.size());
#else
auto s = eina_stringshare_vprintf(fmt, args);
auto ret = compatibility_new<String>(isolate, s);
eina_stringshare_del(s);
return ret;
#endif
}
static global_ref<v8::Value> js_eina_log_print_cb_data;
static std::map<int, std::string> js_eina_log_color_map;
static void js_eina_log_print_cb(const Eina_Log_Domain *d, Eina_Log_Level level,
const char *file, const char *fnc, int line,
const char *fmt, void */*data*/, va_list args)
{
using v8::String;
using v8::Integer;
using v8::Isolate;
Isolate *const isolate = Isolate::GetCurrent();
constexpr unsigned argc = 7;
v8::Handle<v8::Value> argv[argc] = {
compatibility_new<String>(isolate, d->name ? d->name : ""),
compatibility_new<String>(isolate, d->color ? d->color : ""),
compatibility_new<Integer>(isolate, static_cast<int>(level)),
compatibility_new<String>(isolate, file),
compatibility_new<String>(isolate, fnc),
compatibility_new<Integer>(isolate, line),
to_v8_string(isolate, fmt, args)
};
auto o = js_eina_log_print_cb_data.handle();
v8::Function::Cast(*o)->Call(o->ToObject(), argc, argv);
}
static bool valid_level_conversion(int src, Eina_Log_Level &dst)
{
if (src != EINA_LOG_LEVEL_CRITICAL && src != EINA_LOG_LEVEL_ERR
&& src != EINA_LOG_LEVEL_WARN && src != EINA_LOG_LEVEL_INFO
&& src != EINA_LOG_LEVEL_DBG)
return false;
dst = static_cast<Eina_Log_Level>(src);
return true;
}
EAPI
void register_log_print(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::String;
using v8::StackTrace;
using v8::FunctionTemplate;
auto print = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
|| !args[2]->IsString())
return compatibility_return();
Eina_Log_Level level;
if (!valid_level_conversion(args[1]->NumberValue(), level))
return compatibility_return();
auto frame = compatibility_current_stack_trace<>(args.GetIsolate(), 1,
StackTrace::kDetailed)->GetFrame(0);
eina_log_print(args[0]->NumberValue(), level,
*String::Utf8Value(frame->GetScriptNameOrSourceURL()),
*String::Utf8Value(frame->GetFunctionName()),
frame->GetLineNumber(), "%s",
*String::Utf8Value(args[2]));
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, print)
->GetFunction());
}
EAPI
void register_log_domain_register(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::Local;
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString())
return compatibility_return();
// We duplicate the color string as eina takes a const char* but does take care of
// its lifetime, assuming a ever lasting string.
std::string color = *String::Utf8Value(args[1]);
int d = eina_log_domain_register(*String::Utf8Value(args[0]),
color.c_str());
js_eina_log_color_map[d] = color;
auto isolate = args.GetIsolate();
return compatibility_return(value_cast<Local<Value>>(d, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_domain_unregister(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
int domain = args[0]->NumberValue();
eina_log_domain_unregister(domain);
js_eina_log_color_map.erase(domain);
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_domain_registered_level_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::Local;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
int l = eina_log_domain_registered_level_get(args[0]->NumberValue());
auto isolate = args.GetIsolate();
return compatibility_return(value_cast<Local<Value>>(l, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_domain_registered_level_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
return compatibility_return();
eina_log_domain_registered_level_set(args[0]->NumberValue(),
args[1]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_print_cb_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsFunction())
return compatibility_return();
js_eina_log_print_cb_data
= global_ref<v8::Value>(args.GetIsolate(), args[0]);
eina_log_print_cb_set(js_eina_log_print_cb, NULL);
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_level_set(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
eina_log_level_set(args[0]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_level_get(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
using v8::Integer;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
int l = eina_log_level_get();
auto ret = compatibility_new<Integer>(args.GetIsolate(), l);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_level_check(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
using v8::Boolean;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
bool b = eina_log_level_check(args[0]->NumberValue());
auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_color_disable_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsBoolean())
return compatibility_return();
eina_log_color_disable_set(args[0]->BooleanValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_color_disable_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::Boolean;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
bool b = eina_log_color_disable_get();
auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_file_disable_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsBoolean())
return compatibility_return();
eina_log_file_disable_set(args[0]->BooleanValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_file_disable_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::Boolean;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
bool b = eina_log_file_disable_get();
auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_function_disable_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsBoolean())
return compatibility_return();
eina_log_function_disable_set(args[0]->BooleanValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_function_disable_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::Boolean;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
bool b = eina_log_function_disable_get();
auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_abort_on_critical_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsBoolean())
return compatibility_return();
eina_log_abort_on_critical_set(args[0]->BooleanValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_abort_on_critical_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::Boolean;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
bool b = eina_log_abort_on_critical_get();
auto ret = compatibility_new<Boolean>(args.GetIsolate(), b);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_abort_on_critical_level_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
eina_log_abort_on_critical_level_set(args[0]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_abort_on_critical_level_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
using v8::Integer;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
int l = eina_log_abort_on_critical_level_get();
auto ret = compatibility_new<Integer>(args.GetIsolate(), l);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_domain_level_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
using v8::String;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsNumber())
return compatibility_return();
eina_log_domain_level_set(*String::Utf8Value(args[0]),
args[1]->NumberValue());
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_domain_level_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
using v8::String;
using v8::Integer;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsString())
return compatibility_return();
int l = eina_log_domain_level_get(*String::Utf8Value(args[0]));
auto ret = compatibility_new<Integer>(args.GetIsolate(), l);
return compatibility_return(ret, args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
EAPI
void register_log_timing(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Value;
using v8::FunctionTemplate;
using v8::String;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 3 || !args[0]->IsNumber() || !args[1]->IsNumber()
|| !args[2]->IsString()) {
return compatibility_return();
}
eina_log_timing(args[0]->NumberValue(),
static_cast<Eina_Log_State>(args[1]->NumberValue()),
*String::Utf8Value(args[2]));
return compatibility_return();
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
static void register_constant(v8::Isolate *isolate, v8::Handle<v8::Object> global, int value, const char* name)
{
global->Set(compatibility_new<v8::String>(isolate, name), compatibility_new<v8::Integer>(isolate, value));
}
static void register_constant(v8::Isolate *isolate, v8::Handle<v8::Object> global, const char* value, const char* name)
{
global->Set(compatibility_new<v8::String>(isolate, name), compatibility_new<v8::String>(isolate, value));
}
EAPI void register_log_constants(v8::Isolate *isolate, v8::Handle<v8::Object> global)
{
register_constant(isolate, global, EINA_LOG_STATE_START, "LOG_STATE_START");
register_constant(isolate, global, EINA_LOG_STATE_START, "LOG_STATE_STOP");
register_constant(isolate, global, EINA_LOG_LEVEL_CRITICAL, "LOG_LEVEL_CRITICAL");
register_constant(isolate, global, EINA_LOG_LEVEL_ERR, "LOG_LEVEL_ERR");
register_constant(isolate, global, EINA_LOG_LEVEL_WARN, "LOG_LEVEL_WARN");
register_constant(isolate, global, EINA_LOG_LEVEL_INFO, "LOG_LEVEL_INFO");
register_constant(isolate, global, EINA_LOG_LEVEL_DBG, "LOG_LEVEL_DBG");
register_constant(isolate, global, EINA_LOG_LEVELS, "LOG_LEVELS");
register_constant(isolate, global, EINA_LOG_LEVEL_UNKNOWN, "LOG_LEVEL_UNKNOWN");
register_constant(isolate, global, EINA_LOG_DOMAIN_GLOBAL, "LOG_DOMAIN_GLOBAL");
register_constant(isolate, global, EINA_COLOR_LIGHTRED, "COLOR_LIGHTRED");
register_constant(isolate, global, EINA_COLOR_RED, "COLOR_RED");
register_constant(isolate, global, EINA_COLOR_LIGHTBLUE, "COLOR_LIGHTBLUE");
register_constant(isolate, global, EINA_COLOR_BLUE, "COLOR_BLUE");
register_constant(isolate, global, EINA_COLOR_GREEN, "COLOR_GREEN");
register_constant(isolate, global, EINA_COLOR_YELLOW, "COLOR_YELLOW");
register_constant(isolate, global, EINA_COLOR_ORANGE, "COLOR_ORANGE");
register_constant(isolate, global, EINA_COLOR_WHITE, "COLOR_WHITE");
register_constant(isolate, global, EINA_COLOR_LIGHTCYAN, "COLOR_LIGHTCYAN");
register_constant(isolate, global, EINA_COLOR_CYAN, "COLOR_CYAN");
register_constant(isolate, global, EINA_COLOR_RESET, "COLOR_RESET");
register_constant(isolate, global, EINA_COLOR_HIGH, "COLOR_HIGH");
}
#define REGISTER_LOG_HELPER(isolate, global, level, name) \
{ \
using v8::String; \
using v8::FunctionTemplate;\
using v8::StackTrace;\
\
auto wrapper = [](compatibility_callback_info_type args)\
-> compatibility_return_type {\
if (args.Length() != 1 || !args[0]->IsString()) {\
eina::js::compatibility_throw \
(args.GetIsolate(), v8::Exception::TypeError(\
eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Message must be a string."))); \
return compatibility_return();\
} \
\
auto frame = compatibility_current_stack_trace<>(args.GetIsolate(), 1,\
StackTrace::kDetailed)->GetFrame(0);\
\
eina_log_print(EINA_LOG_DOMAIN_GLOBAL, level,\
*String::Utf8Value(frame->GetScriptNameOrSourceURL()),\
*String::Utf8Value(frame->GetFunctionName()),\
frame->GetLineNumber(), "%s",\
*String::Utf8Value(args[0]));\
\
return compatibility_return();\
};\
\
global->Set(compatibility_new<String>(isolate, name),\
compatibility_new<FunctionTemplate>(isolate, wrapper)->GetFunction());\
}
EAPI void register_log_helpers(v8::Isolate *isolate, v8::Handle<v8::Object> global)
{
REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_CRITICAL, "logCritical");
REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_ERR, "logError");
REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_WARN, "logWarning");
REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_INFO, "logInfo");
REGISTER_LOG_HELPER(isolate, global, EINA_LOG_LEVEL_DBG, "logDebug");
}
} } } // namespace efl { namespace js {
EAPI
void eina_log_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate)
{
using efl::eina::js::compatibility_new;
efl::eina::js::register_log_domain_register(isolate, exports
, compatibility_new<v8::String>(isolate, "registerLogDomain"));
efl::eina::js::register_log_domain_unregister(isolate, exports
, compatibility_new<v8::String>(isolate, "unregisterLogDomain"));
efl::eina::js::register_log_domain_registered_level_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogDomainRegisteredLevel"));
efl::eina::js::register_log_domain_registered_level_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogDomainRegisteredLevel"));
efl::eina::js::register_log_print(isolate, exports
, compatibility_new<v8::String>(isolate, "logPrint"
));
efl::eina::js::register_log_print_cb_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogPrintCb"
));
efl::eina::js::register_log_level_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogLevel"
));
efl::eina::js::register_log_level_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogLevel"
));
efl::eina::js::register_log_level_check(isolate, exports
, compatibility_new<v8::String>(isolate, "checkLogLevel"
));
efl::eina::js::register_log_color_disable_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogColorDisable"
));
efl::eina::js::register_log_color_disable_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogColorDisable"
));
efl::eina::js::register_log_file_disable_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogFileDisable"
));
efl::eina::js::register_log_file_disable_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogFileDisable"
));
efl::eina::js::register_log_function_disable_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogFunctionDisable"
));
efl::eina::js::register_log_function_disable_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogFunctionDisable"
));
efl::eina::js::register_log_abort_on_critical_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogAbortOnCritical"
));
efl::eina::js::register_log_abort_on_critical_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogAbortOnCritical"
));
efl::eina::js::register_log_abort_on_critical_level_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogAbortOnCriticalLevel"
));
efl::eina::js::register_log_abort_on_critical_level_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogAbortOnCriticalLevel"
));
efl::eina::js::register_log_domain_level_set(isolate, exports
, compatibility_new<v8::String>(isolate, "setLogDomainLevel"
));
efl::eina::js::register_log_domain_level_get(isolate, exports
, compatibility_new<v8::String>(isolate, "getLogDomainLevel"
));
efl::eina::js::register_log_timing(isolate, exports
, compatibility_new<v8::String>(isolate, "logTiming"));
efl::eina::js::register_log_constants(isolate, exports);
efl::eina::js::register_log_helpers(isolate, exports);
}

View File

@ -0,0 +1,133 @@
#ifndef EINA_JS_LOG_HH
#define EINA_JS_LOG_HH
#include <type_traits>
namespace efl { namespace eina { namespace js {
using ::efl::eina::js::compatibility_new;
using ::efl::eina::js::compatibility_return_type;
using ::efl::eina::js::compatibility_callback_info_type;
using ::efl::eina::js::compatibility_return;
using ::efl::eina::js::compatibility_get_pointer_internal_field;
using ::efl::eina::js::compatibility_set_pointer_internal_field;
void register_log_level_critical(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_err(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_warn(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_info(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_dbg(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_global(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_print(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_register(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_unregister(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_registered_level_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_registered_level_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_print_cb_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_set(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_get(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_level_check(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_color_disable_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_color_disable_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_file_disable_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_file_disable_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_function_disable_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_function_disable_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_abort_on_critical_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_abort_on_critical_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_abort_on_critical_level_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_abort_on_critical_level_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_level_set(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_domain_level_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_state_start(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_state_stop(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
void register_log_timing(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
} } } // namespace efl::js
EAPI void eina_log_register(v8::Handle<v8::Object> exports, v8::Isolate* isolate);
#endif /* EINA_JS_LOG_HH */

View File

@ -0,0 +1,14 @@
#ifdef HAVE_NODE_NODE_H
#include <node/node.h>
#elif defined(HAVE_NODEJS_DEPS_NODE_NODE_H)
#include <nodejs/deps/node/node.h>
#elif defined(HAVE_NODEJS_DEPS_NODE_INCLUDE_NODE_H)
#include <nodejs/deps/node/include/node.h>
#elif defined(HAVE_NODEJS_SRC_NODE_H)
#include <nodejs/src/node.h>
#elif defined(HAVE_NODE_H)
#include <node.h>
#else
#error We must have at least one node header to include
#endif

View File

@ -0,0 +1,132 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eina_Js.hh>
namespace efl { namespace eina { namespace js {
namespace {
compatibility_return_type eina_value_set(compatibility_callback_info_type args)
{
if (args.Length() != 1)
return compatibility_return();
void *ptr = js::compatibility_get_pointer_internal_field(args.Holder(), 0);
v8::Isolate *isolate = args.GetIsolate();
try {
*static_cast<value*>(ptr) = value_cast<value>(args[0]);
} catch(const std::bad_cast &e) {
v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
je->Set(compatibility_new<v8::String>(isolate, "code"),
compatibility_new<v8::String>(isolate, "std::bad_cast"));
return compatibility_throw(isolate, je);
} catch(const ::efl::eina::system_error &e) {
v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
je->Set(compatibility_new<v8::String>(isolate, "code"),
compatibility_new<v8::String>(isolate, "std::error_code"));
je->Set(compatibility_new<v8::String>(isolate, "category"),
compatibility_new<v8::String>(isolate, e.code().category().name()));
je->Set(compatibility_new<v8::String>(isolate, "value"),
compatibility_new<v8::Integer>(isolate, e.code().value()));
return compatibility_throw(isolate, je);
}
return compatibility_return();
}
compatibility_return_type eina_value_get(compatibility_callback_info_type args)
{
void *ptr = compatibility_get_pointer_internal_field(args.Holder(), 0);
auto &value = *static_cast<eina::value*>(ptr);
return compatibility_return
(value_cast<v8::Local<v8::Value>>(value, args.GetIsolate()), args);
}
compatibility_return_type eina_value_constructor(compatibility_callback_info_type args)
{
if (args.Length() != 1)
return compatibility_return();
v8::Isolate* isolate = args.GetIsolate();
try {
std::unique_ptr<value>
ptr(new value(value_cast<value>(args[0])));
compatibility_set_pointer_internal_field(args.This(), 0, ptr.get());
ptr.release();
} catch(const std::bad_cast &e) {
v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
je->Set(compatibility_new<v8::String>(isolate, "code"),
compatibility_new<v8::String>(isolate, "std::bad_cast"));
return compatibility_throw(isolate,je);
} catch(const ::efl::eina::system_error &e) {
v8::Local<v8::Object> je = compatibility_new<v8::Object>(isolate);
je->Set(compatibility_new<v8::String>(isolate, "code"),
compatibility_new<v8::String>(isolate, "std::error_code"));
je->Set(compatibility_new<v8::String>(isolate, "category"),
compatibility_new<v8::String>(isolate, e.code().category().name()));
je->Set(compatibility_new<v8::String>(isolate, "value"),
compatibility_new<v8::Integer>(isolate, e.code().value()));
return compatibility_throw(isolate, je);
}
// makeweak
// {
// typedef global_ref<v8::Object> persistent_t;
// typedef v8::WeakCallbackData<v8::Object, persistent_t> cb_type;
// auto on_gc = [](const cb_type &data) {
// typedef ::efl::eina::value value_type;
// typedef value_type *ptr_type;
// auto o = data.GetValue();
// delete static_cast<ptr_type>
// (compatibility_get_pointer_internal_field(o, 0));
// compatibility_set_pointer_internal_field<void*>(o, 0, nullptr);
// delete data.GetParameter();
// };
// auto persistent = new persistent_t(isolate, args.This());
// persistent->SetWeak<v8::Object>(persistent, on_gc);
// }
}
}
EAPI
void register_value(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Isolate;
using v8::Local;
using v8::Value;
using v8::Integer;
using v8::String;
using v8::Object;
using v8::FunctionTemplate;
using v8::FunctionCallbackInfo;
v8::Local<v8::FunctionTemplate> constructor = compatibility_new<v8::FunctionTemplate>(isolate, &eina_value_constructor);
v8::Local<v8::ObjectTemplate> instance = constructor->InstanceTemplate();
instance->SetInternalFieldCount(1);
auto prototype = constructor->PrototypeTemplate();
prototype->Set(compatibility_new<v8::String>(isolate, "set")
, compatibility_new<FunctionTemplate>(isolate, &eina_value_set));
prototype->Set(compatibility_new<v8::String>(isolate, "get")
, compatibility_new<FunctionTemplate>(isolate, &eina_value_get));
global->Set(name, constructor->GetFunction());
}
} } } // namespace efl { namespace js {
EAPI
void eina_value_register(v8::Handle<v8::Object> global, v8::Isolate* isolate)
{
efl::eina::js::register_value(isolate, global
, efl::eina::js::compatibility_new<v8::String>(isolate, "value"));
}

View File

@ -0,0 +1,142 @@
#ifndef EINA_JS_VALUE_HH
#define EINA_JS_VALUE_HH
#include <type_traits>
#include <eina_js_compatibility.hh>
namespace efl { namespace eina { namespace js {
namespace detail {
template<class T, class = void>
struct is_representable_as_v8_integer: std::false_type {};
template<class T>
struct is_representable_as_v8_integer
<T,
typename std::enable_if<std::is_integral<T>::value
/* v8::Integer only stores 32-bit signed and unsigned
numbers. */
&& (sizeof(T) <= sizeof(int32_t))>::type>
: std::true_type {};
template<class T>
typename std::enable_if<is_representable_as_v8_integer<T>::value
&& std::is_signed<T>::value,
v8::Local<v8::Value>>::type
to_v8_number(const T &v, v8::Isolate *isolate)
{
return compatibility_new<v8::Integer>(isolate, v);
}
template<class T>
typename std::enable_if<is_representable_as_v8_integer<T>::value
&& std::is_unsigned<T>::value,
v8::Local<v8::Value>>::type
to_v8_number(const T &v, v8::Isolate *isolate)
{
return compatibility_new<v8::Integer>(isolate, v);
}
template<class T>
typename std::enable_if<(std::is_integral<T>::value
&& !is_representable_as_v8_integer<T>::value)
|| std::is_floating_point<T>::value,
v8::Local<v8::Value>>::type
to_v8_number(const T &v, v8::Isolate *isolate)
{
return compatibility_new<v8::Number>(isolate, v);
}
template<class T>
typename std::enable_if<std::is_same<T, ::efl::eina::stringshare>::value
|| std::is_same<T, std::string>::value,
v8::Local<v8::Value>>::type
to_v8_string(const T &v, v8::Isolate *isolate)
{
return compatibility_new<v8::String>(isolate, v.c_str());
}
} // namespace detail
template<class T>
typename std::enable_if<std::is_same<T, v8::Local<v8::Value>>::value, T>::type
value_cast(const ::efl::eina::value &v, v8::Isolate *isolate)
{
using detail::to_v8_number;
using detail::to_v8_string;
using ::efl::eina::get;
const auto &t = v.type_info();
if (t == EINA_VALUE_TYPE_UINT64) {
return to_v8_number(get<uint64_t>(v), isolate);
} else if (t == EINA_VALUE_TYPE_UCHAR) {
return to_v8_number(get<unsigned char>(v), isolate);
} else if (t == EINA_VALUE_TYPE_USHORT) {
return to_v8_number(get<unsigned short>(v), isolate);
} else if (t == EINA_VALUE_TYPE_UINT) {
return to_v8_number(get<unsigned int>(v), isolate);
} else if (t == EINA_VALUE_TYPE_ULONG) {
return to_v8_number(get<unsigned long>(v), isolate);
} else if (t == EINA_VALUE_TYPE_CHAR) {
return to_v8_number(get<char>(v), isolate);
} else if (t == EINA_VALUE_TYPE_SHORT) {
return to_v8_number(get<short>(v), isolate);
} else if (t == EINA_VALUE_TYPE_INT) {
return to_v8_number(get<int>(v), isolate);
} else if (t == EINA_VALUE_TYPE_LONG) {
return to_v8_number(get<long>(v), isolate);
} else if (t == EINA_VALUE_TYPE_FLOAT) {
return to_v8_number(get<float>(v), isolate);
} else if (t == EINA_VALUE_TYPE_DOUBLE) {
return to_v8_number(get<double>(v), isolate);
} else if (t == EINA_VALUE_TYPE_STRINGSHARE) {
return to_v8_string(get<::efl::eina::stringshare>(v), isolate);
} else if (t == EINA_VALUE_TYPE_STRING) {
return to_v8_string(get<std::string>(v), isolate);
}
throw std::bad_cast{};
}
template<class T>
typename std::enable_if<std::is_same<T, ::efl::eina::value>::value, T>::type
value_cast(const v8::Handle<v8::Value> &v)
{
using ::efl::eina::value;
if (v->IsBoolean()) {
return value(int{v->BooleanValue()});
} else if (v->IsInt32()) {
return value(v->Int32Value());
} else if (v->IsUint32()) {
return value(v->Uint32Value());
} else if (v->IsNumber()) {
return value(v->NumberValue());
} else if (v->IsString()) {
v8::String::Utf8Value data(v);
return value(std::string(*data, data.length()));
}
throw std::bad_cast{};
}
/*
# JS binding
- There is the `value()` constructor, which accepts a primitive value as input
argument and might throw.
- The returned object has a `get()` method, which can be used to get the
wrapped value as a JavaScript value.
- The returned object has a `set()` method, which can be used to change the
wrapped value.
*/
void register_value(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name);
} } } // namespace efl::js
EAPI void eina_value_register(v8::Handle<v8::Object> global, v8::Isolate* isolate);
#endif /* EINA_JS_VALUE_HH */

View File

@ -0,0 +1,44 @@
#ifndef EIO_JS_INIT_HH
#define EIO_JS_INIT_HH
#include <Eio.h>
#include <Ecore.h>
#include <Eina.hh>
#include <Eina_Js.hh>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_EIO_JS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_EIO_JS_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
namespace efl { namespace eio { namespace js {
EAPI
void register_eio(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
} } } // namespace efl { namespace eio { namespace js {
#endif /* EIO_JS_INIT_HH */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
#ifndef EFL_ELDBUS_JS_HH
#define EFL_ELDBUS_JS_HH
#include <Eina.hh>
#include <Eina_Js.hh>
#include <Eldbus.h>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_EINA_JS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_ECORE_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
namespace efl { namespace eldbus { namespace js {
EAPI void register_eldbus_connection(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
EAPI void register_eldbus_core(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
EAPI void register_eldbus_message(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
EAPI void register_eldbus_object_mapper(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
EAPI void register_eldbus(v8::Isolate* isolate, v8::Handle<v8::Object> exports);
} } }
#include <eldbus_js_util.hh>
#endif

View File

@ -0,0 +1,543 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eldbus_Js.hh>
namespace efl { namespace eldbus { namespace js {
namespace {
v8::Local<v8::Object> wrap_event_callback(Eldbus_Connection *conn,
Eldbus_Connection_Event_Type type,
Eldbus_Connection_Event_Cb cb,
void *cb_data, v8::Isolate *isolate)
{
using v8::String;
using v8::Integer;
using v8::Value;
using v8::Object;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(3);
auto ret = obj_tpl->NewInstance();
ret->Set(compatibility_new<String>(isolate, "_type"),
compatibility_new<Integer>(isolate, type));
compatibility_set_pointer_internal_field(ret, 0, conn);
compatibility_set_pointer_internal_field(ret, 1, (void*)(cb));
compatibility_set_pointer_internal_field(ret, 2, cb_data);
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
auto o = info.This();
auto isolate = info.GetIsolate();
auto conn
= (compatibility_get_pointer_internal_field<Eldbus_Connection*>
(o, 0));
auto cb
= (compatibility_get_pointer_internal_field
<Eldbus_Connection_Event_Cb>(o, 1));
auto cb_data
= (compatibility_get_pointer_internal_field
<efl::eina::js::global_ref<Value>*>(o, 2));
auto type
= (static_cast<Eldbus_Connection_Event_Type>
(o->Get(compatibility_new<String>(isolate, "_type"))
->IntegerValue()));
eldbus_connection_event_callback_del(conn, type, cb, cb_data);
delete cb_data;
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
return ret;
}
Eldbus_Connection* extract_eldbus_connection(v8::Local<v8::Object> o)
{
return compatibility_get_pointer_internal_field<Eldbus_Connection*>(o, 0);
}
void register_timeout_infinite(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name, compatibility_new<Integer>(isolate,
ELDBUS_TIMEOUT_INFINITE));
}
void register_connection_type_unknown(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_TYPE_UNKNOWN));
}
void register_connection_type_session(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_TYPE_SESSION));
}
void register_connection_type_system(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_TYPE_SYSTEM));
}
void register_connection_type_starter(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_TYPE_STARTER));
}
void register_connection_type_address(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_TYPE_ADDRESS));
}
void register_connection_type_last(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_TYPE_LAST));
}
void register_connection_event_del(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name, compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_EVENT_DEL));
}
void register_connection_event_disconnected(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>
(isolate, ELDBUS_CONNECTION_EVENT_DISCONNECTED));
}
void register_connection_event_last(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name, compatibility_new<Integer>(isolate,
ELDBUS_CONNECTION_EVENT_LAST));
}
void register_connection_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
auto isolate = args.GetIsolate();
Eldbus_Connection_Type type;
switch (args[0]->IntegerValue()) {
case ELDBUS_CONNECTION_TYPE_UNKNOWN:
type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
break;
case ELDBUS_CONNECTION_TYPE_SESSION:
type = ELDBUS_CONNECTION_TYPE_SESSION;
break;
case ELDBUS_CONNECTION_TYPE_SYSTEM:
type = ELDBUS_CONNECTION_TYPE_SYSTEM;
break;
case ELDBUS_CONNECTION_TYPE_STARTER:
type = ELDBUS_CONNECTION_TYPE_STARTER;
break;
case ELDBUS_CONNECTION_TYPE_ADDRESS:
type = ELDBUS_CONNECTION_TYPE_ADDRESS;
break;
case ELDBUS_CONNECTION_TYPE_LAST:
type = ELDBUS_CONNECTION_TYPE_LAST;
break;
default:
return compatibility_return();
}
auto ret = eldbus_connection_get(type);
return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_private_connection_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsNumber())
return compatibility_return();
auto isolate = args.GetIsolate();
Eldbus_Connection_Type type;
switch (args[0]->IntegerValue()) {
case ELDBUS_CONNECTION_TYPE_UNKNOWN:
type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
break;
case ELDBUS_CONNECTION_TYPE_SESSION:
type = ELDBUS_CONNECTION_TYPE_SESSION;
break;
case ELDBUS_CONNECTION_TYPE_SYSTEM:
type = ELDBUS_CONNECTION_TYPE_SYSTEM;
break;
case ELDBUS_CONNECTION_TYPE_STARTER:
type = ELDBUS_CONNECTION_TYPE_STARTER;
break;
case ELDBUS_CONNECTION_TYPE_ADDRESS:
type = ELDBUS_CONNECTION_TYPE_ADDRESS;
break;
case ELDBUS_CONNECTION_TYPE_LAST:
type = ELDBUS_CONNECTION_TYPE_LAST;
break;
default:
return compatibility_return();
}
auto ret = eldbus_private_connection_get(type);
return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_address_connection_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsString())
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = eldbus_address_connection_get(*String::Utf8Value(args[0]));
return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_private_address_connection_get(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsString())
return compatibility_return();
auto isolate = args.GetIsolate();
String::Utf8Value address(args[0]);
auto ret = eldbus_private_address_connection_get(*address);
return compatibility_return(wrap_eldbus_connection(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
}
v8::Local<v8::Object> wrap_eldbus_connection(Eldbus_Connection *conn,
v8::Isolate *isolate)
{
using v8::String;
using v8::Boolean;
using v8::Value;
using v8::Handle;
using v8::ObjectTemplate;
using v8::Function;
using v8::FunctionTemplate;
using std::unique_ptr;
typedef efl::eina::js::global_ref<Value> persistent_t;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto event_callback_add = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 2 || !info[0]->IsNumber()
|| !info[1]->IsFunction()) {
return compatibility_return();
}
auto isolate = info.GetIsolate();
auto conn = extract_eldbus_connection(info.This());
Eldbus_Connection_Event_Type type;
switch (info[0]->IntegerValue()) {
case ELDBUS_CONNECTION_EVENT_DEL:
type = ELDBUS_CONNECTION_EVENT_DEL;
break;
case ELDBUS_CONNECTION_EVENT_DISCONNECTED:
type = ELDBUS_CONNECTION_EVENT_DISCONNECTED;
break;
case ELDBUS_CONNECTION_EVENT_LAST:
type = ELDBUS_CONNECTION_EVENT_LAST;
break;
default:
return compatibility_return();
}
unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[1]}};
auto cb = [](void *data, Eldbus_Connection *conn,
void */*event_info*/) {
auto persistent = reinterpret_cast<persistent_t*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args{wrap_eldbus_connection(conn, isolate)};
Function::Cast(*o)->Call(o->ToObject(), 1, &args);
};
eldbus_connection_event_callback_add(conn, type, cb, cb_data.get());
auto ret = wrap_event_callback(conn, type, cb, cb_data.release(),
isolate);
return compatibility_return(ret, info);
};
auto send = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 3 || !info[0]->IsObject() || !info[1]->IsFunction()
|| !info[2]->IsNumber()) {
return compatibility_return();
}
auto isolate = info.GetIsolate();
auto conn = extract_eldbus_connection(info.This());
auto msg
= (compatibility_get_pointer_internal_field<Eldbus_Message*>
(info[0]->ToObject(), 0));
unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[1]}};
auto cb = [](void *data, const Eldbus_Message *msg,
Eldbus_Pending *pending) {
auto persistent = reinterpret_cast<persistent_t*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args[2] = {
wrap_const_eldbus_msg(msg, isolate),
wrap_eldbus_pending(pending, persistent, isolate)
};
Function::Cast(*o)->Call(o->ToObject(), 2, args);
delete persistent;
};
auto ret = eldbus_connection_send(conn, msg, cb, cb_data.get(),
info[2]->NumberValue());
return compatibility_return(wrap_eldbus_pending(ret, cb_data.release(),
isolate),
info);
};
auto unique_name_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto conn = extract_eldbus_connection(info.This());
auto ret = eldbus_connection_unique_name_get(conn);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto object_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 2 || !info[0]->IsString() || !info[1]->IsString())
return compatibility_return();
auto isolate = info.GetIsolate();
auto conn = extract_eldbus_connection(info.This());
auto ret = eldbus_object_get(conn, *String::Utf8Value(info[0]),
*String::Utf8Value(info[1]));
return compatibility_return(wrap_eldbus_object(ret, isolate), info);
};
auto signal_handler_add = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 5 || !info[0]->IsString() || !info[1]->IsString()
|| !info[2]->IsString() || !info[3]->IsString()
|| !info[4]->IsFunction()) {
return compatibility_return();
}
auto isolate = info.GetIsolate();
auto conn = extract_eldbus_connection(info.This());
unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[4]}};
auto cb = [](void *data, const Eldbus_Message *msg) {
auto persistent = reinterpret_cast<persistent_t*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args{wrap_const_eldbus_msg(msg, isolate)};
Function::Cast(*o)->Call(o->ToObject(), 1, &args);
};
auto ret = eldbus_signal_handler_add(conn, *String::Utf8Value(info[0]),
*String::Utf8Value(info[1]),
*String::Utf8Value(info[2]),
*String::Utf8Value(info[3]),
cb, cb_data.get());
auto wrapped_ret = wrap_eldbus_signal_handler(ret, cb_data.release(),
isolate);
return compatibility_return(wrapped_ret, info);
};
ret->Set(compatibility_new<String>(isolate, "event_callback_add"),
compatibility_new<FunctionTemplate>(isolate, event_callback_add)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "send"),
compatibility_new<FunctionTemplate>(isolate, send)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "unique_name_get"),
compatibility_new<FunctionTemplate>(isolate, unique_name_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "object_get"),
compatibility_new<FunctionTemplate>(isolate, object_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "signal_handler_add"),
compatibility_new<FunctionTemplate>(isolate, signal_handler_add)
->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, conn);
return ret;
}
EAPI
void register_eldbus_connection(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
using v8::String;
register_timeout_infinite(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_TIMEOUT_INFINITE"));
register_connection_type_unknown(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_TYPE_UNKNOWN"));
register_connection_type_session(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_TYPE_SESSION"));
register_connection_type_system(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_TYPE_SYSTEM"));
register_connection_type_starter(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_TYPE_STARTER"));
register_connection_type_address(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_TYPE_ADDRESS"));
register_connection_type_last(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_TYPE_LAST"));
register_connection_event_del(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_EVENT_DEL"));
register_connection_event_disconnected(isolate, exports,
compatibility_new<String>
(isolate,
"ELDBUS_CONNECTION_EVENT"
"_DISCONNECTED"));
register_connection_event_last(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_CONNECTION_EVENT_LAST"));
register_connection_get(isolate, exports,
compatibility_new<String>
(isolate, "connection_get"));
register_private_connection_get(isolate, exports,
compatibility_new<String>
(isolate, "private_connection_get"));
register_address_connection_get(isolate, exports,
compatibility_new<String>
(isolate, "address_connection_get"));
register_private_address_connection_get(isolate, exports,
compatibility_new<String>
(isolate, "private_address_connection_get"));
}
} } } // namespace efl { namespace eldbus { namespace js {

View File

@ -0,0 +1,183 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eldbus_Js.hh>
namespace efl { namespace eldbus { namespace js {
namespace {
void register_init(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto init = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = eldbus_init();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, init)
->GetFunction());
}
void register_shutdown(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
using v8::FunctionTemplate;
auto shutdown = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 0)
return compatibility_return();
auto isolate = args.GetIsolate();
auto ret = eldbus_shutdown();
return compatibility_return(compatibility_new<Integer>(isolate, ret),
args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, shutdown)
->GetFunction());
}
void register_fdo_bus(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name, compatibility_new<String>(isolate, ELDBUS_FDO_BUS));
}
void register_fdo_path(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name, compatibility_new<String>(isolate, ELDBUS_FDO_PATH));
}
void register_fdo_interface(v8::Isolate *isolate, v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name, compatibility_new<String>(isolate, ELDBUS_FDO_INTERFACE));
}
void register_fdo_interface_properties(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name,
compatibility_new<String>(isolate,
ELDBUS_FDO_INTERFACE_PROPERTIES));
}
void register_fdo_interface_object_manager(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name,
compatibility_new<String>(isolate,
ELDBUS_FDO_INTERFACE_OBJECT_MANAGER));
}
void register_fdo_interface_introspectable(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name,
compatibility_new<String>(isolate,
ELDBUS_FDO_INTERFACE_INTROSPECTABLE));
}
void register_fdo_inteface_peer(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name,
compatibility_new<String>(isolate, ELDBUS_FDO_INTEFACE_PEER));
}
void register_error_pending_canceled(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name,
compatibility_new<String>(isolate,
ELDBUS_ERROR_PENDING_CANCELED));
}
void register_error_pending_timeout(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
global->Set(name,
compatibility_new<String>(isolate,
ELDBUS_ERROR_PENDING_TIMEOUT));
}
}
EAPI
void register_eldbus_core(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
using v8::String;
register_init(isolate, exports,
compatibility_new<String>(isolate, "eldbus_init"));
register_shutdown(isolate, exports,
compatibility_new<String>(isolate, "eldbus_shutdown"));
register_fdo_bus(isolate, exports,
compatibility_new<String>(isolate, "ELDBUS_FDO_BUS"));
register_fdo_path(isolate, exports,
compatibility_new<String>(isolate, "ELDBUS_FDO_PATH"));
register_fdo_interface(isolate, exports,
compatibility_new<String>(isolate,
"ELDBUS_FDO_INTERFACE"));
register_fdo_interface_properties(isolate, exports,
compatibility_new<String>
(isolate,
"ELDBUS_FDO_INTERFACE_PROPERTIES"));
register_fdo_interface_object_manager(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_FDO_INTERFACE_OBJECT_MANAGER"));
register_fdo_interface_introspectable
(isolate, exports,
compatibility_new<String>(isolate,
"ELDBUS_FDO_INTERFACE_INTROSPECTABLE"));
register_fdo_inteface_peer(isolate, exports,
compatibility_new<String>
(isolate, "ELDBUS_FDO_INTEFACE_PEER"));
register_error_pending_canceled
(isolate, exports,
compatibility_new<String>(isolate, "ELDBUS_ERROR_PENDING_CANCELED"));
register_error_pending_timeout
(isolate, exports,
compatibility_new<String>(isolate, "ELDBUS_ERROR_PENDING_TIMEOUT"));
}
EAPI void register_eldbus(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
register_eldbus_connection(isolate, exports);
register_eldbus_core(isolate, exports);
register_eldbus_message(isolate, exports);
register_eldbus_object_mapper(isolate, exports);
}
} } } // namespace efl { namespace eldbus { namespace js {

View File

@ -0,0 +1,103 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eldbus_Js.hh>
namespace efl { namespace eldbus { namespace js {
namespace {
void register_message_method_call_new(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsString()
|| !args[2]->IsString() || !args[3]->IsString()) {
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto ret = eldbus_message_method_call_new(*String::Utf8Value(args[0]),
*String::Utf8Value(args[1]),
*String::Utf8Value(args[2]),
*String::Utf8Value(args[3]));
return compatibility_return(wrap_eldbus_msg(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_message_error_new(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 3 || !args[0]->IsObject() || !args[1]->IsString()
|| !args[2]->IsString()) {
return compatibility_return();
}
auto isolate = args.GetIsolate();
auto ret = eldbus_message_error_new(extract_eldbus_msg(args[0]
->ToObject()),
*String::Utf8Value(args[1]),
*String::Utf8Value(args[2]));
return compatibility_return(wrap_eldbus_msg(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
void register_message_method_return_new(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::String;
using v8::FunctionTemplate;
auto f = [](compatibility_callback_info_type args)
-> compatibility_return_type {
if (args.Length() != 1 || !args[0]->IsObject())
return compatibility_return();
auto isolate = args.GetIsolate();
auto eldbus_msg = extract_eldbus_msg(args[0]->ToObject());
auto ret = eldbus_message_method_return_new(eldbus_msg);
return compatibility_return(wrap_eldbus_msg(ret, isolate), args);
};
global->Set(name,
compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
}
}
EAPI
void register_eldbus_message(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
register_message_method_call_new
(isolate, exports, compatibility_new<v8::String>
(isolate, "message_method_call_new"));
register_message_error_new
(isolate, exports, compatibility_new<v8::String>
(isolate, "message_error_new"));
register_message_method_return_new
(isolate, exports, compatibility_new<v8::String>
(isolate, "message_method_return_new"));
}
} } } // namespace efl { namespace eldbus { namespace js {

View File

@ -0,0 +1,100 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Eldbus_Js.hh>
namespace efl { namespace eldbus { namespace js {
namespace {
void register_object_event_iface_added(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_OBJECT_EVENT_IFACE_ADDED));
}
void register_object_event_iface_removed(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate,
ELDBUS_OBJECT_EVENT_IFACE_REMOVED));
}
void register_object_event_property_changed(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>
(isolate, ELDBUS_OBJECT_EVENT_PROPERTY_CHANGED));
}
void register_object_event_property_removed(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>
(isolate, ELDBUS_OBJECT_EVENT_PROPERTY_REMOVED));
}
void register_object_event_del(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ELDBUS_OBJECT_EVENT_DEL));
}
void register_object_event_last(v8::Isolate *isolate,
v8::Handle<v8::Object> global,
v8::Handle<v8::String> name)
{
using v8::Integer;
global->Set(name,
compatibility_new<Integer>(isolate, ELDBUS_OBJECT_EVENT_LAST));
}
}
EAPI
void register_eldbus_object_mapper(v8::Isolate* isolate, v8::Handle<v8::Object> exports)
{
register_object_event_iface_added
(isolate, exports, compatibility_new<v8::String>
(isolate, "object_event_iface_added"));
register_object_event_iface_removed
(isolate, exports, compatibility_new<v8::String>
(isolate, "object_event_iface_removed"));
register_object_event_property_changed
(isolate, exports, compatibility_new<v8::String>
(isolate, "object_event_property_changed"));
register_object_event_property_removed
(isolate, exports, compatibility_new<v8::String>
(isolate, "object_event_property_removed"));
register_object_event_del
(isolate, exports, compatibility_new<v8::String>
(isolate, "object_event_del"));
register_object_event_last
(isolate, exports, compatibility_new<v8::String>
(isolate, "object_event_last"));
}
} } } // namespace efl { namespace eldbus { namespace js {

View File

@ -0,0 +1,836 @@
#ifndef ELDBUS_JS_UTIL_HH
#define ELDBUS_JS_UTIL_HH
namespace efl { namespace eldbus { namespace js {
using eina::js::compatibility_get_pointer_internal_field;
using eina::js::compatibility_set_pointer_internal_field;
using eina::js::compatibility_new;
using eina::js::compatibility_callback_info_type;
using eina::js::compatibility_return_type;
using eina::js::compatibility_return;
v8::Local<v8::Object> wrap_eldbus_connection(Eldbus_Connection *conn,
v8::Isolate *isolate);
inline
const Eldbus_Message *extract_const_eldbus_msg(v8::Local<v8::Object> o)
{
return compatibility_get_pointer_internal_field<Eldbus_Message*>(o, 0);
}
inline
v8::Local<v8::Object> wrap_const_eldbus_msg(const Eldbus_Message *msg,
v8::Isolate *isolate)
{
using v8::String;
using v8::Object;
using v8::Boolean;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto path_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
auto ret = eldbus_message_path_get(msg);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto interface_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
auto ret = eldbus_message_interface_get(msg);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto member_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
auto ret = eldbus_message_member_get(msg);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto destination_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
auto ret = eldbus_message_destination_get(msg);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto sender_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
auto ret = eldbus_message_sender_get(msg);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto signature_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
auto ret = eldbus_message_signature_get(msg);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto error_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto msg = extract_const_eldbus_msg(info.This());
const char *name = NULL;
const char *text = NULL;
auto ret = compatibility_new<Object>(isolate);
auto bret = eldbus_message_error_get(msg, &name, &text);
ret->Set(compatibility_new<String>(isolate, "ok"),
compatibility_new<Boolean>(isolate, bret));
if (bret) {
ret->Set(compatibility_new<String>(isolate, "name"),
compatibility_new<String>(isolate, name));
ret->Set(compatibility_new<String>(isolate, "text"),
compatibility_new<String>(isolate, text));
}
return compatibility_return(ret, info);
};
ret->Set(compatibility_new<String>(isolate, "path_get"),
compatibility_new<FunctionTemplate>(isolate, path_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "interface_get"),
compatibility_new<FunctionTemplate>(isolate, interface_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "member_get"),
compatibility_new<FunctionTemplate>(isolate, member_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "destination_get"),
compatibility_new<FunctionTemplate>(isolate, destination_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "sender_get"),
compatibility_new<FunctionTemplate>(isolate, sender_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "signature_get"),
compatibility_new<FunctionTemplate>(isolate, signature_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "error_get"),
compatibility_new<FunctionTemplate>(isolate, error_get)
->GetFunction());
compatibility_set_pointer_internal_field(ret, 0,
const_cast<Eldbus_Message*>(msg));
return ret;
}
inline Eldbus_Message *extract_eldbus_msg(v8::Local<v8::Object> o)
{
return compatibility_get_pointer_internal_field<Eldbus_Message*>(o, 0);
}
inline
v8::Local<v8::Object> wrap_eldbus_msg(Eldbus_Message *msg, v8::Isolate *isolate)
{
using v8::String;
using v8::FunctionTemplate;
auto ret = wrap_const_eldbus_msg(msg, isolate);
auto ref = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto msg = extract_eldbus_msg(info.This());
eldbus_message_ref(msg);
return compatibility_return();
};
auto unref = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto msg = extract_eldbus_msg(info.This());
eldbus_message_unref(msg);
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "ref"),
compatibility_new<FunctionTemplate>(isolate, ref)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "unref"),
compatibility_new<FunctionTemplate>(isolate, unref)
->GetFunction());
return ret;
}
inline
v8::Local<v8::Object> wrap_eldbus_pending(Eldbus_Pending *pending,
efl::eina::js::global_ref<v8::Value>*
persistent,
v8::Isolate *isolate)
{
using v8::String;
using v8::Object;
using v8::Boolean;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
typedef decltype(persistent) persistent_ptr_t;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(2);
auto ret = obj_tpl->NewInstance();
auto cancel = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto o = info.This();
auto pending
= compatibility_get_pointer_internal_field<Eldbus_Pending*>(o, 0);
auto persistent
= compatibility_get_pointer_internal_field<persistent_ptr_t>(o, 1);
eldbus_pending_cancel(pending);
delete persistent;
return compatibility_return();
};
auto destination_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto pending
= compatibility_get_pointer_internal_field<Eldbus_Pending*>(o, 0);
auto ret = eldbus_pending_destination_get(pending);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto path_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto pending
= compatibility_get_pointer_internal_field<Eldbus_Pending*>(o, 0);
auto ret = eldbus_pending_path_get(pending);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto interface_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto pending
= compatibility_get_pointer_internal_field<Eldbus_Pending*>(o, 0);
auto ret = eldbus_pending_interface_get(pending);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto method_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto pending
= compatibility_get_pointer_internal_field<Eldbus_Pending*>(o, 0);
auto ret = eldbus_pending_method_get(pending);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
ret->Set(compatibility_new<String>(isolate, "cancel"),
compatibility_new<FunctionTemplate>(isolate, cancel)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "destination_get"),
compatibility_new<FunctionTemplate>(isolate, destination_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "path_get"),
compatibility_new<FunctionTemplate>(isolate, path_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "interface_get"),
compatibility_new<FunctionTemplate>(isolate, interface_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "method_get"),
compatibility_new<FunctionTemplate>(isolate, method_get)
->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, pending);
compatibility_set_pointer_internal_field(ret, 1, persistent);
return ret;
}
inline
v8::Local<v8::Object>
wrap_eldbus_signal_handler(Eldbus_Signal_Handler *handler,
efl::eina::js::global_ref<v8::Value> *persistent,
v8::Isolate *isolate)
{
using v8::String;
using v8::Object;
using v8::Boolean;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
typedef decltype(persistent) persistent_ptr_t;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(2);
auto ret = obj_tpl->NewInstance();
auto ref = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
eldbus_signal_handler_ref(handler);
return compatibility_return();
};
auto unref = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
eldbus_signal_handler_unref(handler);
return compatibility_return();
};
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto persistent
= compatibility_get_pointer_internal_field<persistent_ptr_t>(o, 1);
eldbus_signal_handler_del(handler);
delete persistent;
return compatibility_return();
};
auto sender_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto ret = eldbus_signal_handler_sender_get(handler);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto path_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto ret = eldbus_signal_handler_path_get(handler);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto interface_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto ret = eldbus_signal_handler_interface_get(handler);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto member_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto ret = eldbus_signal_handler_member_get(handler);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto match_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto ret = eldbus_signal_handler_match_get(handler);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto connection_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto o = info.This();
auto handler
= (compatibility_get_pointer_internal_field<Eldbus_Signal_Handler*>
(o, 0));
auto ret = eldbus_signal_handler_connection_get(handler);
return compatibility_return(wrap_eldbus_connection(ret, isolate), info);
};
ret->Set(compatibility_new<String>(isolate, "ref"),
compatibility_new<FunctionTemplate>(isolate, ref)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "unref"),
compatibility_new<FunctionTemplate>(isolate, unref)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "sender_get"),
compatibility_new<FunctionTemplate>(isolate, sender_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "path_get"),
compatibility_new<FunctionTemplate>(isolate, path_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "interface_get"),
compatibility_new<FunctionTemplate>(isolate, interface_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "member_get"),
compatibility_new<FunctionTemplate>(isolate, member_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "match_get"),
compatibility_new<FunctionTemplate>(isolate, match_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "connection_get"),
compatibility_new<FunctionTemplate>(isolate, connection_get)
->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, handler);
compatibility_set_pointer_internal_field(ret, 1, persistent);
return ret;
}
static
v8::Local<v8::Object> wrap_object_event_callback(Eldbus_Object *obj,
Eldbus_Object_Event_Type type,
Eldbus_Object_Event_Cb cb,
void *cb_data,
v8::Isolate *isolate)
{
using v8::String;
using v8::Integer;
using v8::Value;
using v8::Object;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(3);
auto ret = obj_tpl->NewInstance();
ret->Set(compatibility_new<String>(isolate, "_type"),
compatibility_new<Integer>(isolate, type));
compatibility_set_pointer_internal_field(ret, 0, obj);
compatibility_set_pointer_internal_field(ret, 1, (void*)(cb));
compatibility_set_pointer_internal_field(ret, 2, cb_data);
auto del = [](compatibility_callback_info_type info)
-> compatibility_return_type {
auto o = info.This();
auto isolate = info.GetIsolate();
auto obj
= (compatibility_get_pointer_internal_field<Eldbus_Object*>
(o, 0));
auto cb
= (compatibility_get_pointer_internal_field
<Eldbus_Object_Event_Cb>(o, 1));
auto cb_data
= (compatibility_get_pointer_internal_field
<efl::eina::js::global_ref<Value>*>(o, 2));
auto type
= (static_cast<Eldbus_Object_Event_Type>
(o->Get(compatibility_new<String>(isolate, "_type"))
->IntegerValue()));
eldbus_object_event_callback_del(obj, type, cb, cb_data);
delete cb_data;
return compatibility_return();
};
ret->Set(compatibility_new<String>(isolate, "del"),
compatibility_new<FunctionTemplate>(isolate, del)->GetFunction());
return ret;
}
inline
Eldbus_Object *extract_eldbus_object(v8::Local<v8::Object> o)
{
return compatibility_get_pointer_internal_field<Eldbus_Object*>(o, 0);
}
inline
v8::Local<v8::Object> wrap_eldbus_object(Eldbus_Object *object,
v8::Isolate *isolate)
{
using v8::String;
using v8::Value;
using v8::Handle;
using v8::Function;
using v8::ObjectTemplate;
using v8::FunctionTemplate;
using std::unique_ptr;
typedef efl::eina::js::global_ref<Value> persistent_t;
auto obj_tpl = compatibility_new<ObjectTemplate>(isolate);
obj_tpl->SetInternalFieldCount(1);
auto ret = obj_tpl->NewInstance();
auto ref = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto object = extract_eldbus_object(info.This());
eldbus_object_ref(object);
return compatibility_return();
};
auto unref = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto object = extract_eldbus_object(info.This());
eldbus_object_unref(object);
return compatibility_return();
};
auto event_callback_add = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 2 || !info[0]->IsNumber()
|| !info[1]->IsFunction()) {
return compatibility_return();
}
Eldbus_Object_Event_Type type;
switch (info[0]->IntegerValue()) {
case ELDBUS_OBJECT_EVENT_IFACE_ADDED:
type = ELDBUS_OBJECT_EVENT_IFACE_ADDED;
break;
case ELDBUS_OBJECT_EVENT_IFACE_REMOVED:
type = ELDBUS_OBJECT_EVENT_IFACE_REMOVED;
break;
case ELDBUS_OBJECT_EVENT_PROPERTY_CHANGED:
type = ELDBUS_OBJECT_EVENT_PROPERTY_CHANGED;
break;
case ELDBUS_OBJECT_EVENT_PROPERTY_REMOVED:
type = ELDBUS_OBJECT_EVENT_PROPERTY_REMOVED;
break;
case ELDBUS_OBJECT_EVENT_DEL:
type = ELDBUS_OBJECT_EVENT_DEL;
break;
case ELDBUS_OBJECT_EVENT_LAST:
type = ELDBUS_OBJECT_EVENT_LAST;
break;
default:
return compatibility_return();
}
auto isolate = info.GetIsolate();
unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[1]}};
auto cb = [](void *data, Eldbus_Object *obj, void */*event_info*/) {
auto persistent = reinterpret_cast<persistent_t*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args{wrap_eldbus_object(obj, isolate)};
Function::Cast(*o)->Call(o->ToObject(), 1, &args);
};
auto object = extract_eldbus_object(info.This());
eldbus_object_event_callback_add(object, type, cb, cb_data.get());
auto ret = wrap_object_event_callback(object, type, cb,
cb_data.release(), isolate);
return compatibility_return(ret, info);
};
auto connection_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto object = extract_eldbus_object(info.This());
auto conn = eldbus_object_connection_get(object);
return compatibility_return(wrap_eldbus_connection(conn, isolate),
info);
};
auto bus_name_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto object = extract_eldbus_object(info.This());
auto ret = eldbus_object_bus_name_get(object);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto path_get = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 0)
return compatibility_return();
auto isolate = info.GetIsolate();
auto object = extract_eldbus_object(info.This());
auto ret = eldbus_object_path_get(object);
return compatibility_return(compatibility_new<String>(isolate, ret),
info);
};
auto send = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 3 || !info[0]->IsObject() || !info[1]->IsFunction()
|| !info[2]->IsNumber()) {
return compatibility_return();
}
auto isolate = info.GetIsolate();
auto obj = extract_eldbus_object(info.This());
auto msg
= (compatibility_get_pointer_internal_field<Eldbus_Message*>
(info[0]->ToObject(), 0));
unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[1]}};
auto cb = [](void *data, const Eldbus_Message *msg,
Eldbus_Pending *pending) {
auto persistent = reinterpret_cast<persistent_t*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args[2] = {
wrap_const_eldbus_msg(msg, isolate),
wrap_eldbus_pending(pending, persistent, isolate)
};
Function::Cast(*o)->Call(o->ToObject(), 2, args);
delete persistent;
};
auto ret = eldbus_object_send(obj, msg, cb, cb_data.get(),
info[2]->NumberValue());
return compatibility_return(wrap_eldbus_pending(ret, cb_data.release(),
isolate),
info);
};
auto signal_handler_add = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 3 || !info[0]->IsString() || !info[1]->IsString()
|| !info[2]->IsFunction()) {
return compatibility_return();
}
auto isolate = info.GetIsolate();
auto object = extract_eldbus_object(info.This());
String::Utf8Value interface(info[0]);
String::Utf8Value member(info[1]);
unique_ptr<persistent_t> cb_data{new persistent_t{isolate, info[2]}};
auto cb = [](void *data, const Eldbus_Message *msg) {
auto persistent = reinterpret_cast<persistent_t*>(data);
auto o = persistent->handle();
auto isolate = v8::Isolate::GetCurrent();
Handle<Value> args{wrap_const_eldbus_msg(msg, isolate)};
Function::Cast(*o)->Call(o->ToObject(), 1, &args);
};
auto ret = eldbus_object_signal_handler_add(object, *interface, *member,
cb, cb_data.get());
return
compatibility_return(wrap_eldbus_signal_handler(ret,
cb_data.release(),
isolate),
info);
};
auto method_call_new = [](compatibility_callback_info_type info)
-> compatibility_return_type {
if (info.Length() != 2 || !info[0]->IsString()
|| !info[1]->IsString()) {
return compatibility_return();
}
auto isolate = info.GetIsolate();
auto object = extract_eldbus_object(info.This());
auto ret = eldbus_object_method_call_new(object,
*String::Utf8Value(info[0]),
*String::Utf8Value(info[1]));
return compatibility_return(wrap_eldbus_msg(ret, isolate), info);
};
ret->Set(compatibility_new<String>(isolate, "ref"),
compatibility_new<FunctionTemplate>(isolate, ref)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "unref"),
compatibility_new<FunctionTemplate>(isolate, unref)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "event_callback_add"),
compatibility_new<FunctionTemplate>(isolate, event_callback_add)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "connection_get"),
compatibility_new<FunctionTemplate>(isolate, connection_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "bus_name_get"),
compatibility_new<FunctionTemplate>(isolate, bus_name_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "path_get"),
compatibility_new<FunctionTemplate>(isolate, path_get)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "send"),
compatibility_new<FunctionTemplate>(isolate, send)->GetFunction());
ret->Set(compatibility_new<String>(isolate, "signal_handler_add"),
compatibility_new<FunctionTemplate>(isolate, signal_handler_add)
->GetFunction());
ret->Set(compatibility_new<String>(isolate, "method_call_new"),
compatibility_new<FunctionTemplate>(isolate, method_call_new)
->GetFunction());
compatibility_set_pointer_internal_field(ret, 0, object);
return ret;
}
} } } // namespace efl { namespace eldbus { namespace js {
#endif /* ELDBUS_JS_UTIL_HH */

View File

@ -0,0 +1,15 @@
#ifndef EFL_EO_JS_HH
#define EFL_EO_JS_HH
#include <Eina_Js.hh>
#include <eo_js_direction.hh>
#include <eo_js_constructor.hh>
#include <eo_js_call_function.hh>
#include <eo_js_event.hh>
#include <eo_js_namespace.hh>
#include <eo_js_struct.hh>
#include <eo_js_construct_from_eo.hh>
#endif

View File

@ -0,0 +1,288 @@
#ifndef EFL_EO_JS_CALL_FUNCTION_HH
#define EFL_EO_JS_CALL_FUNCTION_HH
#include <eina_tuple.hh>
#include <eina_tuple_c.hh>
#include <eina_function.hh>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
inline eina::js::compatibility_return_type call_function(eina::js::compatibility_callback_info_type args)
{
void* data = v8::External::Cast(*args.Data())->Value();
std::function<eina::js::compatibility_return_type(eina::js::compatibility_callback_info_type)>*
f = static_cast<std::function<eina::js::compatibility_return_type(eina::js::compatibility_callback_info_type)>*>(data);
return (*f)(args);
}
template <typename In, std::size_t I>
struct is_in : eina::_mpl::tuple_contains<std::integral_constant<std::size_t, I>, In>
{};
template <typename In, std::size_t I>
struct arg_index : std::integral_constant<std::size_t,
std::conditional<is_in<In, I>::value, std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 0>>::type::value +
arg_index<In, I - 1>::value>
{};
template <typename In>
struct arg_index<In, 0> : std::integral_constant<std::size_t, 0>
{};
template <typename In, typename Out, typename Ownership, typename F, typename Return, typename Parameters>
struct method_caller
{
typedef typename eina::_mpl::function_params<F>::type parameters_t;
template <std::size_t I>
struct is_out : eina::_mpl::tuple_contains<std::integral_constant<std::size_t, I>, Out>
{};
template <std::size_t I>
struct is_inout : std::integral_constant<bool,
eina::_mpl::tuple_contains<std::integral_constant<std::size_t, I>, Out>::value &&
eina::_mpl::tuple_contains<std::integral_constant<std::size_t, I>, In>::value>
{};
template <std::size_t I, typename Outs>
static
typename std::tuple_element<I, parameters_t>::type
get_value(eina::js::compatibility_callback_info_type args, Outs& /*outs*/, v8::Isolate* isolate, char const* class_name
, std::false_type)
{
using Param = typename std::tuple_element<I, Parameters>::type;
const auto js_index = arg_index<In, I>::value;
return eina::js::get_value_from_javascript
(args[js_index], isolate, class_name, eina::js::value_tag<Param>());
}
template <std::size_t I, typename Outs>
static
typename std::add_pointer<
typename std::tuple_element
<eina::_mpl::tuple_find<std::integral_constant<std::size_t, I>, Out>::value
, Outs>::type>::type
get_value(eina::js::compatibility_callback_info_type, Outs& outs, v8::Isolate*, char const*
, std::true_type)
{
return &std::get<eina::_mpl::tuple_find<std::integral_constant<std::size_t, I>, Out>::value>
(outs);
}
template <typename OutParameter, std::size_t I, typename R>
eina::js::compatibility_return_type
create_return_unique_value(eina::js::compatibility_callback_info_type args
, R const& r) const
{
return eina::js::compatibility_return(
eina::js::get_value_from_c(
eina::js::wrap_value<OutParameter>(r, eina::js::value_tag<OutParameter>{}),
args.GetIsolate(),
class_names[I]),
args);
}
template <typename OutParameters, typename Outs>
eina::js::compatibility_return_type
create_return_value(eina::js::compatibility_callback_info_type args
, Outs const& outs
, typename std::enable_if<std::tuple_size<Outs>::value == 1>::type* = 0) const
{
using OutParameter = typename std::tuple_element<0, OutParameters>::type;
return create_return_unique_value<OutParameter, std::tuple_element<0, Out>::type::value>(args, std::get<0u>(outs));
}
template <typename OutParameters, typename Outs>
eina::js::compatibility_return_type
create_return_value(eina::js::compatibility_callback_info_type
, Outs const&
, typename std::enable_if<std::tuple_size<Outs>::value == 0>::type* = 0) const
{
// nothing
return eina::js::compatibility_return();
}
template <typename OutParameters, typename Outs>
eina::js::compatibility_return_type
create_return_value(eina::js::compatibility_callback_info_type args
, Outs const& outs
, typename std::enable_if<(std::tuple_size<Outs>::value > 1)>::type* = 0) const
{
v8::Isolate* isolate = args.GetIsolate();
int const length = std::tuple_size<Outs>::value;
v8::Local<v8::Array> ret = eina::js::compatibility_new<v8::Array>(isolate, length);
set_return<OutParameters, 0u>(isolate, ret, outs, eina::make_index_sequence<std::tuple_size<Outs>::value>());
return eina::js::compatibility_return(ret, args);
}
template <typename OutParameters, typename R, typename Outs>
eina::js::compatibility_return_type
create_return_value(eina::js::compatibility_callback_info_type args
, R const& r
, Outs const&
, typename std::enable_if<std::tuple_size<Outs>::value == 0>::type* = 0) const
{
return create_return_unique_value<Return, std::tuple_size<Ownership>::value>(args, r);
}
template <typename OutParameters, std::size_t Offset, typename Outs, std::size_t...S>
void set_return(v8::Isolate* isolate, v8::Local<v8::Array> r
, Outs const& outs, eina::index_sequence<S...>) const
{
std::initializer_list<int> l
= {(r->Set(S+Offset, eina::js::get_value_from_c(
eina::js::wrap_value<typename std::tuple_element<S, OutParameters>::type>(std::get<S>(outs), eina::js::value_tag<typename std::tuple_element<S, OutParameters>::type>{}),
isolate,
class_names[std::tuple_element<S, Out>::type::value])),0)...};
static_cast<void>(l);
}
template <typename OutParameters, typename R, typename Outs>
eina::js::compatibility_return_type
create_return_value(eina::js::compatibility_callback_info_type args
, R const& r
, Outs const& outs
, typename std::enable_if<std::tuple_size<Outs>::value != 0>::type* = 0) const
{
v8::Isolate* isolate = args.GetIsolate();
int const length = std::tuple_size<Outs>::value + 1;
v8::Local<v8::Array> ret = eina::js::compatibility_new<v8::Array>(isolate, length);
ret->Set(0, eina::js::get_value_from_c(
eina::js::wrap_value<Return>(r, eina::js::value_tag<Return>{}),
isolate,
class_names[std::tuple_size<Ownership>::value]));
set_return<OutParameters, 1u>(isolate, ret, outs, eina::make_index_sequence<std::tuple_size<Outs>::value>());
return eina::js::compatibility_return(ret, args);
}
template <std::size_t I, typename Outs>
static void
init_inout(eina::js::compatibility_callback_info_type args
, Outs& outs
, v8::Isolate* isolate
, char const* class_name
, std::true_type)
{
using Param = typename std::remove_pointer<typename std::tuple_element<I, Parameters>::type>::type;
const auto js_index = arg_index<In, I>::value;
*get_value<I>(args, outs, args.GetIsolate(), class_name, std::true_type()) =
eina::js::get_value_from_javascript(args[js_index], isolate, class_name, eina::js::value_tag<Param>());;
}
template <std::size_t I, typename Outs>
static void
init_inout(eina::js::compatibility_callback_info_type
, Outs&
, v8::Isolate*
, char const*
, std::false_type)
{
}
template <typename OutParameters, std::size_t... I>
eina::js::compatibility_return_type
aux(eina::js::compatibility_callback_info_type args, eina::index_sequence<I...>
, std::true_type) const
{
typename eina::_mpl::tuple_transform<Out, out_transform<parameters_t> >::type outs {};
static_cast<void>(outs);
std::initializer_list<int> l =
{(init_inout<I>(args, outs, args.GetIsolate(), class_names[I], typename is_inout<I>::type()), 0)...};
static_cast<void>(l);
function(get_value<I>(args, outs, args.GetIsolate(), class_names[I], typename is_out<I>::type())...);
return create_return_value<OutParameters>(args, outs);
}
template <typename OutParameters, std::size_t... I>
eina::js::compatibility_return_type
aux(eina::js::compatibility_callback_info_type args, eina::index_sequence<I...>
, std::false_type) const
{
typename eina::_mpl::tuple_transform<Out, out_transform<parameters_t> >::type outs {};
static_cast<void>(outs);
std::initializer_list<int> l =
{(init_inout<I>(args, outs, args.GetIsolate(), class_names[I], typename is_inout<I>::type()), 0)...};
static_cast<void>(l);
typename eina::_mpl::function_return<F>::type r =
function(get_value<I>(args, outs, args.GetIsolate(), class_names[I], typename is_out<I>::type())...);
return create_return_value<OutParameters>(args, r, outs);
}
template <typename P>
struct out_transform
{
template <typename T>
struct apply
{
typedef typename std::remove_pointer<typename std::tuple_element<T::value, P>::type>::type type;
};
};
eina::js::compatibility_return_type operator()(eina::js::compatibility_callback_info_type args)
{
using OutParameters = typename eina::_mpl::tuple_transform<Out, out_transform<Parameters> >::type;
int input_parameters = std::tuple_size<In>::value;
if(input_parameters <= args.Length())
{
v8::Local<v8::Object> self = args.This();
v8::Local<v8::Value> external = self->GetInternalField(0);
Eo* eo = static_cast<Eo*>(v8::External::Cast(*external)->Value());
try
{
eo_do
(eo,
aux<OutParameters>(
args,
eina::make_index_sequence<std::tuple_size<parameters_t>::value>(),
std::is_same<void, Return>())
);
}
catch(std::logic_error const&)
{
return eina::js::compatibility_return();
}
}
else
{
return eina::js::compatibility_throw
(v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(nullptr, "Expected more arguments for this call")));
}
}
template <typename A>
method_caller(F f, A&& c)
: function(f)
, class_names(std::forward<A>(c))
{}
F function;
/// Hold the names of the type of each argument, with the return's type name at the end
std::array<const char*, std::tuple_size<Ownership>::value + 1> class_names;
};
template <typename In, typename Out, typename Ownership, typename Return, typename Parameters, std::size_t N, typename F>
v8::Handle<v8::Value> call_function_data(v8::Isolate* isolate, std::array<const char*, N> class_names, F f)
{
return eina::js::compatibility_new<v8::External>
(isolate, new std::function<eina::js::compatibility_return_type(eina::js::compatibility_callback_info_type const&)>
(method_caller<In, Out, Ownership, F, Return, Parameters>{f, class_names}));
}
} } }
#endif

View File

@ -0,0 +1,39 @@
#ifndef EFL_EO_JS_CONSTRUCT_FROM_EO_HH
#define EFL_EO_JS_CONSTRUCT_FROM_EO_HH
#include <eina_tuple.hh>
#include <eina_tuple_c.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
inline eina::js::compatibility_return_type construct_from_eo(eina::js::compatibility_callback_info_type args)
{
if(args.IsConstructCall())
{
Eo* eo = static_cast<Eo*>(v8::External::Cast(*args[0])->Value());
args.This()->SetInternalField(0, args[0]);
efl::eina::js::make_weak(args.GetIsolate(), args.This(), [eo] { eo_unref(eo); });
return eina::js::compatibility_return();
}
else
{
std::size_t argc = args.Length();
std::vector<v8::Local<v8::Value> > argv (argc ? argc : 1 );
for(int i = 0; i != args.Length(); ++i)
argv[i] = args[i];
args.Callee()->NewInstance(argc, &argv[0]);
return eina::js::compatibility_return();
}
}
} } }
#endif

View File

@ -0,0 +1,136 @@
#ifndef EFL_EO_JS_CONSTRUCTOR_HH
#define EFL_EO_JS_CONSTRUCTOR_HH
#include <Eina.hh>
#include <eina_tuple.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
inline eina::js::compatibility_return_type constructor(eina::js::compatibility_callback_info_type args)
{
if(args.IsConstructCall())
{
void* data = v8::External::Cast(*args.Data())->Value();
std::function<eina::js::compatibility_return_type(eina::js::compatibility_callback_info_type)>*
f = static_cast<std::function<eina::js::compatibility_return_type(eina::js::compatibility_callback_info_type)>*>
(data);
return (*f)(args);
}
else
{
std::size_t argc = args.Length();
std::vector<v8::Local<v8::Value> > argv (argc ? argc : 1 );
for(int i = 0; i != args.Length(); ++i)
argv[i] = args[i];
args.Callee()->NewInstance(argc, &argv[0]);
return eina::js::compatibility_return();
}
}
template <typename...F>
struct constructor_caller
{
struct call
{
template <typename T>
void operator()(T function) const
{
int const parameters
= std::tuple_size<typename eina::_mpl::function_params<T>::type>::value;
if(*current + parameters <= args->Length())
{
aux(function, eina::make_index_sequence<parameters>());
*current += parameters;
}
else
{
eina::js::compatibility_throw
(v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args->GetIsolate(), "Expected more arguments for this call")));
throw std::logic_error("");
}
}
template <typename U, std::size_t I>
static
typename std::tuple_element<I, typename eina::_mpl::function_params<U>::type>::type
get_value(v8::Local<v8::Value> v, v8::Isolate* isolate)
{
typename std::tuple_element<I, typename eina::_mpl::function_params<U>::type>::type
tmp =
eina::js::get_value_from_javascript
(v, isolate, ""
, eina::js::value_tag<typename std::tuple_element
<I, typename eina::_mpl::function_params<U>::type>::type>());
return tmp;
}
template <typename T, std::size_t... I>
void aux(T function, eina::index_sequence<I...>) const
{
function(get_value<T, I>((*args)[I + *current], args->GetIsolate())...);
}
int* current;
eina::js::compatibility_callback_info_pointer args;
};
eina::js::compatibility_return_type operator()(eina::js::compatibility_callback_info_type args) const
{
int current_index = 1;
if(args.Length() != 0)
{
try
{
Eo* parent = eina::js::get_value_from_javascript
(args[0], args.GetIsolate(), "", eina::js::value_tag<Eo*>());
Eo* eo = eo_add
(klass
, parent
, eina::_mpl::for_each(constructors, call{&current_index, &args})
);
assert(eo != 0);
v8::Local<v8::Object> self = args.This();
self->SetInternalField(0, eina::js::compatibility_new<v8::External>(args.GetIsolate(), eo));
efl::eina::js::make_weak(args.GetIsolate(), self
, [eo]
{
eo_unref(eo);
});
}
catch(std::logic_error const&) {}
}
else
{
eina::js::compatibility_throw
(v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Expected at least one argument for this call")));
}
return eina::js::compatibility_return();
}
Eo_Class const* klass;
std::tuple<F...> constructors;
};
template <typename... F>
v8::Handle<v8::Value> constructor_data(v8::Isolate* isolate, Eo_Class const* klass, F... f)
{
return eina::js::compatibility_new<v8::External>
(isolate
, new std::function<eina::js::compatibility_return_type(eina::js::compatibility_callback_info_type)>
(constructor_caller<F...>{klass, std::tuple<F...>{f...}}));
}
} } }
#endif

View File

@ -0,0 +1,12 @@
#ifndef EFL_EO_JS_EO_JS_DIRECTION_HH
#define EFL_EO_JS_EO_JS_DIRECTION_HH
namespace efl { namespace eo { namespace js {
struct input {};
struct output {};
struct input_output {};
} } }
#endif

View File

@ -0,0 +1,126 @@
#ifndef EFL_EO_JS_EVENT_HH
#define EFL_EO_JS_EVENT_HH
#include <eina_tuple.hh>
#include <eina_tuple_c.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
struct event_information
{
eina::js::global_ref<v8::Function>* constructor;
Eo_Event_Description const* event;
Eo_Event_Cb event_callback;
const char* class_name;
};
typedef std::map<std::string, event_information*> event_information_map;
struct event_callback_information
{
event_information* event_info;
eina::js::global_ref<v8::Function> function;
};
template <typename T>
v8::Local<v8::Value> get_event_info(void* event_info, v8::Isolate* isolate, const char* class_name)
{
using no_tag_type = typename eina::js::remove_tag<T>::type;
return eina::js::get_value_from_c(
eina::js::wrap_value<T>(*static_cast<no_tag_type*>(event_info), eina::js::value_tag<T>{}),
isolate,
class_name);
}
// FIXME: This shouldn't be necessary. Reveiew Eolian standards.
template <>
inline v8::Local<v8::Value> get_event_info<const char*>(void* event_info, v8::Isolate* isolate, const char*)
{
return eina::js::get_value_from_c(static_cast<const char*>(event_info), isolate, "");
}
template <>
inline v8::Local<v8::Value> get_event_info<void>(void*, v8::Isolate* isolate, const char*)
{
return v8::Undefined(isolate);
}
template <typename T>
inline Eina_Bool event_callback(void* data, Eo* obj, Eo_Event_Description const*
, void* event_info)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
event_callback_information* event = static_cast<event_callback_information*>(data);
v8::Handle<v8::Value> a[] = {eina::js::compatibility_new<v8::External>(isolate, obj)};
v8::Local<v8::Object> self = (event->event_info->constructor->handle())->NewInstance(1, a);
v8::Local<v8::Value> call_args[] = {
self,
get_event_info<T>(event_info, isolate, event->event_info->class_name)
};
event->function.handle()->Call(eina::js::compatibility_global(), 2, call_args);
return EO_CALLBACK_CONTINUE;
}
inline eina::js::compatibility_return_type on_event(eina::js::compatibility_callback_info_type args)
{
if (args.Length() >= 2)
{
v8::Local<v8::Value> ev_name = args[0];
v8::Local<v8::Value> f = args[1];
if (ev_name->IsString() && f->IsFunction())
{
v8::Local<v8::Value> data = args.Data();
auto ev_map =
static_cast<event_information_map*>
(v8::External::Cast(*data)->Value());
v8::String::Utf8Value str(ev_name->ToString());
auto found = ev_map->find(*str);
if (found == ev_map->end())
return eina::js::compatibility_return();
auto event = found->second;
v8::Local<v8::Object> self = args.This();
v8::Local<v8::Value> external = self->GetInternalField(0);
Eo* eo = static_cast<Eo*>(v8::External::Cast(*external)->Value());
auto isolate = args.GetIsolate();
event_callback_information* i = new event_callback_information
{event, {isolate, eina::js::compatibility_cast<v8::Function>(f)}};
eo_do(eo, eo_event_callback_priority_add
(event->event, EO_CALLBACK_PRIORITY_DEFAULT, event->event_callback, i));
}
else
{
eina::js::compatibility_throw
(v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Invalid argument type")));
throw std::logic_error("");
}
}
else
{
eina::js::compatibility_throw
(v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(args.GetIsolate(), "Expected more arguments for this call")));
throw std::logic_error("");
}
return eina::js::compatibility_return();
}
} } }
#endif

View File

@ -0,0 +1,24 @@
#ifndef EFL_EO_JS_NAMESPACE_HH
#define EFL_EO_JS_NAMESPACE_HH
namespace efl { namespace eo { namespace js {
inline
v8::Local<v8::Object> get_namespace(std::vector<const char*> const& nss, v8::Isolate* isolate, v8::Local<v8::Object> to_export)
{
for (auto ns : nss)
{
v8::Local<v8::Value> ns_obj = to_export->Get(::efl::eina::js::compatibility_new<v8::String>(isolate, ns));
if (ns_obj->IsUndefined() || ns_obj->IsNull())
{
ns_obj = ::efl::eina::js::compatibility_new<v8::Object>(isolate);
to_export->Set(::efl::eina::js::compatibility_new<v8::String>(isolate, ns), ns_obj);
}
to_export = ns_obj->ToObject();
}
return to_export;
}
} } }
#endif

View File

@ -0,0 +1,106 @@
#ifndef EFL_EO_JS_STRUCT_HH
#define EFL_EO_JS_STRUCT_HH
#include <eina_tuple.hh>
#include <eina_tuple_c.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
template <typename S, typename M, M S::*MPtr, typename K>
eina::js::compatibility_accessor_getter_return_type
get_struct_member(v8::Local<v8::String>, eina::js::compatibility_accessor_getter_callback_info_type info)
{
v8::Local<v8::Object> self_obj = eina::js::compatibility_cast<v8::Object>(info.This());
auto sct = static_cast<S*>(eina::js::compatibility_get_pointer_internal_field(self_obj, 0));
return eina::js::compatibility_return(eina::js::get_value_from_c(sct->*MPtr, info.GetIsolate(), K::class_name()), info);
}
template <typename S, typename GenTag, typename M, M S::*MPtr, typename K>
eina::js::compatibility_accessor_setter_return_type
set_struct_member(v8::Local<v8::String>, v8::Local<v8::Value> value, eina::js::compatibility_accessor_setter_callback_info_type info)
{
v8::Local<v8::Object> self_obj = eina::js::compatibility_cast<v8::Object>(info.This());
auto sct = static_cast<S*>(eina::js::compatibility_get_pointer_internal_field(self_obj, 0));
sct->*MPtr = eina::js::get_value_from_javascript(value, info.GetIsolate(), K::class_name(), eina::js::value_tag<GenTag>());
}
template <typename S>
eina::js::compatibility_return_type new_struct(eina::js::compatibility_callback_info_type args)
{
if (!args.IsConstructCall())
return eina::js::compatibility_throw
(nullptr, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(nullptr, "Not constructor call")));
if(args.Length() == 0)
{
S* p = new S{};
eina::js::compatibility_set_pointer_internal_field(args.This(), 0, static_cast<void*>(p));
}
else
{
if (!args[0]->IsExternal())
return eina::js::compatibility_throw
(nullptr, v8::Exception::TypeError
(eina::js::compatibility_new<v8::String>(nullptr, "Invalid argument type for constructor call")));
S* p = reinterpret_cast<S*>(v8::External::Cast(*args[0])->Value());
eina::js::compatibility_set_pointer_internal_field(args.This(), 0, static_cast<void*>(p));
}
return eina::js::compatibility_return();
}
template <typename S, typename F>
inline void register_struct_persistent(v8::Isolate* isolate, const char* name, const char* full_name, F&& fields_func)
{
v8::Handle<v8::FunctionTemplate> constructor = eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::new_struct<S>);
constructor->SetClassName(eina::js::compatibility_new<v8::String>(isolate, name));
v8::Local<v8::ObjectTemplate> instance_t = constructor->InstanceTemplate();
instance_t->SetInternalFieldCount(1);
v8::Local<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();
fields_func(isolate, prototype);
static efl::eina::js::global_ref<v8::ObjectTemplate> instance_persistent{isolate, instance_t};
static efl::eina::js::global_ref<v8::Function> instance_template{isolate, constructor->GetFunction()};
(void)instance_persistent;
eina::js::register_class_constructor(full_name, instance_template.handle());
}
template <typename S, typename F>
void register_struct_exports(v8::Isolate* isolate, const char* name, v8::Handle<v8::Object> exports, F&& fields_func)
{
v8::Handle<v8::FunctionTemplate> constructor = eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::new_struct<S>);
constructor->SetClassName(eina::js::compatibility_new<v8::String>(isolate, name));
v8::Local<v8::ObjectTemplate> instance_t = constructor->InstanceTemplate();
instance_t->SetInternalFieldCount(1);
v8::Local<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();
fields_func(isolate, prototype);
exports->Set(eina::js::compatibility_new<v8::String>(isolate, name), constructor->GetFunction());
}
template <typename S, typename F>
void register_struct(v8::Isolate* isolate, const char* name, const char* full_name, v8::Handle<v8::Object> exports, F&& fields_func)
{
register_struct_persistent<S>(isolate, name, full_name, std::forward<F>(fields_func));
register_struct_exports<S>(isolate, name, exports, std::forward<F>(fields_func));
}
} } }
#endif

View File

@ -0,0 +1,48 @@
#ifndef ETHUMB_JS_INIT_HH
#define ETHUMB_JS_INIT_HH
#include <Eina.hh>
#include <Eina_Js.hh>
#include <Ethumb_Client.h>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_ETHUMB_JS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_ETHUMB_JS_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
namespace efl { namespace ethumb { namespace js {
using ::efl::eina::js::compatibility_new;
using ::efl::eina::js::compatibility_return_type;
using ::efl::eina::js::compatibility_callback_info_type;
using ::efl::eina::js::compatibility_return;
using ::efl::eina::js::compatibility_get_pointer_internal_field;
using ::efl::eina::js::compatibility_set_pointer_internal_field;
EAPI void register_ethumb(v8::Isolate *isolate, v8::Handle<v8::Object> exports);
} } } // namespace efl { namespace ethumb { namespace js {
#endif /* ETHUMB_JS_INIT_HH */

Some files were not shown because too many files have changed in this diff Show More