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(
|
function __embind_register_vector(
|
||||||
vectorType,
|
vectorType,
|
||||||
elementType,
|
elementType,
|
||||||
|
@ -579,10 +484,25 @@ function __embind_register_class(
|
||||||
) {
|
) {
|
||||||
name = Pointer_stringify(name);
|
name = Pointer_stringify(name);
|
||||||
destructor = FUNCTION_TABLE[destructor];
|
destructor = FUNCTION_TABLE[destructor];
|
||||||
|
|
||||||
var Handle = createNamedFunction(name, function(ptr) {
|
var Handle = createNamedFunction(name, function(ptr) {
|
||||||
this.count = {value: 1};
|
var h = function() {
|
||||||
this.ptr = ptr;
|
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() {
|
Handle.prototype.clone = function() {
|
||||||
|
@ -618,7 +538,7 @@ function __embind_register_class(
|
||||||
|
|
||||||
var constructor = createNamedFunction(name, function() {
|
var constructor = createNamedFunction(name, function() {
|
||||||
var body = constructor.body;
|
var body = constructor.body;
|
||||||
body.apply(this, arguments);
|
return body.apply(this, arguments);
|
||||||
});
|
});
|
||||||
constructor.prototype = Handle.prototype;
|
constructor.prototype = Handle.prototype;
|
||||||
|
|
||||||
|
@ -676,7 +596,8 @@ function __embind_register_class_constructor(
|
||||||
|
|
||||||
var ptr = constructor.apply(null, args);
|
var ptr = constructor.apply(null, args);
|
||||||
runDestructors(destructors);
|
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);
|
memberFunction = copyMemberPointer(memberFunction, memberFunctionSize);
|
||||||
|
|
||||||
classType.Handle.prototype[methodName] = function() {
|
classType.Handle.prototype[methodName] = function() {
|
||||||
|
|
||||||
if (!this.ptr) {
|
if (!this.ptr) {
|
||||||
throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
|
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);
|
argTypes = requireArgumentTypes(argCount, argTypes, 'classmethod ' + humanName);
|
||||||
invoker = FUNCTION_TABLE[invoker];
|
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(
|
function __embind_register_class_field(
|
||||||
classType,
|
classType,
|
||||||
|
|
|
@ -100,15 +100,6 @@ namespace emscripten {
|
||||||
GenericFunction destructor,
|
GenericFunction destructor,
|
||||||
GenericFunction getPointee);
|
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(
|
void _embind_register_vector(
|
||||||
TYPEID vectorType,
|
TYPEID vectorType,
|
||||||
TYPEID elementType,
|
TYPEID elementType,
|
||||||
|
@ -160,6 +151,14 @@ namespace emscripten {
|
||||||
GenericFunction invoker,
|
GenericFunction invoker,
|
||||||
GenericFunction method);
|
GenericFunction method);
|
||||||
|
|
||||||
|
void _embind_register_class_operator_call(
|
||||||
|
TYPEID classType,
|
||||||
|
TYPEID returnType,
|
||||||
|
unsigned argCount,
|
||||||
|
TYPEID argTypes[],
|
||||||
|
GenericFunction invoker
|
||||||
|
);
|
||||||
|
|
||||||
void _embind_register_enum(
|
void _embind_register_enum(
|
||||||
TYPEID enumType,
|
TYPEID enumType,
|
||||||
const char* name);
|
const char* name);
|
||||||
|
@ -255,7 +254,7 @@ namespace emscripten {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<typename ReturnType, typename... Args, typename... Policies>
|
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;
|
using namespace internal;
|
||||||
|
|
||||||
registerStandardTypes();
|
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>
|
template<typename ClassType, typename ReturnType, typename... Args>
|
||||||
struct MethodInvoker {
|
struct MethodInvoker {
|
||||||
|
@ -567,26 +575,6 @@ namespace emscripten {
|
||||||
reinterpret_cast<internal::GenericFunction>(&internal::get_pointee<PointerType>));
|
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
|
// VECTORS
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -706,6 +694,20 @@ namespace emscripten {
|
||||||
reinterpret_cast<GenericFunction>(classMethod));
|
reinterpret_cast<GenericFunction>(classMethod));
|
||||||
return *this;
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Загрузка…
Ссылка в новой задаче