-
Notifications
You must be signed in to change notification settings - Fork 120
/
ValueObj.h
95 lines (66 loc) · 2.82 KB
/
ValueObj.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// This file is part of nbind, copyright (C) 2014-2015 BusFaster Ltd.
// Released under the MIT license, see LICENSE.
#pragma once
namespace nbind {
template <typename ArgType>
inline WireType BindingType<ArgType *>::toWireType(ArgType *arg) {
if(arg == nullptr) return(Nan::Undefined());
#ifndef DUPLICATE_POINTERS
auto ref = BindWrapper<ArgType>::findInstance(arg);
if(!ref->IsEmpty()) {
return(Nan::New<v8::Object>(*ref));
}
#endif // DUPLICATE_POINTERS
unsigned int constructorNum = BindClass<ArgType>::getInstance().wrapperConstructorNum;
v8::Local<v8::Function> constructor = Overloader::getDef(constructorNum).constructorJS->GetFunction();
const unsigned int argc = 1;
v8::Local<v8::Value> argv = Nan::New<v8::External>(arg);
return(constructor->NewInstance(argc, &argv));
}
template <> struct BindingType<v8::Local<v8::Function>> {
static inline WireType toWireType(v8::Local<v8::Function> arg) {
return(arg);
}
};
// Call the toJS method of a returned C++ object, to convert it into a JavaScript object.
// This is used when a C++ function is called from JavaScript.
// A functor capable of calling the correct JavaScript constructor is passed to toJS,
// which must call the functor with arguments in the correct order.
// The functor calls the JavaScript constructor and writes a pointer to the resulting object
// directly into a local handle called "output" which is returned to JavaScript.
template <typename ArgType>
inline WireType BindingType<ArgType>::toWireType(ArgType arg) {
v8::Local<v8::Value> output = Nan::Undefined();
cbFunction *jsConstructor = BindClass<ArgType>::getInstance().getValueConstructorJS();
if(jsConstructor != nullptr) {
cbOutput construct(*jsConstructor, &output);
arg.toJS(construct);
} else {
throw(std::runtime_error("Value type JavaScript class is missing or not registered"));
}
return(output);
}
template <typename ArgType>
ArgType BindingType<ArgType>::fromWireType(WireType arg) noexcept(false) {
Nan::HandleScope();
auto target = arg->ToObject();
auto fromJS = target->Get(Nan::New<v8::String>("fromJS").ToLocalChecked());
if(!fromJS->IsFunction()) throw(std::runtime_error("Type mismatch"));
TemplatedArgStorage<ArgType> storage(
BindClass<ArgType>::getInstance().valueConstructorNum
);
// TODO: cache this for a speedup.
cbFunction converter(v8::Local<v8::Function>::Cast(fromJS));
v8::Local<v8::FunctionTemplate> constructorTemplate = Nan::New<v8::FunctionTemplate>(
Overloader::createValue,
// Data specifically for createValue function.
Nan::New<v8::External>(&storage)
);
// TODO: cache this for a speedup.
auto constructor = constructorTemplate->GetFunction();
converter.callMethod<void>(target, constructor);
const char *message = Status::getError();
if(message) throw(std::runtime_error(message));
return(storage.getBound());
}
} // namespace