summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Welden <bwelden@BWELDEN-T1600.corp.imvu.com>2012-11-10 13:01:34 -0800
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:21:57 +0300
commit338d59e81e5467df7021ad0854cee83b043c1204 (patch)
treee7c2ea46108fecaaef1077f89c6315049bc900ec
parent61b2ff66ffe1aba9550c828d5df9ecc0d3af8f7b (diff)
More files for upcast/downcast commit.
-rwxr-xr-x[-rw-r--r--]src/embind/embind.js61
-rwxr-xr-x[-rw-r--r--]system/include/emscripten/bind.h74
2 files changed, 123 insertions, 12 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 6a59f11d..f491c1dd 100644..100755
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -413,6 +413,7 @@ function __embind_register_smart_ptr(
registerType(pointerType, name, {
name: name,
+ Handle: Handle,
fromWireType: function(ptr) {
if (!getPointee(ptr)) {
destructor(ptr);
@@ -541,7 +542,7 @@ function __embind_register_class(
return body.apply(this, arguments);
});
constructor.prototype = Handle.prototype;
-
+
registerType(classType, name, {
name: name,
constructor: constructor,
@@ -643,6 +644,64 @@ function __embind_register_class_method(
};
}
+function __embind_register_cast_method(
+ classType,
+ methodName,
+ returnType,
+ invoker
+) {
+ classType = requireRegisteredType(classType, 'class');
+ methodName = Pointer_stringify(methodName);
+ var humanName = classType.name + '.' + methodName;
+
+ returnType = requireRegisteredType(returnType, 'method ' + humanName + ' return value');
+ invoker = FUNCTION_TABLE[invoker];
+
+ classType.Handle.prototype[methodName] = function() {
+ if (!this.ptr) {
+ throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
+ }
+ if (arguments.length !== 0) {
+ throw new BindingError('emscripten binding method ' + humanName + ' called with arguments, none expected');
+ }
+
+ var args = new Array(1);
+ args[0] = this.ptr;
+ var rv = returnType.fromWireType(invoker.apply(null, args)); // in case ptr needs to be adjusted for multiple inheritance
+ return rv;
+ };
+}
+
+function __embind_register_pointer_cast_method(
+ classType,
+ methodName,
+ returnType,
+ invoker
+) {
+ classType = requireRegisteredType(classType, 'class');
+ methodName = Pointer_stringify(methodName);
+ var humanName = classType.name + '.' + methodName;
+
+ returnType = requireRegisteredType(returnType, 'method ' + humanName + ' return value');
+ invoker = FUNCTION_TABLE[invoker];
+
+ classType.Handle.prototype[methodName] = function() {
+ if (!this.ptr) {
+ throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
+ }
+ if (arguments.length !== 0) {
+ throw new BindingError('emscripten binding method ' + humanName + ' called with arguments, none expected');
+ }
+ var args = new Array(2);
+ var newPtr = _malloc(8);
+ args[0] = newPtr;
+ args[1] = this.smartPointer;
+ invoker.apply(null,args);
+ var rv = returnType.fromWireType(newPtr); // in case ptr needs to be adjusted for multiple inheritance
+ return rv;
+ };
+}
+
function __embind_register_class_classmethod(
classType,
methodName,
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index e20a5e68..ec3db2d2 100644..100755
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -133,6 +133,18 @@ namespace emscripten {
size_t memberFunctionSize,
void* memberFunction);
+ void _embind_register_cast_method(
+ TYPEID classType,
+ const char* methodName,
+ TYPEID returnType,
+ GenericFunction invoker);
+
+ void _embind_register_pointer_cast_method(
+ TYPEID classType,
+ const char* methodName,
+ TYPEID returnType,
+ GenericFunction invoker);
+
void _embind_register_class_field(
TYPEID classType,
const char* fieldName,
@@ -253,6 +265,17 @@ namespace emscripten {
// FUNCTIONS
////////////////////////////////////////////////////////////////////////////////
+
+ template<typename FromType, typename ToType>
+ ToType& performCast(FromType& from) {
+ return *dynamic_cast<ToType*>(&from);
+ };
+
+ 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()));
+ };
+
template<typename ReturnType, typename... Args, typename... Policies>
void function(const char* name, ReturnType (fn)(Args...), Policies...) {
using namespace internal;
@@ -563,17 +586,35 @@ namespace emscripten {
////////////////////////////////////////////////////////////////////////////////
template<typename PointerType>
- inline void register_smart_ptr(const char* name) {
- typedef typename PointerType::element_type PointeeType;
+ class register_smart_ptr {
+ public:
+ register_smart_ptr(const char* name) {
+ using namespace internal;
+ typedef typename PointerType::element_type PointeeType;
- internal::registerStandardTypes();
- internal::_embind_register_smart_ptr(
- internal::TypeID<PointerType>::get(),
- internal::TypeID<PointeeType>::get(),
- name,
- reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<PointerType>),
- reinterpret_cast<internal::GenericFunction>(&internal::get_pointee<PointerType>));
- }
+ registerStandardTypes();
+ _embind_register_smart_ptr(
+ TypeID<PointerType>::get(),
+ TypeID<PointeeType>::get(),
+ name,
+ reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>),
+ reinterpret_cast<GenericFunction>(&get_pointee<PointerType>));
+
+ }
+
+ template<typename ReturnType>
+ register_smart_ptr& cast(const char* methodName) {
+ using namespace internal;
+ typedef typename ReturnType::element_type ReturnPointeeType;
+ typedef typename PointerType::element_type PointeeType;
+ _embind_register_pointer_cast_method(
+ TypeID<PointerType>::get(),
+ methodName,
+ TypeID<ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&performPointerCast<PointeeType,ReturnPointeeType>));
+ return *this;
+ }
+ };
////////////////////////////////////////////////////////////////////////////////
// VECTORS
@@ -599,7 +640,6 @@ namespace emscripten {
////////////////////////////////////////////////////////////////////////////////
// CLASSES
////////////////////////////////////////////////////////////////////////////////
-
// TODO: support class definitions without constructors.
// TODO: support external class constructors
template<typename ClassType>
@@ -708,6 +748,18 @@ namespace emscripten {
reinterpret_cast<internal::GenericFunction>(&internal::FunctorInvoker<ClassType, ReturnType, Args...>::invoke));
return *this;
}
+
+ template<typename ReturnType>
+ class_& cast(const char* methodName) {
+ using namespace internal;
+
+ _embind_register_cast_method(
+ TypeID<ClassType>::get(),
+ methodName,
+ TypeID<ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&performCast<ClassType,ReturnType>));
+ return *this;
+ }
};
////////////////////////////////////////////////////////////////////////////////