diff options
author | Bill Welden <bwelden@imvu.com> | 2012-11-27 10:54:41 -0800 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:22:08 +0300 |
commit | 1b9928686e2a3bd0d6394d79cab7b110cf35990f (patch) | |
tree | 6cc2b40ce51a2c27f84a8e0d9c46a7a7e2b9f82c | |
parent | ab18c1107d8493b6a1ef0c19b5210a756cb4709c (diff) |
Automatic downcasting of function return values (first cut -- multiple inheritance still not supported).
-rwxr-xr-x | src/embind/embind.js | 139 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 8 |
2 files changed, 146 insertions, 1 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 504db37c..b50c7aca 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -493,15 +493,21 @@ function __embind_register_vector( }); } +// hang onto your hats, guys, we're going to try to make this one registration work for the class and all its +// derived classes function __embind_register_class( classType, pointerType, constPointerType, name, + getDynamicPointerType, destructor ) { name = Pointer_stringify(name); destructor = FUNCTION_TABLE[destructor]; + if (getDynamicPointerType) { + getDynamicPointerType = FUNCTION_TABLE[getDynamicPointerType]; + } var Handle = createNamedFunction(name, function(ptr) { var h = function() { @@ -562,6 +568,7 @@ function __embind_register_class( registerType(classType, name, { name: name, + pointerType: pointerType, constructor: constructor, Handle: Handle, fromWireType: function(ptr) { @@ -576,6 +583,19 @@ function __embind_register_class( registerType(pointerType, pointerName, { name: pointerName, fromWireType: function(ptr) { + var dynamicType = getDynamicPointerType && getDynamicPointerType(ptr); + if (dynamicType === null || dynamicType === pointerType) { + return new Handle(ptr); + } + try { + dynamicType = requireRegisteredType(dynamicType); + } catch (err) { + return new Handle(ptr); // I suppose we could work our way up the inheritance tree... + } + dynamicType = requireRegisteredType(dynamicType.pointerType); + return dynamicType.fromWireTypeStatic(ptr); + }, + fromWireTypeStatic: function(ptr) { return new Handle(ptr); }, toWireType: function(destructors, o) { @@ -586,6 +606,19 @@ function __embind_register_class( var constPointerName = name + ' const*'; registerType(constPointerType, constPointerName, { name: constPointerName, + fromWireType: function(ptr) { + var dynamicType = getDynamicPointerType && getDynamicPointerType(ptr); + if (dynamicType === null || dynamicType === pointerType) { + return new Handle(ptr); + } + try { + dynamicType = requireRegisteredType(dynamicType); + } catch (err) { + return new Handle(ptr); // I suppose we could work our way up the inheritance tree... + } + dynamicType = requireRegisteredType(dynamicType.pointerType); + return dynamicType.fromWireType(ptr); + }, toWireType: function(destructors, o) { return o.ptr; } @@ -594,6 +627,112 @@ function __embind_register_class( exposePublicSymbol(name, constructor); } +//function __embind_register_class( +// classType, +// pointerType, +// constPointerType, +// name, +// destructor +//) { +// name = Pointer_stringify(name); +// destructor = FUNCTION_TABLE[destructor]; +// +// var Handle = createNamedFunction(name, function(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() { +// 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) { +// destructor(this.ptr); +// } +// this.ptr = undefined; +// }; +// +// var constructor = createNamedFunction(name, function() { +// var body = constructor.body; +// return body.apply(this, arguments); +// }); +// constructor.prototype = Handle.prototype; +// +// registerType(classType, name, { +// name: name, +// constructor: constructor, +// Handle: Handle, +// fromWireType: function(ptr) { +// return new Handle(ptr); +// }, +// toWireType: function(destructors, o) { +// return o.ptr; +// } +// }); +// +// var pointerName = name + '*'; +// registerType(pointerType, pointerName, { +// name: pointerName, +// fromWireType: function(ptr) { +// // based on the fully downcast type of the pointer, +// +// return new Handle(ptr); // if me +// }, +// toWireType: function(destructors, o) { +// return o.ptr; +// } +// }); +// +// var constPointerName = name + ' const*'; +// registerType(constPointerType, constPointerName, { +// name: constPointerName, +// fromWireType: function(ptr) { +// return new Handle(ptr); +// }, +// toWireType: function(destructors, o) { +// return o.ptr; +// } +// }); +// +// exposePublicSymbol(name, constructor); +//} +// function __embind_register_class_constructor( classType, argCount, diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 08118259..3dc6b5e7 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -114,6 +114,7 @@ namespace emscripten { TYPEID pointerType, TYPEID constPointerType, const char* className, + GenericFunction getDynamicTypeInfo, GenericFunction destructor); void _embind_register_class_constructor( @@ -265,12 +266,16 @@ namespace emscripten { // FUNCTIONS //////////////////////////////////////////////////////////////////////////////// - template<typename FromType, typename ToType> ToType& performCast(FromType& from) { return *dynamic_cast<ToType*>(&from); }; + template<typename PointerType> + internal::TYPEID getDynamicPointerType(PointerType *p) { + return reinterpret_cast<internal::TYPEID>(&typeid(*p)); + }; + template<typename FromRawType, typename ToRawType> std::shared_ptr<ToRawType> performPointerCast(std::shared_ptr<FromRawType> from) { return std::shared_ptr<ToRawType>(from, dynamic_cast<ToRawType*>(from.get())); @@ -653,6 +658,7 @@ namespace emscripten { TypeID<AllowedRawPointer<ClassType>>::get(), TypeID<AllowedRawPointer<const ClassType>>::get(), name, + reinterpret_cast<GenericFunction>(&getDynamicPointerType<ClassType>), reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); } |