aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinícius dos Santos Oliveira <vini.ipsmaker@expertisesolutions.com.br>2015-06-02 14:13:30 -0300
committerVinícius dos Santos Oliveira <vini.ipsmaker@expertisesolutions.com.br>2015-06-02 14:13:30 -0300
commit6f531867659d698873c79ed79d76fd670e3bc38c (patch)
tree593d01e1af5fc89461c1fa137d5cf156883009cd
parentInitial binding for Ecore_Mainloop (diff)
downloadefl-6f531867659d698873c79ed79d76fd670e3bc38c.tar.gz
Initial bindings for Ecore_Timer
-rw-r--r--src/Makefile_Ecore_Js.am6
-rw-r--r--src/bindings/ecore_js/ecore_js_timer.cc254
-rw-r--r--src/bindings/ecore_js/ecore_js_timer.hh38
-rw-r--r--src/tests/ecore_js/ecore_js_suite.cc18
-rwxr-xr-xsrc/tests/ecore_js/ecore_js_suite.js82
5 files changed, 396 insertions, 2 deletions
diff --git a/src/Makefile_Ecore_Js.am b/src/Makefile_Ecore_Js.am
index 84c8f98c5f..15afab9e2b 100644
--- a/src/Makefile_Ecore_Js.am
+++ b/src/Makefile_Ecore_Js.am
@@ -22,7 +22,8 @@ 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_mainloop.cc
+bindings/ecore_js/ecore_js_mainloop.cc \
+bindings/ecore_js/ecore_js_timer.cc
ECORE_JS_TEST_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
-DTESTS_WD=\"`pwd`\" \
@@ -40,7 +41,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_mainloop.hh
+bindings/ecore_js/ecore_js_mainloop.hh \
+bindings/ecore_js/ecore_js_timer.hh
### Unit tests
diff --git a/src/bindings/ecore_js/ecore_js_timer.cc b/src/bindings/ecore_js/ecore_js_timer.cc
new file mode 100644
index 0000000000..2458b29cd6
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_timer.cc
@@ -0,0 +1,254 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ecore_js_timer.hh>
+#include <Ecore.h>
+#include <memory>
+#include <cstdlib>
+
+namespace efl { namespace ecore { namespace js {
+
+struct persistent_with_isolate_t
+{
+ template<class S>
+ persistent_with_isolate_t(v8::Isolate *isolate, v8::Handle<S> that)
+ : isolate(isolate)
+ , persistent(isolate, that)
+ {}
+
+ v8::Isolate *isolate;
+ v8::Persistent<v8::Value> persistent;
+};
+
+static Ecore_Timer* extract_timer(v8::Local<v8::Object> object)
+{
+ auto ptr = v8::External::Cast(*object->GetInternalField(0))->Value();
+ return reinterpret_cast<Ecore_Timer*>(ptr);
+}
+
+static 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()));
+ };
+
+ auto freeze = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_timer_freeze(extract_timer(info.This()));
+ };
+
+ 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()));
+ info.GetReturnValue().Set(compatibility_new<Boolean>
+ (info.GetIsolate(), bool(ret)));
+ };
+
+ auto thaw = [](compatibility_callback_info_type info)
+ -> compatibility_return_type {
+ if (info.Length() != 0)
+ return compatibility_return();
+
+ ecore_timer_thaw(extract_timer(info.This()));
+ };
+
+ 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;
+}
+
+EAPI
+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());
+}
+
+EAPI
+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());
+}
+
+EAPI
+void register_timer_dump(v8::Isolate *isolate, v8::Handle<v8::Object> global,
+ v8::Handle<v8::String> name)
+{
+ using v8::String;
+ using v8::FunctionTemplate;
+ using std::unique_ptr;
+ using std::free;
+ using std::unique_ptr;
+
+ auto f = [](compatibility_callback_info_type args)
+ -> compatibility_return_type {
+ if (args.Length() != 0)
+ return compatibility_return();
+
+ auto dump = unique_ptr<char, void(*)(char*)>(ecore_timer_dump(),
+ [](char *str) {
+ free(str);
+ });
+ auto ret = (dump
+ ? compatibility_new<String>(args.GetIsolate(), dump.get())
+ : compatibility_new<String>(args.GetIsolate(), ""));
+
+ return compatibility_return(ret, args);
+ };
+
+ global->Set(name,
+ compatibility_new<FunctionTemplate>(isolate, f)->GetFunction());
+}
+
+EAPI
+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();
+ }
+
+ persistent_with_isolate_t *f
+ = new persistent_with_isolate_t(args.GetIsolate(), args[1]);
+
+ auto cb = [](void *data) -> Eina_Bool {
+ auto persistent
+ = reinterpret_cast<persistent_with_isolate_t *>(data);
+ auto value = Local<Value>::New(persistent->isolate,
+ persistent->persistent);
+ auto closure = Function::Cast(*value);
+
+ auto ret = closure->Call(Undefined(persistent->isolate), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ 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());
+}
+
+EAPI
+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();
+ }
+
+ persistent_with_isolate_t *f
+ = new persistent_with_isolate_t(args.GetIsolate(), args[1]);
+
+ auto cb = [](void *d) -> Eina_Bool {
+ auto persistent
+ = reinterpret_cast<persistent_with_isolate_t *>(d);
+ auto value = Local<Value>::New(persistent->isolate,
+ persistent->persistent);
+ auto closure = Function::Cast(*value);
+
+ auto ret = closure->Call(Undefined(persistent->isolate), 0, NULL);
+ auto bret = ret->IsBoolean() && ret->BooleanValue();
+
+ if (!bret)
+ 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());
+}
+
+} } } // namespace efl { namespace ecore { namespace js {
diff --git a/src/bindings/ecore_js/ecore_js_timer.hh b/src/bindings/ecore_js/ecore_js_timer.hh
new file mode 100644
index 0000000000..e1e65e1020
--- /dev/null
+++ b/src/bindings/ecore_js/ecore_js_timer.hh
@@ -0,0 +1,38 @@
+#ifndef ECORE_JS_TIMER_HH
+#define ECORE_JS_TIMER_HH
+
+#include <Eina.hh>
+#include EINA_STRINGIZE(V8_INCLUDE_HEADER)
+
+#include <eina_js_compatibility.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;
+
+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 */
diff --git a/src/tests/ecore_js/ecore_js_suite.cc b/src/tests/ecore_js/ecore_js_suite.cc
index cc28e2dc37..eb4ad14dd0 100644
--- a/src/tests/ecore_js/ecore_js_suite.cc
+++ b/src/tests/ecore_js/ecore_js_suite.cc
@@ -15,6 +15,7 @@
#include <ecore_js_init.hh>
#include <ecore_js_mainloop.hh>
+#include <ecore_js_timer.hh>
const char* ToCString(const v8::String::Utf8Value& value) {
return *value ? *value : "<string conversion failed>";
@@ -146,6 +147,23 @@ void test_setup(v8::Handle<v8::Object> exports)
"ecore_mainloop_thread_safe_call"
"_sync"));
+ // timer
+ register_timer_precision_get(isolate, exports,
+ compatibility_new<String>(isolate,
+ "ecore_timer_precision"
+ "_get"));
+ register_timer_precision_set(isolate, exports,
+ compatibility_new<String>(isolate,
+ "ecore_timer_precision"
+ "_set"));
+ register_timer_dump(isolate, exports,
+ compatibility_new<String>(isolate, "ecore_timer_dump"));
+ register_timer_add(isolate, exports,
+ compatibility_new<String>(isolate, "ecore_timer_add"));
+ register_timer_loop_add(isolate, exports,
+ compatibility_new<String>(isolate,
+ "ecore_timer_loop_add"));
+
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 4db1781e6a..6882ae9aca 100755
--- a/src/tests/ecore_js/ecore_js_suite.js
+++ b/src/tests/ecore_js/ecore_js_suite.js
@@ -16,6 +16,13 @@ if(typeof process !== 'undefined') {
console.log('running from libv8')
}
+function abs(n) {
+ if (n < 0)
+ return n * -1;
+ return n;
+}
+var TOLERANCE = 0.0001;
+
// Ecore initialization
suite.ecore_init();
@@ -39,6 +46,81 @@ suite.ecore_mainloop_begin();
assert(captured);
+// Timers
+
+var p = 2.5;
+suite.ecore_timer_precision_set(p);
+assert(abs(suite.ecore_timer_precision_get() - p) < TOLERANCE);
+
+p = 0.5;
+suite.ecore_timer_precision_set(p);
+assert(abs(suite.ecore_timer_precision_get() - p) < TOLERANCE);
+
+var dump = suite.ecore_timer_dump();
+assert(typeof(dump) === 'string');
+console.log("### BEGINING of Timer dump: ###");
+console.log(dump);
+console.log("### END of Timer dump ###");
+
+var ncalls = 0;
+
+captured = false;
+suite.ecore_timer_add(1, function() {
+ ++ncalls;
+ if (ncalls != 4)
+ return true;
+
+ captured = true;
+ suite.ecore_mainloop_thread_safe_call_async(suite.ecore_mainloop_quit);
+ return false;
+});
+
+suite.ecore_mainloop_begin();
+assert(captured);
+
+ncalls = 0;
+captured = false;
+
+suite.ecore_timer_loop_add(1, function() {
+ ++ncalls;
+ if (ncalls != 4)
+ return true;
+
+ captured = true;
+ suite.ecore_mainloop_thread_safe_call_async(suite.ecore_mainloop_quit);
+ return false;
+});
+
+suite.ecore_mainloop_begin();
+assert(captured);
+
+captured = false;
+
+var timer = suite.ecore_timer_add(1, function() {
+ captured = true;
+ return false;
+});
+
+assert(timer.freeze_get() === false);
+
+timer.freeze();
+
+assert(timer.freeze_get() === true);
+
+timer.thaw();
+
+assert(timer.freeze_get() === false);
+
+timer.del();
+
+suite.ecore_timer_add(2, function() {
+ suite.ecore_mainloop_thread_safe_call_async(suite.ecore_mainloop_quit);
+ return false;
+});
+
+suite.ecore_mainloop_begin();
+assert(captured === false);
+
// Ecore shutdown
suite.ecore_shutdown();