aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-12-06 16:35:47 -0800
committerBruce Mitchener <bruce.mitchener@gmail.com>2014-02-04 16:21:54 +0700
commit9ba56d2c20fb2a5d5572e6030bd9dc1794fefdd2 (patch)
treec74d388a3e78122bd42d73016624b1168570f492
parent52e04b489962f1167868aa46eb8325df4b2c9fdf (diff)
Add a sample for adding mixins to embind
-rw-r--r--system/include/emscripten/bind.h39
-rw-r--r--tests/embind/embind.test.js9
-rw-r--r--tests/embind/embind_test.cpp31
3 files changed, 66 insertions, 13 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 13fa2008..4d7547a1 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -533,6 +533,8 @@ namespace emscripten {
template<typename ClassType>
class value_array : public internal::noncopyable {
public:
+ typedef ClassType class_type;
+
value_array(const char* name) {
using namespace internal;
_embind_register_value_array(
@@ -605,6 +607,8 @@ namespace emscripten {
template<typename ClassType>
class value_object : public internal::noncopyable {
public:
+ typedef ClassType class_type;
+
value_object(const char* name) {
using namespace internal;
_embind_register_value_object(
@@ -753,6 +757,8 @@ namespace emscripten {
template<typename T>
class wrapper : public T {
public:
+ typedef T class_type;
+
explicit wrapper(val&& wrapped)
: wrapped(std::forward<val>(wrapped))
{}
@@ -808,6 +814,8 @@ namespace emscripten {
template<typename BaseClass>
struct base {
+ typedef BaseClass class_type;
+
template<typename ClassType>
static void verify() {
static_assert(!std::is_same<ClassType, BaseClass>::value, "Base must not have same type as class");
@@ -854,6 +862,9 @@ namespace emscripten {
template<typename ClassType, typename BaseSpecifier = internal::NoBaseClass>
class class_ {
public:
+ typedef ClassType class_type;
+ typedef BaseSpecifier base_specifier;
+
class_() = delete;
explicit class_(const char* name) {
@@ -874,7 +885,7 @@ namespace emscripten {
}
template<typename PointerType>
- class_& smart_ptr() {
+ const class_& smart_ptr() const {
using namespace internal;
typedef smart_ptr_trait<PointerType> PointerTrait;
@@ -895,14 +906,14 @@ namespace emscripten {
};
template<typename... ConstructorArgs, typename... Policies>
- class_& constructor(Policies... policies) {
+ const class_& constructor(Policies... policies) const {
return constructor(
&internal::operator_new<ClassType, ConstructorArgs...>,
policies...);
}
template<typename... Args, typename ReturnType, typename... Policies>
- class_& constructor(ReturnType (*factory)(Args...), Policies...) {
+ const class_& constructor(ReturnType (*factory)(Args...), Policies...) const {
using namespace internal;
// TODO: allows all raw pointers... policies need a rethink
@@ -917,7 +928,7 @@ namespace emscripten {
}
template<typename SmartPtr, typename... Args, typename... Policies>
- class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) {
+ const class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) const {
using namespace internal;
smart_ptr<SmartPtr>();
@@ -933,7 +944,7 @@ namespace emscripten {
}
template<typename WrapperType, typename PointerType = WrapperType*>
- class_& allow_subclass() {
+ const class_& allow_subclass() const {
using namespace internal;
auto cls = class_<WrapperType, base<ClassType>>(typeid(WrapperType).name())
@@ -947,7 +958,7 @@ namespace emscripten {
}
template<typename ReturnType, typename... Args, typename... Policies>
- class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) {
+ const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) const {
using namespace internal;
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args;
@@ -962,7 +973,7 @@ namespace emscripten {
}
template<typename ReturnType, typename... Args, typename... Policies>
- class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) {
+ const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) const {
using namespace internal;
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args;
@@ -977,7 +988,7 @@ namespace emscripten {
}
template<typename ReturnType, typename ThisType, typename... Args, typename... Policies>
- class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) {
+ const class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) const {
using namespace internal;
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
@@ -992,7 +1003,7 @@ namespace emscripten {
}
template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
- class_& property(const char* fieldName, const FieldType ClassType::*field) {
+ const class_& property(const char* fieldName, const FieldType ClassType::*field) const {
using namespace internal;
_embind_register_class_property(
@@ -1008,7 +1019,7 @@ namespace emscripten {
}
template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
- class_& property(const char* fieldName, FieldType ClassType::*field) {
+ const class_& property(const char* fieldName, FieldType ClassType::*field) const {
using namespace internal;
_embind_register_class_property(
@@ -1024,7 +1035,7 @@ namespace emscripten {
}
template<typename Getter>
- class_& property(const char* fieldName, Getter getter) {
+ const class_& property(const char* fieldName, Getter getter) const {
using namespace internal;
typedef GetterPolicy<Getter> GP;
_embind_register_class_property(
@@ -1040,7 +1051,7 @@ namespace emscripten {
}
template<typename Getter, typename Setter>
- class_& property(const char* fieldName, Getter getter, Setter setter) {
+ const class_& property(const char* fieldName, Getter getter, Setter setter) const {
using namespace internal;
typedef GetterPolicy<Getter> GP;
typedef SetterPolicy<Setter> SP;
@@ -1057,7 +1068,7 @@ namespace emscripten {
}
template<typename ReturnType, typename... Args, typename... Policies>
- class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) {
+ const class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) const {
using namespace internal;
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
@@ -1164,6 +1175,8 @@ namespace emscripten {
template<typename EnumType>
class enum_ {
public:
+ typedef EnumType enum_type;
+
enum_(const char* name) {
_embind_register_enum(
internal::TypeID<EnumType>::get(),
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index 0976c597..a36c8b08 100644
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -1916,6 +1916,15 @@ module({
sh1.delete();
});
});
+
+ BaseFixture.extend("mixin", function() {
+ test("can call mixin method", function() {
+ var a = new cm.DerivedWithMixin();
+ assert.instanceof(a, cm.Base);
+ assert.equal(10, a.get10());
+ a.delete();
+ });
+ });
});
/* global run_all_tests */
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index 508fe052..4efc4bd8 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -2273,3 +2273,34 @@ EMSCRIPTEN_BINDINGS(return_values) {
function("return_StringHolder_copy", &return_StringHolder_copy);
function("call_StringHolder_func", &call_StringHolder_func);
}
+
+
+struct Mixin {
+ int get10() const {
+ return 10;
+ }
+};
+
+template<typename ClassBinding>
+const ClassBinding& registerMixin(const ClassBinding& binding) {
+ // need a wrapper for implicit conversion from DerivedWithMixin to Mixin
+ struct Local {
+ static int get10(const typename ClassBinding::class_type& self) {
+ return self.get10();
+ }
+ };
+
+ return binding
+ .function("get10", &Local::get10)
+ ;
+}
+
+class DerivedWithMixin : public Base, public Mixin {
+};
+
+EMSCRIPTEN_BINDINGS(mixins) {
+ registerMixin(
+ class_<DerivedWithMixin, base<Base>>("DerivedWithMixin")
+ .constructor<>()
+ );
+}