Exposing std::shared_ptr<T> to javascript.
This commit is contained in:
Родитель
a20c654c1f
Коммит
db4baa7a70
|
@ -354,6 +354,86 @@ function __embind_register_struct_field(
|
|||
};
|
||||
}
|
||||
|
||||
function __embind_register_shared_ptr(
|
||||
ptrType,
|
||||
classType,
|
||||
name,
|
||||
destructor,
|
||||
internalPtrGetter
|
||||
) {
|
||||
name = Pointer_stringify(name);
|
||||
classType = requireRegisteredType(classType, 'class');
|
||||
destructor = FUNCTION_TABLE[destructor];
|
||||
internalPtrGetter = FUNCTION_TABLE[internalPtrGetter];
|
||||
|
||||
var Handle = createNamedFunction(name, function(ptr) {
|
||||
this.count = {value: 1};
|
||||
this.ptr = ptr;
|
||||
|
||||
var args = new Array(1);
|
||||
args[0] = ptr;
|
||||
this.internalReference = classType.fromWireType(internalPtrGetter.apply(null, args));
|
||||
});
|
||||
|
||||
for(var prop in classType.Handle.prototype){
|
||||
if(prop === 'clone' || prop === 'move' === prop === 'delete'){
|
||||
continue;
|
||||
}
|
||||
|
||||
function createDuplicatedFunc(prop) {
|
||||
return function() {
|
||||
console.log(arguments);
|
||||
return classType.Handle.prototype[prop].apply(this.internalReference, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
Handle.prototype[prop] = createDuplicatedFunc(prop);
|
||||
}
|
||||
|
||||
Handle.prototype.clone = function() {
|
||||
if (!this.ptr) {
|
||||
throw new BindingError(classType.name + ' instance already deleted');
|
||||
}
|
||||
|
||||
var clone = Object.create(Handle.prototype);
|
||||
clone.count = this.count;
|
||||
clone.ptr = this.ptr;
|
||||
|
||||
clone.count.value += 1;
|
||||
return clone;
|
||||
};
|
||||
|
||||
Handle.prototype.move = function() {
|
||||
var rv = this.clone();
|
||||
this.delete();
|
||||
return rv;
|
||||
};
|
||||
|
||||
Handle.prototype['delete'] = function() {
|
||||
if (!this.ptr) {
|
||||
throw new BindingError(classType.name + ' instance already deleted');
|
||||
}
|
||||
|
||||
this.count.value -= 1;
|
||||
if (0 === this.count.value) {
|
||||
console.log(destructor);
|
||||
destructor(this.ptr);
|
||||
}
|
||||
this.ptr = undefined;
|
||||
}
|
||||
|
||||
typeRegistry[ptrType] = {
|
||||
name: name,
|
||||
Handle: Handle,
|
||||
fromWireType: function(ptr) {
|
||||
return new Handle(ptr);
|
||||
},
|
||||
toWireType: function(destructors, o) {
|
||||
return o.ptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function __embind_register_class(
|
||||
classType,
|
||||
name,
|
||||
|
@ -479,7 +559,7 @@ function __embind_register_class_method(
|
|||
for (var i = 0; i < argCount; ++i) {
|
||||
args[i + 2] = argTypes[i].toWireType(destructors, arguments[i]);
|
||||
}
|
||||
|
||||
|
||||
var rv = returnType.fromWireType(invoker.apply(null, args));
|
||||
runDestructors(destructors);
|
||||
return rv;
|
||||
|
|
|
@ -91,6 +91,13 @@ namespace emscripten {
|
|||
size_t memberPointerSize,
|
||||
void* memberPointer);
|
||||
|
||||
void _embind_register_shared_ptr(
|
||||
TYPEID ptrType,
|
||||
TYPEID classType,
|
||||
const char* ptrName,
|
||||
GenericFunction destructor,
|
||||
GenericFunction invoker);
|
||||
|
||||
void _embind_register_class(
|
||||
TYPEID classType,
|
||||
const char* className,
|
||||
|
@ -215,6 +222,11 @@ namespace emscripten {
|
|||
delete ptr;
|
||||
}
|
||||
|
||||
template<typename ClassType>
|
||||
ClassType* getSharedInternalPtr(std::shared_ptr<ClassType>* ptr) {
|
||||
return ptr->get();
|
||||
}
|
||||
|
||||
template<typename ClassType, typename ReturnType, typename... Args>
|
||||
struct MethodInvoker {
|
||||
typedef ReturnType (ClassType::*MemberPointer)(Args...);
|
||||
|
@ -424,6 +436,20 @@ namespace emscripten {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename ClassType>
|
||||
class shared_ptr_ {
|
||||
public:
|
||||
shared_ptr_(const char* name) {
|
||||
internal::registerStandardTypes();
|
||||
internal::_embind_register_shared_ptr(
|
||||
internal::TypeID<std::shared_ptr<ClassType>>::get(),
|
||||
internal::TypeID<ClassType>::get(),
|
||||
name,
|
||||
reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<std::shared_ptr<ClassType>>),
|
||||
reinterpret_cast<internal::GenericFunction>(&internal::getSharedInternalPtr<ClassType>));
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: support class definitions without constructors.
|
||||
// TODO: support external class constructors
|
||||
template<typename ClassType>
|
||||
|
|
Загрузка…
Ссылка в новой задаче