diff options
author | mey <mey@imvu.com> | 2012-11-30 14:56:58 -0800 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:22:15 +0300 |
commit | 15603bbafc0aa68f9d8d843e083b89bfc566533d (patch) | |
tree | 45ed85654607be98395485b164f28af73362c330 | |
parent | 026a4d49e496339c0f31b79ca3b399c53dac5f7f (diff) |
Switching vector class_ instead of bound as an explicit type.
-rwxr-xr-x | src/embind/embind.js | 69 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 121 | ||||
-rwxr-xr-x | system/include/emscripten/wire.h | 27 |
3 files changed, 179 insertions, 38 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index b50c7aca..fa364900 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -495,6 +495,7 @@ 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, @@ -882,9 +883,10 @@ function __embind_register_class_operator_call( invoker ) { classType = requireRegisteredType(classType, 'class'); + var humanName = classType.name + '.' + 'operator_call'; 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) { @@ -907,6 +909,71 @@ function __embind_register_class_operator_call( }; } +function __embind_register_class_operator_array_get( + classType, + elementType, + indexType, + invoker +) { + classType = requireRegisteredType(classType, 'class'); + indexType = requireRegisteredType(indexType, 'array access index ' + classType.name); + elementType = requireRegisteredType(elementType, 'array access element' + classType.name); + invoker = FUNCTION_TABLE[invoker]; + var humanName = classType.name + '.' + 'operator_array_get'; + + classType.Handle.prototype.array_get = function() { + if (!this.ptr) { + throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object'); + } + + if (arguments.length !== 1) { + throw new BindingError('emscripten binding method ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + 1); + } + + var destructors = []; + var args = new Array(2); + args[0] = this.ptr; + args[1] = indexType.toWireType(destructors, arguments[0]); + + var rv = elementType.fromWireType(invoker.apply(null, args)); + runDestructors(destructors); + return rv; + }; +} + +function __embind_register_class_operator_array_set( + classType, + elementType, + indexType, + invoker +) { + classType = requireRegisteredType(classType, 'class'); + indexType = requireRegisteredType(indexType, 'array access index ' + classType.name); + elementType = requireRegisteredType(elementType, 'vector ' + classType.name); + invoker = FUNCTION_TABLE[invoker]; + var humanName = classType.name + '.' + 'operator_array_get'; + + classType.Handle.prototype.array_set = function() { + if (!this.ptr) { + throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object'); + } + + if (arguments.length !== 2) { + throw new BindingError('emscripten binding method ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + 2); + } + + var destructors = []; + var args = new Array(2); + args[0] = this.ptr; + args[1] = indexType.toWireType(destructors, arguments[0]); + args[2] = elementType.toWireType(destructors, arguments[1]); + + var rv = elementType.fromWireType(invoker.apply(null, args)); + runDestructors(destructors); + return rv; + }; +} + function __embind_register_class_field( classType, fieldName, diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 3dc6b5e7..6b8b6f10 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -165,8 +165,19 @@ namespace emscripten { TYPEID classType, unsigned argCount, TYPEID argTypes[], - GenericFunction invoker - ); + GenericFunction invoker); + + void _embind_register_class_operator_array_get( + TYPEID classType, + TYPEID elementType, + TYPEID indexType, + GenericFunction invoker); + + void _embind_register_class_operator_array_set( + TYPEID classType, + TYPEID elementType, + TYPEID indexType, + GenericFunction invoker); void _embind_register_enum( TYPEID enumType, @@ -341,6 +352,30 @@ namespace emscripten { } }; + template<typename ClassType, typename ElementType> + struct ArrayAccessGetInvoker { + static typename internal::BindingType<ElementType>::WireType invoke( + ClassType* ptr, + size_t index, + typename internal::BindingType<ElementType> + ) { + return internal::BindingType<ElementType>::toWireType( + (*ptr)[index] + ); + } + }; + + template<typename ClassType, typename ElementType> + struct ArrayAccessSetInvoker { + static void invoke( + ClassType* ptr, + size_t index, + typename internal::BindingType<ElementType>::WireType item + ) { + (*ptr)[index] = internal::BindingType<ElementType>::fromWireType(item); + } + }; + template<typename ClassType, typename ReturnType, typename... Args> struct MethodInvoker { typedef ReturnType (ClassType::*MemberPointer)(Args...); @@ -621,27 +656,6 @@ namespace emscripten { }; //////////////////////////////////////////////////////////////////////////////// - // VECTORS - //////////////////////////////////////////////////////////////////////////////// - - template<typename VectorType> - inline void register_vector(const char* name) { - typedef typename VectorType::value_type ElementType; - - internal::registerStandardTypes(); - internal::_embind_register_vector( - internal::TypeID<VectorType>::get(), - internal::TypeID<ElementType>::get(), - name, - reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<VectorType>), - reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<VectorType>), - reinterpret_cast<internal::GenericFunction>(&internal::Vector<VectorType>::length), - reinterpret_cast<internal::GenericFunction>(&internal::Vector<VectorType>::getAt), - reinterpret_cast<internal::GenericFunction>(&internal::Vector<VectorType>::push_back) - ); - } - - //////////////////////////////////////////////////////////////////////////////// // CLASSES //////////////////////////////////////////////////////////////////////////////// // TODO: support class definitions without constructors. @@ -750,6 +764,44 @@ namespace emscripten { return *this; } + + /* + * void _embind_register_class_operator_array_get( + TYPEID classType, + TYPEID elementType, + GenericFunction invoker); + + void _embind_register_class_operator_array_set( + TYPEID classType, + TYPEID elementType, + GenericFunction invoker); + + ArrayAccessSetInvoker + */ + + template<typename ElementType, typename IndexType> + class_& arrayoperatorget() { + using namespace internal; + + _embind_register_class_operator_array_get( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + TypeID<IndexType>::get(), + reinterpret_cast<internal::GenericFunction>(&internal::ArrayAccessGetInvoker<ClassType, ElementType>::invoke)); + } + + template<typename ElementType, typename IndexType> + class_& arrayoperatorset() { + using namespace internal; + + _embind_register_class_operator_array_set( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + TypeID<IndexType>::get(), + reinterpret_cast<internal::GenericFunction>(&internal::ArrayAccessSetInvoker<ClassType, ElementType>::invoke)); + return *this; + } + template<typename ReturnType> class_& cast(const char* methodName) { using namespace internal; @@ -764,6 +816,29 @@ namespace emscripten { }; //////////////////////////////////////////////////////////////////////////////// + // VECTORS + //////////////////////////////////////////////////////////////////////////////// + template<typename T> + class_<std::vector<T>> register_vector(const char* name) { + using namespace std; + typedef vector<T> VecType; + typedef typename vector<T>::iterator IterType; + typedef typename vector<T>::const_iterator ConstIterType; + + void (VecType::*push_back)(const T&) = &VecType::push_back; + const T& (VecType::*at)(size_t) const = &VecType::at; + auto c = class_<std::vector<T>>(name) + .template constructor<>() + .method("push_back", push_back) + .method("at", at) + .method("size", &vector<T>::size) + .template arrayoperatorget<T, size_t>() + .template arrayoperatorset<T, size_t>() + ; + return c; + } + + //////////////////////////////////////////////////////////////////////////////// // ENUMS //////////////////////////////////////////////////////////////////////////////// diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index ec302d3a..5a2deb7a 100755 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -133,19 +133,18 @@ namespace emscripten { template<typename T> struct BindingType; -#define EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(type) \ - template<> \ - struct BindingType<type> { \ - typedef type WireType; \ - \ - constexpr static WireType toWireType(type v) { \ - return v; \ - } \ - constexpr static type fromWireType(WireType v) { \ - return v; \ - } \ - static void destroy(WireType) { \ - } \ +#define EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(type) \ + template<> \ + struct BindingType<type> { \ + typedef type WireType; \ + constexpr static WireType toWireType(const type& v) { \ + return v; \ + } \ + constexpr static type fromWireType(WireType v) { \ + return v; \ + } \ + static void destroy(WireType) { \ + } \ } EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(char); @@ -276,7 +275,7 @@ namespace emscripten { }; static WireType toWireType(T v) { - return new T(v); + return new ActualT(v); } static Marshaller fromWireType(WireType p) { |