aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormey <mey@imvu.com>2012-11-30 14:56:58 -0800
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:22:15 +0300
commit15603bbafc0aa68f9d8d843e083b89bfc566533d (patch)
tree45ed85654607be98395485b164f28af73362c330
parent026a4d49e496339c0f31b79ca3b399c53dac5f7f (diff)
Switching vector class_ instead of bound as an explicit type.
-rwxr-xr-xsrc/embind/embind.js69
-rwxr-xr-xsystem/include/emscripten/bind.h121
-rwxr-xr-xsystem/include/emscripten/wire.h27
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) {