From d44cf0f62f8db5e1c26ebd9b32d2d30899fcb6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Tue, 2 Jun 2015 14:13:13 -0300 Subject: [PATCH] Initial binding for Ecore_Mainloop --- src/Makefile_Ecore_Js.am | 6 +- src/bindings/ecore_js/ecore_js_mainloop.cc | 270 +++++++++++++++++++++ src/bindings/ecore_js/ecore_js_mainloop.hh | 66 +++++ src/tests/ecore_js/ecore_js_suite.cc | 51 +++- src/tests/ecore_js/ecore_js_suite.js | 26 +- 5 files changed, 410 insertions(+), 9 deletions(-) create mode 100644 src/bindings/ecore_js/ecore_js_mainloop.cc create mode 100644 src/bindings/ecore_js/ecore_js_mainloop.hh diff --git a/src/Makefile_Ecore_Js.am b/src/Makefile_Ecore_Js.am index 330076bf74..84c8f98c5f 100644 --- a/src/Makefile_Ecore_Js.am +++ b/src/Makefile_Ecore_Js.am @@ -21,7 +21,8 @@ lib_ecore_js_libecore_js_la_DEPENDENCIES = @ECORE_INTERNAL_LIBS@ @DL_INTERNAL_LI lib_ecore_js_libecore_js_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ lib_ecore_js_libecore_js_la_SOURCES = \ -bindings/ecore_js/ecore_js_init.cc +bindings/ecore_js/ecore_js_init.cc \ +bindings/ecore_js/ecore_js_mainloop.cc ECORE_JS_TEST_CXXFLAGS = -I$(top_builddir)/src/lib/efl \ -DTESTS_WD=\"`pwd`\" \ @@ -38,7 +39,8 @@ ECORE_JS_TEST_CXXFLAGS = -I$(top_builddir)/src/lib/efl \ installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@ dist_installed_ecorejsheaders_DATA = \ -bindings/ecore_js/ecore_js_init.hh +bindings/ecore_js/ecore_js_init.hh \ +bindings/ecore_js/ecore_js_mainloop.hh ### Unit tests diff --git a/src/bindings/ecore_js/ecore_js_mainloop.cc b/src/bindings/ecore_js/ecore_js_mainloop.cc new file mode 100644 index 0000000000..1924e86666 --- /dev/null +++ b/src/bindings/ecore_js/ecore_js_mainloop.cc @@ -0,0 +1,270 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +namespace efl { namespace ecore { namespace js { + +struct persistent_with_isolate_t +{ + template + persistent_with_isolate_t(v8::Isolate *isolate, v8::Handle that) + : isolate(isolate) + , persistent(isolate, that) + {} + + v8::Isolate *isolate; + v8::Persistent persistent; +}; + +EAPI +void register_callback_cancel(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name) +{ + using v8::Boolean; + global->Set(name, compatibility_new(isolate, + bool{ECORE_CALLBACK_CANCEL})); +} + +EAPI +void register_callback_renew(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name) +{ + using v8::Boolean; + global->Set(name, compatibility_new(isolate, + bool{ECORE_CALLBACK_RENEW})); +} + +EAPI +void register_callback_pass_on(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name) +{ + using v8::Boolean; + global->Set(name, compatibility_new(isolate, + bool{ECORE_CALLBACK_PASS_ON})); +} + +EAPI +void register_callback_done(v8::Isolate *isolate, v8::Handle global, + v8::Handle name) +{ + using v8::Boolean; + global->Set(name, compatibility_new(isolate, + bool{ECORE_CALLBACK_DONE})); +} + +EAPI +void register_mainloop_iterate(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_iterate_may_block(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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 + (args.GetIsolate(), ret), args); + }; + + global->Set(name, + compatibility_new(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_begin(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_quit(v8::Isolate *isolate, v8::Handle global, + v8::Handle 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(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_animator_ticked_get(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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 + (args.GetIsolate(), ret), args); + }; + + global->Set(name, + compatibility_new(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_nested_get(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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 + (args.GetIsolate(), ret), args); + }; + + global->Set(name, + compatibility_new(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_thread_safe_call_async(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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(); + + persistent_with_isolate_t *f + = new persistent_with_isolate_t(args.GetIsolate(), args[0]); + ecore_main_loop_thread_safe_call_async([](void *data) { + persistent_with_isolate_t *persistent + = reinterpret_cast(data); + auto value = Local::New(persistent->isolate, + persistent->persistent); + auto closure = Function::Cast(*value); + + closure->Call(Undefined(persistent->isolate), 0, NULL); + + delete persistent; + }, f); + return compatibility_return(); + }; + + global->Set(name, + compatibility_new(isolate, f)->GetFunction()); +} + +EAPI +void register_mainloop_thread_safe_call_sync(v8::Isolate *isolate, + v8::Handle global, + v8::Handle 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 persistent_with_isolate_t(args.GetIsolate(), args[0]); + void *data = ecore_main_loop_thread_safe_call_sync([](void *data) { + persistent_with_isolate_t *persistent + = reinterpret_cast(data); + auto value = Local::New(persistent->isolate, + persistent->persistent); + auto closure = Function::Cast(*value); + auto res = closure->Call(Undefined(persistent->isolate), 0, + NULL); + void *ret = new persistent_with_isolate_t(persistent->isolate, + res); + + delete persistent; + + return ret; + }, f); + + auto ret = reinterpret_cast(data); + auto value = Local::New(ret->isolate, ret->persistent); + + delete ret; + + return compatibility_return(value, args); + }; + + global->Set(name, + compatibility_new(isolate, f)->GetFunction()); +} + +} } } // namespace efl { namespace js { diff --git a/src/bindings/ecore_js/ecore_js_mainloop.hh b/src/bindings/ecore_js/ecore_js_mainloop.hh new file mode 100644 index 0000000000..968f13fc09 --- /dev/null +++ b/src/bindings/ecore_js/ecore_js_mainloop.hh @@ -0,0 +1,66 @@ +#ifndef ECORE_JS_MAINLOOP_HH +#define ECORE_JS_MAINLOOP_HH + +#include +#include EINA_STRINGIZE(V8_INCLUDE_HEADER) + +#include + +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; + +void register_callback_cancel(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_callback_renew(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_callback_pass_on(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_callback_done(v8::Isolate *isolate, v8::Handle global, + v8::Handle name); + +void register_mainloop_iterate(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_mainloop_iterate_may_block(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_mainloop_begin(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_mainloop_quit(v8::Isolate *isolate, v8::Handle global, + v8::Handle name); + +void register_mainloop_animator_ticked_get(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_mainloop_nested_get(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_mainloop_thread_safe_call_async(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +void register_mainloop_thread_safe_call_sync(v8::Isolate *isolate, + v8::Handle global, + v8::Handle name); + +} } } // namespace efl::js + +#endif /* ECORE_JS_MAINLOOP_HH */ diff --git a/src/tests/ecore_js/ecore_js_suite.cc b/src/tests/ecore_js/ecore_js_suite.cc index 4191ecbb24..cc28e2dc37 100644 --- a/src/tests/ecore_js/ecore_js_suite.cc +++ b/src/tests/ecore_js/ecore_js_suite.cc @@ -14,6 +14,7 @@ #include #include +#include const char* ToCString(const v8::String::Utf8Value& value) { return *value ? *value : ""; @@ -87,16 +88,64 @@ efl::eina::js::compatibility_return_type Print(efl::eina::js::compatibility_call void test_setup(v8::Handle exports) { + using namespace efl::ecore::js; + using efl::eina::js::compatibility_new; + using v8::String; + v8::Isolate *isolate = v8::Isolate::GetCurrent(); + // init efl::ecore::js::register_init(isolate, exports, efl::eina::js::compatibility_new (isolate, "ecore_init")); - efl::ecore::js::register_shutdown(isolate, exports, efl::eina::js::compatibility_new (isolate, "ecore_shutdown")); + // mainloop + register_callback_cancel(isolate, exports, + compatibility_new + (isolate, "ECORE_CALLBACK_CANCEL")); + register_callback_renew(isolate, exports, + compatibility_new + (isolate, "ECORE_CALLBACK_RENEW")); + register_callback_pass_on(isolate, exports, + compatibility_new + (isolate, "ECORE_CALLBACK_PASS_ON")); + register_callback_done(isolate, exports, + compatibility_new + (isolate, "ECORE_CALLBACK_DONE")); + register_mainloop_iterate(isolate, exports, + compatibility_new + (isolate, "ecore_mainloop_iterate")); + register_mainloop_iterate_may_block(isolate, exports, + compatibility_new + (isolate, + "ecore_mainloop_iterate_may_block")); + register_mainloop_begin(isolate, exports, + compatibility_new + (isolate, "ecore_mainloop_begin")); + register_mainloop_quit(isolate, exports, + compatibility_new + (isolate, "ecore_mainloop_quit")); + register_mainloop_animator_ticked_get(isolate, exports, + compatibility_new + (isolate, + "ecore_mainlop_animator_ticked_get")); + register_mainloop_nested_get(isolate, exports, + compatibility_new + (isolate, "ecore_mainloop_nested_get")); + register_mainloop_thread_safe_call_async(isolate, exports, + compatibility_new + (isolate, + "ecore_mainloop_thread_safe_call" + "_async")); + register_mainloop_thread_safe_call_sync(isolate, exports, + compatibility_new + (isolate, + "ecore_mainloop_thread_safe_call" + "_sync")); + std::cerr << __LINE__ << std::endl; } diff --git a/src/tests/ecore_js/ecore_js_suite.js b/src/tests/ecore_js/ecore_js_suite.js index c790da526d..4db1781e6a 100755 --- a/src/tests/ecore_js/ecore_js_suite.js +++ b/src/tests/ecore_js/ecore_js_suite.js @@ -3,8 +3,7 @@ var suite; var assert; -if(typeof process !== 'undefined') -{ +if(typeof process !== 'undefined') { console.log('running from nodejs'); console.log('path', process.env.NODE_PATH); console.log("teste1"); @@ -12,9 +11,7 @@ if(typeof process !== 'undefined') suite = require('ecore_js_suite_mod'); assert = require('assert'); assert(suite != null); -} -else -{ +} else { assert = function(test, message) { if (test !== true) throw message; }; console.log('running from libv8') } @@ -25,6 +22,23 @@ suite.ecore_init(); console.log("Finished init"); +var captured = false; + +// Handlers + +suite.ecore_mainloop_thread_safe_call_async(function() { + captured = true; + suite.ecore_mainloop_quit(); +}); + +// Ecore mainloop init + +suite.ecore_mainloop_begin(); + +// ... + +assert(captured); + // Ecore shutdown suite.ecore_shutdown(); @@ -33,4 +47,4 @@ console.log("Finished shutdown"); // finished tests -console.log ("Test execution with success"); +console.log("Test execution with success");