Switching vector class_ instead of bound as an explicit type.

This commit is contained in:
mey 2012-11-30 14:56:58 -08:00 коммит произвёл Jukka Jylänki
Родитель 026a4d49e4
Коммит 15603bbafc
3 изменённых файлов: 179 добавлений и 38 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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...);
@ -620,27 +655,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
////////////////////////////////////////////////////////////////////////////////
@ -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;
@ -763,6 +815,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
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -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) {