aboutsummaryrefslogtreecommitdiffstats
path: root/src/bindings/eo_js/eo_js_event.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings/eo_js/eo_js_event.hh')
-rw-r--r--src/bindings/eo_js/eo_js_event.hh126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/bindings/eo_js/eo_js_event.hh b/src/bindings/eo_js/eo_js_event.hh
new file mode 100644
index 0000000000..ab2dd34fee
--- /dev/null
+++ b/src/bindings/eo_js/eo_js_event.hh
@@ -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