Removing Functor as a specific type; folding operator call into the class definition.
This commit is contained in:
Родитель
0d745fa116
Коммит
e237bfd79d
|
@ -430,101 +430,6 @@ function __embind_register_smart_ptr(
|
|||
});
|
||||
}
|
||||
|
||||
function __embind_register_function_ptr(
|
||||
name,
|
||||
functorType,
|
||||
returnType,
|
||||
argCount,
|
||||
argTypes,
|
||||
destructor,
|
||||
invoker
|
||||
) {
|
||||
name = Pointer_stringify(name);
|
||||
var humanName = 'functor::' + name;
|
||||
|
||||
returnType = requireRegisteredType(returnType);
|
||||
argTypes = requireArgumentTypes(argCount, argTypes, humanName);
|
||||
destructor = FUNCTION_TABLE[destructor];
|
||||
invoker = FUNCTION_TABLE[invoker];
|
||||
|
||||
var Handle = createNamedFunction(name, function(ptr) {
|
||||
this.count = {value: 1};
|
||||
this.functorPtr = ptr;
|
||||
});
|
||||
|
||||
Handle.prototype['delete'] = function() {
|
||||
if (!this.functorPtr) {
|
||||
throw new BindingError(functorType.name + ' instance already deleted');
|
||||
}
|
||||
|
||||
this.count.value -= 1;
|
||||
if(0 === this.count.value) {
|
||||
destructor(this.functorPtr);
|
||||
}
|
||||
this.functorPtr = undefined;
|
||||
};
|
||||
|
||||
function createFunctor(ptr) {
|
||||
var h = new Handle(ptr);
|
||||
|
||||
var invoke = function() {
|
||||
if(!this.functorPtr) {
|
||||
throw new BindingError('cannot call invoke functor ' + humanName + ' on deleted object');
|
||||
}
|
||||
|
||||
if (arguments.length !== argCount) {
|
||||
throw new BindingError('emscripten functor ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + argCount);
|
||||
}
|
||||
|
||||
var destructors = [];
|
||||
var args = new Array(argCount + 1);
|
||||
args[0] = this.functorPtr;
|
||||
|
||||
for (var i = 0; i < argCount; ++i) {
|
||||
args[i + 1] = argTypes[i].toWireType(destructors, arguments[i]);
|
||||
}
|
||||
|
||||
var rv = returnType.fromWireType(invoker.apply(null, args));
|
||||
runDestructors(destructors);
|
||||
return rv;
|
||||
}.bind(h);
|
||||
|
||||
invoke.handle = h;
|
||||
invoke['delete'] = function() {
|
||||
this.handle.delete();
|
||||
}.bind(invoke);
|
||||
invoke.clone = function() {
|
||||
if (!this.handle.functorPtr) {
|
||||
throw new BindingError(functorType.name + ' instance already deleted');
|
||||
}
|
||||
|
||||
var clone = createFunctor(this.handle.functorPtr);
|
||||
clone.handle.count = this.handle.count;
|
||||
clone.handle.ptr = this.handle.ptr;
|
||||
|
||||
clone.handle.count.value += 1;
|
||||
return clone;
|
||||
}.bind(invoke);
|
||||
invoke.move = function() {
|
||||
var rv = this.clone();
|
||||
this.delete();
|
||||
return rv;
|
||||
}.bind(invoke);
|
||||
|
||||
return invoke;
|
||||
}
|
||||
|
||||
registerType(functorType, name, {
|
||||
name: name,
|
||||
fromWireType: function(ptr) {
|
||||
return createFunctor(ptr);
|
||||
},
|
||||
toWireType: function(destructors, o) {
|
||||
return o.handle.functorPtr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function __embind_register_vector(
|
||||
vectorType,
|
||||
elementType,
|
||||
|
@ -579,10 +484,25 @@ function __embind_register_class(
|
|||
) {
|
||||
name = Pointer_stringify(name);
|
||||
destructor = FUNCTION_TABLE[destructor];
|
||||
|
||||
|
||||
var Handle = createNamedFunction(name, function(ptr) {
|
||||
this.count = {value: 1};
|
||||
this.ptr = ptr;
|
||||
var h = function() {
|
||||
if(h.operator_call !== undefined) {
|
||||
return h.operator_call.apply(h, arguments);
|
||||
} else {
|
||||
throw new BindingError(name + ' does not define call operator');
|
||||
}
|
||||
};
|
||||
|
||||
h.count = {value: 1};
|
||||
h.ptr = ptr;
|
||||
|
||||
for(var prop in Handle.prototype) {
|
||||
var dp = Object.getOwnPropertyDescriptor(Handle.prototype, prop);
|
||||
Object.defineProperty(h, prop, dp);
|
||||
}
|
||||
|
||||
return h;
|
||||
});
|
||||
|
||||
Handle.prototype.clone = function() {
|
||||
|
@ -618,7 +538,7 @@ function __embind_register_class(
|
|||
|
||||
var constructor = createNamedFunction(name, function() {
|
||||
var body = constructor.body;
|
||||
body.apply(this, arguments);
|
||||
return body.apply(this, arguments);
|
||||
});
|
||||
constructor.prototype = Handle.prototype;
|
||||
|
||||
|
@ -676,7 +596,8 @@ function __embind_register_class_constructor(
|
|||
|
||||
var ptr = constructor.apply(null, args);
|
||||
runDestructors(destructors);
|
||||
classType.Handle.call(this, ptr);
|
||||
|
||||
return classType.Handle.call(this, ptr);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -700,6 +621,7 @@ function __embind_register_class_method(
|
|||
memberFunction = copyMemberPointer(memberFunction, memberFunctionSize);
|
||||
|
||||
classType.Handle.prototype[methodName] = function() {
|
||||
|
||||
if (!this.ptr) {
|
||||
throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
|
||||
}
|
||||
|
@ -737,7 +659,42 @@ function __embind_register_class_classmethod(
|
|||
argTypes = requireArgumentTypes(argCount, argTypes, 'classmethod ' + humanName);
|
||||
invoker = FUNCTION_TABLE[invoker];
|
||||
|
||||
classType.constructor[methodName] = makeInvoker(humanName, returnType, argCount, argTypes, invoker, fn);}
|
||||
classType.constructor[methodName] = makeInvoker(humanName, returnType, argCount, argTypes, invoker, fn);
|
||||
}
|
||||
|
||||
function __embind_register_class_operator_call(
|
||||
classType,
|
||||
returnType,
|
||||
argCount,
|
||||
argTypes,
|
||||
invoker
|
||||
) {
|
||||
classType = requireRegisteredType(classType, 'class');
|
||||
returnType = requireRegisteredType(returnType, 'method ' + humanName + ' return value');
|
||||
argTypes = requireArgumentTypes(argCount, argTypes, 'method ' + humanName);
|
||||
invoker = FUNCTION_TABLE[invoker];
|
||||
var humanName = classType.name + '.' + 'operator_call';
|
||||
|
||||
classType.Handle.prototype.operator_call = function() {
|
||||
if (!this.ptr) {
|
||||
throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
|
||||
}
|
||||
if (arguments.length !== argCount) {
|
||||
throw new BindingError('emscripten binding method ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + argCount);
|
||||
}
|
||||
|
||||
var destructors = [];
|
||||
var args = new Array(argCount + 1);
|
||||
args[0] = this.ptr;
|
||||
for (var i = 0; i < argCount; ++i) {
|
||||
args[i + 1] = argTypes[i].toWireType(destructors, arguments[i]);
|
||||
}
|
||||
|
||||
var rv = returnType.fromWireType(invoker.apply(null, args));
|
||||
runDestructors(destructors);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
function __embind_register_class_field(
|
||||
classType,
|
||||
|
|
|
@ -100,15 +100,6 @@ namespace emscripten {
|
|||
GenericFunction destructor,
|
||||
GenericFunction getPointee);
|
||||
|
||||
void _embind_register_function_ptr(
|
||||
const char* name,
|
||||
TYPEID functorType,
|
||||
TYPEID returnType,
|
||||
unsigned argCount,
|
||||
TYPEID argTypes[],
|
||||
GenericFunction destructor,
|
||||
GenericFunction invoker);
|
||||
|
||||
void _embind_register_vector(
|
||||
TYPEID vectorType,
|
||||
TYPEID elementType,
|
||||
|
@ -160,6 +151,14 @@ namespace emscripten {
|
|||
GenericFunction invoker,
|
||||
GenericFunction method);
|
||||
|
||||
void _embind_register_class_operator_call(
|
||||
TYPEID classType,
|
||||
TYPEID returnType,
|
||||
unsigned argCount,
|
||||
TYPEID argTypes[],
|
||||
GenericFunction invoker
|
||||
);
|
||||
|
||||
void _embind_register_enum(
|
||||
TYPEID enumType,
|
||||
const char* name);
|
||||
|
@ -255,7 +254,7 @@ namespace emscripten {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ReturnType, typename... Args, typename... Policies>
|
||||
void function(const char* name, ReturnType (fn)(Args...)) {
|
||||
void function(const char* name, ReturnType (fn)(Args...), Policies...) {
|
||||
using namespace internal;
|
||||
|
||||
registerStandardTypes();
|
||||
|
@ -305,6 +304,15 @@ namespace emscripten {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename FunctorType, typename... Args>
|
||||
struct FunctorInvoker<FunctorType, void, Args...> {
|
||||
static void invoke(
|
||||
const FunctorType& ptr,
|
||||
typename internal::BindingType<Args>::WireType... args
|
||||
) {
|
||||
ptr(internal::BindingType<Args>::fromWireType(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ClassType, typename ReturnType, typename... Args>
|
||||
struct MethodInvoker {
|
||||
|
@ -567,26 +575,6 @@ namespace emscripten {
|
|||
reinterpret_cast<internal::GenericFunction>(&internal::get_pointee<PointerType>));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTION POINTERS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename ReturnType, typename... Args, typename... Policies>
|
||||
inline void register_function_ptr(const char* name) {
|
||||
typedef std::function<ReturnType(Args...)> FunctorType;
|
||||
|
||||
internal::registerStandardTypes();
|
||||
typename internal::WithPolicies<Policies...>::template ArgTypeList<Args...> args;
|
||||
internal::_embind_register_function_ptr(
|
||||
name,
|
||||
internal::TypeID<FunctorType>::get(),
|
||||
internal::TypeID<ReturnType>::get(),
|
||||
args.count,
|
||||
args.types,
|
||||
reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<FunctorType>),
|
||||
reinterpret_cast<internal::GenericFunction>(&internal::FunctorInvoker<FunctorType, ReturnType, Args...>::invoke)
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// VECTORS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -706,6 +694,20 @@ namespace emscripten {
|
|||
reinterpret_cast<GenericFunction>(classMethod));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename ReturnType, typename... Args, typename... Policies>
|
||||
class_& calloperator(Policies...) {
|
||||
using namespace internal;
|
||||
|
||||
typename WithPolicies<Policies...>::template ArgTypeList<Args...> args;
|
||||
_embind_register_class_operator_call(
|
||||
TypeID<ClassType>::get(),
|
||||
TypeID<ReturnType>::get(),
|
||||
args.count,
|
||||
args.types,
|
||||
reinterpret_cast<internal::GenericFunction>(&internal::FunctorInvoker<ClassType, ReturnType, Args...>::invoke));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Загрузка…
Ссылка в новой задаче