diff options
-rwxr-xr-x | system/include/emscripten/bind.h | 63 | ||||
-rwxr-xr-x | tests/embind/embind.test.js | 28 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 45 |
3 files changed, 101 insertions, 35 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index bd170dea..81ee38e9 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -471,8 +471,30 @@ namespace emscripten { noncopyable(const noncopyable&) = delete; const noncopyable& operator=(const noncopyable&) = delete; }; + + template<typename T> + struct ReturnType; + + template<typename RT, typename ClassType, typename... Args> + struct ReturnType<RT (ClassType::*)(Args...)> { + typedef RT type; + }; + + template<typename ClassType, typename ElementType> + typename BindingType<ElementType>::WireType get_by_index(int index, ClassType& ptr) { + return BindingType<ElementType>::toWireType(ptr[index]); + } + + template<typename ClassType, typename ElementType> + void set_by_index(int index, ClassType& ptr, typename BindingType<ElementType>::WireType wt) { + ptr[index] = BindingType<ElementType>::fromWireType(wt); + } } + template<int Index> + struct index { + }; + //////////////////////////////////////////////////////////////////////////////// // VALUE TUPLES //////////////////////////////////////////////////////////////////////////////// @@ -526,7 +548,26 @@ namespace emscripten { reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), SP::getContext(setter)); return *this; - } + } + + template<int Index> + value_tuple& element(index<Index>) { + using namespace internal; + typedef + typename std::remove_reference< + typename ReturnType<decltype(&ClassType::operator[])>::type + >::type + ElementType; + _embind_register_tuple_element( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>), + reinterpret_cast<void*>(Index), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>), + reinterpret_cast<void*>(Index)); + return *this; + } }; //////////////////////////////////////////////////////////////////////////////// @@ -588,6 +629,26 @@ namespace emscripten { SP::getContext(setter)); return *this; } + + template<int Index> + value_struct& field(const char* fieldName, index<Index>) { + using namespace internal; + typedef + typename std::remove_reference< + typename ReturnType<decltype(&ClassType::operator[])>::type + >::type + ElementType; + _embind_register_struct_field( + TypeID<ClassType>::get(), + fieldName, + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>), + reinterpret_cast<void*>(Index), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>), + reinterpret_cast<void*>(Index)); + return *this; + } }; //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index 020719d5..f365c1b8 100755 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -977,32 +977,32 @@ module({ test("can return tuples by value", function() { var c = cm.emval_test_return_TupleVector(); - assert.deepEqual([1, 2, 3], c); + assert.deepEqual([1, 2, 3, 4], c); }); test("tuples can contain tuples", function() { var c = cm.emval_test_return_TupleVectorTuple(); - assert.deepEqual([[1, 2, 3]], c); + assert.deepEqual([[1, 2, 3, 4]], c); }); test("can pass tuples by value", function() { - var c = cm.emval_test_take_and_return_TupleVector([4, 5, 6]); - assert.deepEqual([4, 5, 6], c); + var c = cm.emval_test_take_and_return_TupleVector([4, 5, 6, 7]); + assert.deepEqual([4, 5, 6, 7], c); }); test("can return structs by value", function() { var c = cm.emval_test_return_StructVector(); - assert.deepEqual({x: 1, y: 2, z: 3}, c); + assert.deepEqual({x: 1, y: 2, z: 3, w: 4}, c); }); test("can pass structs by value", function() { - var c = cm.emval_test_take_and_return_StructVector({x: 4, y: 5, z: 6}); - assert.deepEqual({x: 4, y: 5, z: 6}, c); + var c = cm.emval_test_take_and_return_StructVector({x: 4, y: 5, z: 6, w: 7}); + assert.deepEqual({x: 4, y: 5, z: 6, w: 7}, c); }); test("can pass and return tuples in structs", function() { - var d = cm.emval_test_take_and_return_TupleInStruct({field: [1, 2, 3]}); - assert.deepEqual({field: [1, 2, 3]}, d); + var d = cm.emval_test_take_and_return_TupleInStruct({field: [1, 2, 3, 4]}); + assert.deepEqual({field: [1, 2, 3, 4]}, d); }); test("can clone handles", function() { @@ -1364,9 +1364,9 @@ module({ called = true; assert.equal(10, i); assert.equal(1.5, f); - assert.deepEqual([1.25, 2.5, 3.75], tv); - assert.deepEqual({x: 1.25, y: 2.5, z: 3.75}, sv); - }, 10, 1.5, [1.25, 2.5, 3.75], {x: 1.25, y: 2.5, z: 3.75}); + assert.deepEqual([1.25, 2.5, 3.75, 4], tv); + assert.deepEqual({x: 1.25, y: 2.5, z: 3.75, w:4}, sv); + }, 10, 1.5, [1.25, 2.5, 3.75, 4], {x: 1.25, y: 2.5, z: 3.75, w:4}); assert.true(called); }); }); @@ -1575,8 +1575,8 @@ module({ BaseFixture.extend("constants", function() { assert.equal(10, cm.INT_CONSTANT); assert.equal("some string", cm.STRING_CONSTANT); - assert.deepEqual([1, 2, 3], cm.VALUE_TUPLE_CONSTANT); - assert.deepEqual({x:1,y:2,z:3}, cm.VALUE_STRUCT_CONSTANT); + assert.deepEqual([1, 2, 3, 4], cm.VALUE_TUPLE_CONSTANT); + assert.deepEqual({x:1,y:2,z:3,w:4}, cm.VALUE_STRUCT_CONSTANT); }); }); diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index 1ef3fb16..ea332f2d 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -721,7 +721,20 @@ std::map<std::string, int> embind_test_get_string_int_map() { };
struct Vector {
- float x, y, z;
+ Vector() = delete;
+
+ Vector(float x_, float y_, float z_, float w_)
+ : x(x_)
+ , y(y_)
+ , z(z_)
+ , w(w_)
+ {}
+
+ float x, y, z, w;
+
+ float& operator[](int i) {
+ return (&x)[i];
+ }
float getY() const {
return y;
@@ -736,9 +749,13 @@ struct DummyDataToTestPointerAdjustment { };
struct TupleVector : DummyDataToTestPointerAdjustment, Vector {
+ TupleVector(): Vector(0, 0, 0, 0) {}
+ TupleVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
};
struct StructVector : DummyDataToTestPointerAdjustment, Vector {
+ StructVector(): Vector(0, 0, 0, 0) {}
+ StructVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
};
float readVectorZ(const Vector& v) {
@@ -750,15 +767,11 @@ void writeVectorZ(Vector& v, float z) { }
struct TupleVectorTuple {
- TupleVector v;
+ TupleVector v = TupleVector(0, 0, 0, 0);
};
TupleVector emval_test_return_TupleVector() {
- TupleVector cv;
- cv.x = 1;
- cv.y = 2;
- cv.z = 3;
- return cv;
+ return TupleVector(1, 2, 3, 4);
}
TupleVector emval_test_take_and_return_TupleVector(TupleVector v) {
@@ -772,11 +785,7 @@ TupleVectorTuple emval_test_return_TupleVectorTuple() { }
StructVector emval_test_return_StructVector() {
- StructVector v;
- v.x = 1;
- v.y = 2;
- v.z = 3;
- return v;
+ return StructVector(1, 2, 3, 4);
}
StructVector emval_test_take_and_return_StructVector(StructVector v) {
@@ -1433,16 +1442,10 @@ EMSCRIPTEN_BINDINGS(constants) { constant("INT_CONSTANT", 10);
constant("STRING_CONSTANT", std::string("some string"));
- TupleVector tv;
- tv.x = 1;
- tv.y = 2;
- tv.z = 3;
+ TupleVector tv(1, 2, 3, 4);
constant("VALUE_TUPLE_CONSTANT", tv);
- StructVector sv;
- sv.x = 1;
- sv.y = 2;
- sv.z = 3;
+ StructVector sv(1, 2, 3, 4);
constant("VALUE_STRUCT_CONSTANT", sv);
}
@@ -1484,6 +1487,7 @@ EMSCRIPTEN_BINDINGS(tests) { .element(&TupleVector::x)
.element(&Vector::getY, &Vector::setY)
.element(&readVectorZ, &writeVectorZ)
+ .element(index<3>())
;
function("emval_test_return_TupleVector", &emval_test_return_TupleVector);
@@ -1499,6 +1503,7 @@ EMSCRIPTEN_BINDINGS(tests) { .field("x", &StructVector::x)
.field("y", &Vector::getY, &Vector::setY)
.field("z", &readVectorZ, &writeVectorZ)
+ .field("w", index<3>())
;
function("emval_test_return_StructVector", &emval_test_return_StructVector);
|