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