[eolian-js] Added events to JS

This commit is contained in:
Felipe Magno de Almeida 2014-12-10 20:09:12 -02:00
parent b2263d470d
commit fd8c21d21a
8 changed files with 269 additions and 57 deletions

View File

@ -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

View File

@ -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<void(Eolian_Class const*)> recurse_inherits
= [&] (Eolian_Class const* klass)
std::function<void(Eolian_Class const*, std::function<void(Eolian_Class const*)>)>
recurse_inherits
= [&] (Eolian_Class const* klass, std::function<void(Eolian_Class const*)> function)
{
for(efl::eina::iterator<const char> 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<void(Eolian_Class const*)> 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 <Evas.h>\n";
std::function<void(Eolian_Class const*)> recurse_inherits_includes
= [&] (Eolian_Class const* klass)
auto includes_fun = [&os] (Eolian_Class const* klass)
{
for(efl::eina::iterator<const char> 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<v8::ObjectTemplate> persistent_instance;\n";
os << "static v8::Persistent<v8::Function> constructor_from_eo;\n";
os << "EAPI void register_" << lower_case_class_name
<< "(v8::Handle<v8::Object> global, v8::Isolate* isolate)\n";
os << "EAPI v8::Local<v8::ObjectTemplate>\nregister_" << lower_case_class_name << "_from_constructor\n"
<< "(v8::Isolate* isolate, v8::Handle<v8::FunctionTemplate> constructor)\n";
os << "{\n";
os << " v8::Handle<v8::FunctionTemplate> 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<v8::ObjectTemplate> instance = constructor->InstanceTemplate();\n";
os << " v8::Local<v8::ObjectTemplate> instance = constructor->InstanceTemplate();\n";
os << " instance->SetInternalFieldCount(1);\n";
if(!normal_functions.empty())
os << " v8::Handle<v8::ObjectTemplate> prototype = constructor->PrototypeTemplate();\n";
os << " v8::Handle<v8::ObjectTemplate> 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<efl::eo::js::event_information*>"
<< "(&event_information)) ));\n";
os << " }\n\n";
}
};
generate_events(klass);
recurse_inherits(klass, generate_events);
os << " static_cast<void>(prototype); /* avoid warnings */\n";
os << " static_cast<void>(isolate); /* avoid warnings */\n";
os << " return instance;\n";
os << "}\n\n";
os << "EAPI void register_" << lower_case_class_name
<< "(v8::Handle<v8::Object> global, v8::Isolate* isolate)\n";
os << "{\n";
os << " v8::Handle<v8::FunctionTemplate> 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<v8::FunctionTemplate> 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<v8::ObjectTemplate> instance = "
<< "register_" << lower_case_class_name << "_from_constructor(isolate, constructor);\n";
os << " persistent_instance = v8::Persistent<v8::ObjectTemplate>::New(instance);\n";
os << " constructor_from_eo = v8::Persistent<v8::Function>::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";
}

View File

@ -4,6 +4,8 @@
#include <eo_js_direction.hh>
#include <eo_js_constructor.hh>
#include <eo_js_call_function.hh>
#include <eo_js_event.hh>
#include <eo_js_construct_from_eo.hh>
#endif

View File

@ -361,7 +361,7 @@ v8::Handle<v8::Value> call_function_data(v8::Isolate* isolate, F f)
}
#else
template <typename In, typename Out, typename Ownership, typename F>
v8::Handle<v8::Value> call_function_data(v8::Isolate* isolate, F f)
v8::Handle<v8::Value> call_function_data(v8::Isolate* /*isolate*/, F f)
{
return v8::External::New
(new std::function<v8::Handle<v8::Value>(v8::Arguments const&)>

View File

@ -0,0 +1,54 @@
#ifndef EFL_EO_JS_CONSTRUCT_FROM_EO_HH
#define EFL_EO_JS_CONSTRUCT_FROM_EO_HH
#include <v8.h>
#include <eina_tuple.hh>
#include <eina_tuple_c.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <eo_js_get_value.hh>
#include <eo_js_get_value_from_c.hh>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
#if 0
#else
inline v8::Handle<v8::Value> 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<v8::Value>();
}
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<v8::Local<v8::Value> > 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<v8::Value>();
}
std::cout << "construct_from_eo " << __LINE__ << std::endl;
}
#endif
} } }
#endif

View File

@ -49,7 +49,7 @@ inline v8::Handle<v8::Value> constructor(v8::Arguments const& args)
void* data = v8::External::Cast(*args.Data())->Value();
std::function<v8::Handle<v8::Value>(v8::Arguments const&)>*
f = static_cast<std::function<v8::Handle<v8::Value>(v8::Arguments const&)>*>(data);
(*f)(args);
return (*f)(args);
}
else
{
@ -197,7 +197,7 @@ v8::Handle<v8::Value> constructor_data(v8::Isolate* isolate, Eo_Class const* kla
}
#else
template <typename... F>
v8::Handle<v8::Value> constructor_data(v8::Isolate* isolate, Eo_Class const* klass, F... f)
v8::Handle<v8::Value> 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;

View File

@ -0,0 +1,94 @@
#ifndef EFL_EO_JS_EVENT_HH
#define EFL_EO_JS_EVENT_HH
#include <v8.h>
#include <eina_tuple.hh>
#include <eina_tuple_c.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <eo_js_get_value.hh>
#include <eo_js_get_value_from_c.hh>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
struct event_information
{
v8::Handle<v8::Function>* constructor;
Eo_Event_Description const* event;
};
struct event_callback_information
{
event_information* event_info;
v8::Persistent<v8::Function> 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<event_callback_information*>(data);
std::cout << "event_callback " << __LINE__ << std::endl;
v8::Handle<v8::Value> a[] = {v8::External::New(/*isolate,*/ obj)};
std::cout << "event_callback " << __LINE__ << std::endl;
// v8::Local<v8::Function> f = (*event->event_info->constructor)->GetFunction();
std::cout << "event_callback " << __LINE__ << std::endl;
v8::Local<v8::Object> self = (*event->event_info->constructor)->NewInstance(1, a);
std::cout << "event_callback " << __LINE__ << std::endl;
v8::Handle<v8::Value> 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<v8::Value> 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<v8::Value> arg1 = args[0];
if(arg1->IsFunction())
{
std::cout << "is function" << std::endl;
v8::Local<v8::Value> data = args.Data();
event_information* event =
static_cast<event_information*>
(v8::External::Cast(*data)->Value());
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());
event_callback_information* i = new event_callback_information
{event, v8::Persistent<v8::Function>::New(v8::Handle<v8::Function>
(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<v8::Value>();
}
#endif
} } }
#endif

View File

@ -83,7 +83,7 @@ inline const char* get_value_from_javascript
inline Eo* get_value_from_javascript
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, v8::Isolate* /*isolate*/
, value_tag<Eo*>)
{
if(v->IsNull())
@ -144,7 +144,10 @@ inline int get_value_from_javascript
, value_tag<Eina_Bool>)
{
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<std::is_floating_point<T>::value>::type* = 0)
{
if(v->IsNumber())
return v->NumberValue();
{
std::cout << "Number value " << v->NumberValue() << std::endl;
return v->NumberValue();
}
else
{
#if 0