From fd8c21d21a4cc1b036d508e165803d0bd2a5b9e9 Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Wed, 10 Dec 2014 20:09:12 -0200 Subject: [PATCH] [eolian-js] Added events to JS --- src/Makefile_Eo_Js.am | 2 + src/bin/eolian_js/main.cc | 156 ++++++++++++------ src/bindings/eo_js/Eo_Js.hh | 2 + src/bindings/eo_js/eo_js_call_function.hh | 2 +- src/bindings/eo_js/eo_js_construct_from_eo.hh | 54 ++++++ src/bindings/eo_js/eo_js_constructor.hh | 4 +- src/bindings/eo_js/eo_js_event.hh | 94 +++++++++++ src/bindings/eo_js/eo_js_get_value.hh | 12 +- 8 files changed, 269 insertions(+), 57 deletions(-) create mode 100644 src/bindings/eo_js/eo_js_construct_from_eo.hh create mode 100644 src/bindings/eo_js/eo_js_event.hh diff --git a/src/Makefile_Eo_Js.am b/src/Makefile_Eo_Js.am index 75a67fc66d..43c8579ac0 100644 --- a/src/Makefile_Eo_Js.am +++ b/src/Makefile_Eo_Js.am @@ -9,6 +9,8 @@ bindings/eo_js/eo_js_constructor.hh \ bindings/eo_js/eo_js_direction.hh \ bindings/eo_js/eo_js_get_value_from_c.hh \ bindings/eo_js/eo_js_get_value.hh \ +bindings/eo_js/eo_js_event.hh \ +bindings/eo_js/eo_js_construct_from_eo.hh \ bindings/eo_js/Eo_Js.hh ### Unit tests diff --git a/src/bin/eolian_js/main.cc b/src/bin/eolian_js/main.cc index 0561843a60..5c4c5ebd1e 100644 --- a/src/bin/eolian_js/main.cc +++ b/src/bin/eolian_js/main.cc @@ -164,25 +164,32 @@ int main(int argc, char** argv) separate_functions(klass, EOLIAN_PROPERTY, false); EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "functions were separated"; - - std::function recurse_inherits - = [&] (Eolian_Class const* klass) + + std::function)> + recurse_inherits + = [&] (Eolian_Class const* klass, std::function function) { for(efl::eina::iterator first ( ::eolian_class_inherits_get(klass)) , last; first != last; ++first) { EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << &*first << std::endl; Eolian_Class const* base = ::eolian_class_get_by_name(&*first); - if(classes.find(base) == classes.end()) - { - classes.insert(base); - separate_functions(base, EOLIAN_METHOD, true); - separate_functions(base, EOLIAN_PROPERTY, true); - recurse_inherits(base); - } + function(base); + recurse_inherits(base, function); } }; - recurse_inherits(klass); + + std::function save_functions + = [&] (Eolian_Class const* klass) + { + if(classes.find(klass) == classes.end()) + { + classes.insert(klass); + separate_functions(klass, EOLIAN_METHOD, true); + separate_functions(klass, EOLIAN_PROPERTY, true); + } + }; + recurse_inherits(klass, save_functions); EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "inherits were recursed"; @@ -241,20 +248,12 @@ int main(int argc, char** argv) if(is_evas(klass)) os << "#include \n"; - - std::function recurse_inherits_includes - = [&] (Eolian_Class const* klass) + + auto includes_fun = [&os] (Eolian_Class const* klass) { - for(efl::eina::iterator first ( ::eolian_class_inherits_get(klass)) - , last; first != last; ++first) - { - EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << &*first << std::endl; - Eolian_Class const* base = ::eolian_class_get_by_name(&*first); - os << "#include <" << eolian_class_file_get(base) << ".h>\n\n"; - recurse_inherits_includes(base); - } + os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n"; }; - recurse_inherits_includes(klass); + recurse_inherits(klass, includes_fun); os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n"; os << "}\n"; @@ -270,38 +269,18 @@ int main(int argc, char** argv) } EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "namespace"; + + os << "static v8::Persistent persistent_instance;\n"; + os << "static v8::Persistent constructor_from_eo;\n"; - os << "EAPI void register_" << lower_case_class_name - << "(v8::Handle global, v8::Isolate* isolate)\n"; + os << "EAPI v8::Local\nregister_" << lower_case_class_name << "_from_constructor\n" + << "(v8::Isolate* isolate, v8::Handle constructor)\n"; os << "{\n"; - os << " v8::Handle constructor = v8::FunctionTemplate::New\n"; - os << " (/*isolate,*/ efl::eo::js::constructor\n" - << " , efl::eo::js::constructor_data(isolate\n" - " , "; - EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "before print eo_class"; - - print_eo_class(klass, os); - - EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print eo_class"; - - for(auto function : constructor_functions) - { - os << "\n , & ::" - << eolian_function_full_c_name_get(function); - if(eolian_function_type_get(function) == EOLIAN_PROPERTY) - os << "_set"; - } - - os << "));\n"; - os << " constructor->SetClassName(v8::String::New/*FromUtf8(isolate,*/( \"" - << class_name - << "\"));\n"; - os << " v8::Handle instance = constructor->InstanceTemplate();\n"; + os << " v8::Local instance = constructor->InstanceTemplate();\n"; os << " instance->SetInternalFieldCount(1);\n"; - if(!normal_functions.empty()) - os << " v8::Handle prototype = constructor->PrototypeTemplate();\n"; + os << " v8::Handle prototype = constructor->PrototypeTemplate();\n"; for(auto function : normal_functions) { @@ -400,13 +379,88 @@ int main(int argc, char** argv) } } + auto generate_events = [&] (Eolian_Class const* klass) + { + for(efl::eina::iterator< ::Eolian_Event> first ( ::eolian_class_events_get(klass)) + , last; first != last; ++first) + { + + os << " {\n"; + os << " static efl::eo::js::event_information const event_information\n"; + os << " = {&constructor_from_eo, "; + os << eolian_event_c_name_get(&*first); + os << "};\n\n"; + os << " /* should include event " << ::eolian_event_name_get(&*first) << "*/" << std::endl; + os << " prototype->Set(v8::String::New(/*FromUtf8(isolate,*/ \"event_"; + std::string event_name (::eolian_event_name_get(&*first)); + std::replace(event_name.begin(), event_name.end(), ',', '_'); + os << event_name << "\")\n , v8::FunctionTemplate::New(/*isolate,*/ &efl::eo::js::event_call\n" + << " , v8::External::New(const_cast" + << "(&event_information)) ));\n"; + os << " }\n\n"; + + } + }; + generate_events(klass); + recurse_inherits(klass, generate_events); + + os << " static_cast(prototype); /* avoid warnings */\n"; + os << " static_cast(isolate); /* avoid warnings */\n"; + os << " return instance;\n"; + os << "}\n\n"; + + os << "EAPI void register_" << lower_case_class_name + << "(v8::Handle global, v8::Isolate* isolate)\n"; + os << "{\n"; + os << " v8::Handle constructor = v8::FunctionTemplate::New\n"; + os << " (/*isolate,*/ efl::eo::js::constructor\n" + << " , efl::eo::js::constructor_data(isolate\n" + " , "; + + EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "before print eo_class"; + + print_eo_class(klass, os); + + EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "print eo_class"; + + for(auto function : constructor_functions) + { + os << "\n , & ::" + << eolian_function_full_c_name_get(function); + if(eolian_function_type_get(function) == EOLIAN_PROPERTY) + os << "_set"; + } + + os << "));\n"; + + os << " register_" << lower_case_class_name << "_from_constructor(isolate, constructor);\n"; + + os << " constructor->SetClassName(v8::String::New/*FromUtf8(isolate,*/( \"" + << class_name + << "\"));\n"; + os << " global->Set(v8::String::New/*FromUtf8(isolate,*/( \"" << class_name << "\")" << ", constructor->GetFunction());\n"; - os << "}\n"; + os << " {\n"; + os << " v8::Handle constructor = v8::FunctionTemplate::New\n"; + os << " (/*isolate,*/ &efl::eo::js::construct_from_eo);\n"; + os << " constructor->SetClassName(v8::String::New/*FromUtf8(isolate,*/( \"" + << class_name + << "\"));\n"; + os << " v8::Local instance = " + << "register_" << lower_case_class_name << "_from_constructor(isolate, constructor);\n"; + os << " persistent_instance = v8::Persistent::New(instance);\n"; + os << " constructor_from_eo = v8::Persistent::New(constructor->GetFunction());\n"; + os << " }\n"; + + os << "}\n\n"; + for(std::size_t i = 0, j = namespace_size(klass); i != j; ++i) os << "}"; os << "\n"; + + } diff --git a/src/bindings/eo_js/Eo_Js.hh b/src/bindings/eo_js/Eo_Js.hh index e8167d7d2c..242c5fed1c 100644 --- a/src/bindings/eo_js/Eo_Js.hh +++ b/src/bindings/eo_js/Eo_Js.hh @@ -4,6 +4,8 @@ #include #include #include +#include +#include #endif diff --git a/src/bindings/eo_js/eo_js_call_function.hh b/src/bindings/eo_js/eo_js_call_function.hh index ea43e358a8..0f78582251 100644 --- a/src/bindings/eo_js/eo_js_call_function.hh +++ b/src/bindings/eo_js/eo_js_call_function.hh @@ -361,7 +361,7 @@ v8::Handle call_function_data(v8::Isolate* isolate, F f) } #else template -v8::Handle call_function_data(v8::Isolate* isolate, F f) +v8::Handle call_function_data(v8::Isolate* /*isolate*/, F f) { return v8::External::New (new std::function(v8::Arguments const&)> diff --git a/src/bindings/eo_js/eo_js_construct_from_eo.hh b/src/bindings/eo_js/eo_js_construct_from_eo.hh new file mode 100644 index 0000000000..b7c60d38b6 --- /dev/null +++ b/src/bindings/eo_js/eo_js_construct_from_eo.hh @@ -0,0 +1,54 @@ +#ifndef EFL_EO_JS_CONSTRUCT_FROM_EO_HH +#define EFL_EO_JS_CONSTRUCT_FROM_EO_HH + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace efl { namespace eo { namespace js { + +#if 0 +#else +inline v8::Handle construct_from_eo(v8::Arguments const& args) +{ + std::cout << "construct_from_eo " << __LINE__ << std::endl; + if(args.IsConstructCall()) + { + std::cout << "construct_from_eo " << __LINE__ << std::endl; + args.This()->SetInternalField(0, args[0]); + std::cout << "construct_from_eo " << __LINE__ << std::endl; + return v8::Handle(); + } + else + { + std::cout << "construct_from_eo " << __LINE__ << std::endl; + std::size_t argc = args.Length(); + std::cout << "construct_from_eo " << __LINE__ << std::endl; + std::vector > argv (argc ? argc : 1 ); + std::cout << "construct_from_eo " << __LINE__ << std::endl; + for(int i = 0; i != args.Length(); ++i) + argv[i] = args[i]; + std::cout << "construct_from_eo " << __LINE__ << std::endl; + args.Callee()->NewInstance(argc, &argv[0]); + std::cout << "construct_from_eo " << __LINE__ << std::endl; + return v8::Handle(); + } + std::cout << "construct_from_eo " << __LINE__ << std::endl; +} +#endif + +} } } + +#endif diff --git a/src/bindings/eo_js/eo_js_constructor.hh b/src/bindings/eo_js/eo_js_constructor.hh index a522be1e3a..e404cbf2da 100644 --- a/src/bindings/eo_js/eo_js_constructor.hh +++ b/src/bindings/eo_js/eo_js_constructor.hh @@ -49,7 +49,7 @@ inline v8::Handle constructor(v8::Arguments const& args) void* data = v8::External::Cast(*args.Data())->Value(); std::function(v8::Arguments const&)>* f = static_cast(v8::Arguments const&)>*>(data); - (*f)(args); + return (*f)(args); } else { @@ -197,7 +197,7 @@ v8::Handle constructor_data(v8::Isolate* isolate, Eo_Class const* kla } #else template -v8::Handle constructor_data(v8::Isolate* isolate, Eo_Class const* klass, F... f) +v8::Handle constructor_data(v8::Isolate* /*isolate*/, Eo_Class const* klass, F... f) { fprintf(stderr, "function called %s\n", __func__); fflush(stderr); std::cerr << "function called " << __func__ << std::endl; 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..20dfe3f38b --- /dev/null +++ b/src/bindings/eo_js/eo_js_event.hh @@ -0,0 +1,94 @@ +#ifndef EFL_EO_JS_EVENT_HH +#define EFL_EO_JS_EVENT_HH + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace efl { namespace eo { namespace js { + +struct event_information +{ + v8::Handle* constructor; + Eo_Event_Description const* event; +}; + +struct event_callback_information +{ + event_information* event_info; + v8::Persistent function; +}; + +inline Eina_Bool event_callback(void* data, Eo* obj, Eo_Event_Description const* + , void* /*event_info*/) +{ + std::cout << "event_callback " << __LINE__ << std::endl; + event_callback_information* event = static_cast(data); + std::cout << "event_callback " << __LINE__ << std::endl; + v8::Handle a[] = {v8::External::New(/*isolate,*/ obj)}; + std::cout << "event_callback " << __LINE__ << std::endl; + // v8::Local f = (*event->event_info->constructor)->GetFunction(); + std::cout << "event_callback " << __LINE__ << std::endl; + v8::Local self = (*event->event_info->constructor)->NewInstance(1, a); + std::cout << "event_callback " << __LINE__ << std::endl; + + v8::Handle call_args[] = {self}; + std::cout << "event_callback " << __LINE__ << std::endl; + event->function->Call(v8::Context::GetCurrent()->Global(), 1, call_args); + std::cout << "event_callback " << __LINE__ << std::endl; + + return EO_CALLBACK_CONTINUE; +} + +#if 0 + +#else +inline v8::Handle event_call(v8::Arguments const& args) +{ + std::cout << "event_call" << std::endl; + if(args.Length() >= 1) + { + std::cout << "has one argument" << std::endl; + v8::Local arg1 = args[0]; + if(arg1->IsFunction()) + { + std::cout << "is function" << std::endl; + v8::Local data = args.Data(); + event_information* event = + static_cast + (v8::External::Cast(*data)->Value()); + + v8::Local self = args.This(); + v8::Local external = self->GetInternalField(0); + Eo* eo = static_cast(v8::External::Cast(*external)->Value()); + + event_callback_information* i = new event_callback_information + {event, v8::Persistent::New(v8::Handle + (v8::Function::Cast(*arg1->ToObject())))}; + + eo_do(eo, eo_event_callback_priority_add + (event->event, EO_CALLBACK_PRIORITY_DEFAULT, &event_callback, i)); + } + } + else + { + } + return v8::Handle(); +} +#endif + +} } } + +#endif diff --git a/src/bindings/eo_js/eo_js_get_value.hh b/src/bindings/eo_js/eo_js_get_value.hh index 83fb825e55..8ef9cdeecc 100644 --- a/src/bindings/eo_js/eo_js_get_value.hh +++ b/src/bindings/eo_js/eo_js_get_value.hh @@ -83,7 +83,7 @@ inline const char* get_value_from_javascript inline Eo* get_value_from_javascript (v8::Local v - , v8::Isolate* isolate + , v8::Isolate* /*isolate*/ , value_tag) { if(v->IsNull()) @@ -144,7 +144,10 @@ inline int get_value_from_javascript , value_tag) { if(v->IsBoolean() || v->IsBooleanObject()) - return v->BooleanValue(); + { + std::cout << "Boolean value " << v->BooleanValue() << std::endl; + return v->BooleanValue(); + } else { #if 0 @@ -168,7 +171,10 @@ inline double get_value_from_javascript , typename std::enable_if::value>::type* = 0) { if(v->IsNumber()) - return v->NumberValue(); + { + std::cout << "Number value " << v->NumberValue() << std::endl; + return v->NumberValue(); + } else { #if 0