eolian-js: Developed C++ TMP method registration

This commit is contained in:
Felipe Magno de Almeida 2014-10-29 17:14:59 -02:00
parent eeb0215e23
commit b2457defec
6 changed files with 122 additions and 14 deletions

View File

@ -3,28 +3,80 @@
#include <v8.h>
#include <eina_tuple.hh>
#include <eina_function.hh>
#include <Eo.h>
#include <cstdlib>
#include <eo_js_get_value.hh>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <cassert>
#include <vector>
namespace efl { namespace eo { namespace js {
inline void call_function(v8::FunctionCallbackInfo<v8::Value> const& args)
{
if(args.IsConstructCall())
{
}
else
std::abort();
void* data = v8::External::Cast(*args.Data())->Value();
std::function<void(v8::FunctionCallbackInfo<v8::Value>const&)>*
f = static_cast<std::function<void(v8::FunctionCallbackInfo<v8::Value>const&)>*>(data);
(*f)(args);
}
template <typename T>
v8::Handle<v8::Value> call_function_data(v8::Isolate* isolate, T /*f*/)
template <typename F>
struct method_caller
{
return v8::External::New(isolate, new std::function<void()>());
template <typename U, std::size_t I>
static
typename std::tuple_element<I, typename eina::_mpl::function_params<U>::type>::type
get_value(v8::Local<v8::Value> v, v8::Isolate* isolate)
{
return js::get_value_from_javascript
(v, isolate
, js::value_tag<typename std::tuple_element
<I, typename eina::_mpl::function_params<U>::type>::type>());
}
template <std::size_t... I>
void aux(v8::FunctionCallbackInfo<v8::Value> const& args, eina::index_sequence<I...>) const
{
function(get_value<F, I>(args[I], args.GetIsolate())...);
}
void operator()(v8::FunctionCallbackInfo<v8::Value> const& args)
{
std::size_t const parameters
= std::tuple_size<typename eina::_mpl::function_params<F>::type>::value;
if(parameters <= args.Length())
{
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());
try
{
eo_do(eo, aux(args, eina::make_index_sequence<parameters>()));
}
catch(std::logic_error const&) {}
}
else
{
args.GetIsolate()->ThrowException
(v8::Exception::TypeError
(v8::String::NewFromUtf8(args.GetIsolate(), "Expected more arguments for this call")));
}
}
F function;
};
template <typename F>
v8::Handle<v8::Value> call_function_data(v8::Isolate* isolate, F f)
{
return v8::External::New
(isolate, new std::function<void(v8::FunctionCallbackInfo<v8::Value> const&)>
(method_caller<F>{f}));
}
} } }

View File

@ -66,8 +66,9 @@ struct constructor_caller
get_value(v8::Local<v8::Value> v, v8::Isolate* isolate)
{
return js::get_value_from_javascript
(v, js::value_tag<typename std::tuple_element<I, typename eina::_mpl::function_params<U>::type>::type>()
, isolate);
(v, isolate
, js::value_tag<typename std::tuple_element
<I, typename eina::_mpl::function_params<U>::type>::type>());
}
template <typename T, std::size_t... I>

View File

@ -4,6 +4,7 @@
#include <v8.h>
#include <type_traits>
#include <cstdlib>
namespace efl { namespace eo { namespace js {
@ -15,8 +16,9 @@ struct value_tag
template <typename T>
inline int get_value_from_javascript
(v8::Local<v8::Value> v, value_tag<T>
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, value_tag<T>
, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
{
if(v->IsInt32())
@ -33,8 +35,9 @@ inline int get_value_from_javascript
}
template <typename T>
inline double get_value_from_javascript
(v8::Local<v8::Value> v, value_tag<T>
(v8::Local<v8::Value> v
, v8::Isolate* isolate
, value_tag<T>
, typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
{
if(v->IsNumber())
@ -46,6 +49,13 @@ inline double get_value_from_javascript
throw std::logic_error("");
}
}
template <typename T>
inline T get_value_from_javascript
(v8::Local<v8::Value>, v8::Isolate*, value_tag<T>
, typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value>::type* = 0)
{
std::abort();
}
} } }

View File

@ -9,6 +9,16 @@ class Constructor_Method_Class (Eo.Base)
constructor2 {
params { @in double two; }
}
method1 {
params { @in int one; }
}
method2 {
params { @in int one; }
return: int;
}
method3 {
params { @in int one; @in double two; }
}
}
implements {
Eo.Base.constructor;

View File

@ -28,6 +28,18 @@ static const char script[] =
"}\n"
"print(\"teste\");\n"
"x = new Constructor_Method_Class(5, 10.0);"
"x.method1(2);\n"
"r = x.method2(3);\n"
"x.method3(3, 11.1);\n"
"try\n"
"{\n"
" x.method3(3);\n"
" assert(false, \"No exception thrown! this is wrong\");\n"
"}\n"
"catch (err)\n"
"{\n"
" print(\"Correctly exception thrown\");\n"
"}\n"
"try\n"
"{\n"
" y = new Constructor_Method_Class(5);\n"

View File

@ -48,4 +48,27 @@ static Eo * _constructor_method_class_eo_base_finalize(Eo *obj, Constructor_Meth
return obj;
}
void _constructor_method_class_method1(Eo *obj, Constructor_Method_Class_Data *pd, int one)
{
fprintf(stderr, "method1 one == %d\n", one);
fflush(stderr);
ck_assert(one == 2);
}
int _constructor_method_class_method2(Eo *obj, Constructor_Method_Class_Data *pd, int one)
{
fprintf(stderr, "method2 one == %d\n", one);
fflush(stderr);
ck_assert(one == 3);
return 5;
}
void _constructor_method_class_method3(Eo *obj, Constructor_Method_Class_Data *pd, int one, double two)
{
fprintf(stderr, "method3 one == %d two == %f\n", one, two);
fflush(stderr);
ck_assert(one == 3);
ck_assert(two == 11.1);
}
#include <constructor_method_class.eo.c>