diff options
-rwxr-xr-x | system/include/emscripten/bind.h | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 28fe1f3a..a807be4c 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -278,6 +278,11 @@ namespace emscripten { namespace internal { template<typename ClassType, typename... Args> + ClassType* operator_new(Args... args) { + return new ClassType(args...); + } + + template<typename ClassType, typename... Args> ClassType* raw_constructor( typename internal::BindingType<Args>::WireType... args ) { @@ -595,7 +600,49 @@ namespace emscripten { //////////////////////////////////////////////////////////////////////////////// // CLASSES //////////////////////////////////////////////////////////////////////////////// - // TODO: support class definitions without constructors. + + // abstract classes + template<typename T> + class wrapper : public T { + public: + wrapper(const val& wrapped) + : wrapped(wrapped) + {} + + template<typename ReturnType, typename... Args> + ReturnType call(const char* name, Args... args) const { + return Caller<ReturnType, Args...>::call(wrapped, name, args...); + } + + private: + // this class only exists because you can't partially specialize function templates + template<typename ReturnType, typename... Args> + struct Caller { + static ReturnType call(const val& v, const char* name, Args... args) { + return v.call(name, args...).template as<ReturnType>(); + } + }; + + template<typename... Args> + struct Caller<void, Args...> { + static void call(const val& v, const char* name, Args... args) { + v.call_void(name, args...); + } + }; + + /* + void assertInitialized() { + if (!jsobj) { + internal::_embind_fatal_error( + "Cannot invoke call on uninitialized Javascript interface wrapper.", "JSInterface"); + } + }*/ + val wrapped; + }; + +#define EMSCRIPTEN_WRAPPER(T) \ + T(const ::emscripten::val& v): wrapper(v) {} + // TODO: support external class constructors template<typename ClassType> class class_ { @@ -626,6 +673,21 @@ namespace emscripten { return *this; } + template<typename WrapperType> + class_& allow_subclass() { + using namespace internal; + + // TODO: unique or anonymous name + class_<WrapperType>("WrapperType") + .template constructor<val>() + ; + + return classmethod( + "implement", + &operator_new<WrapperType, val>, + allow_raw_pointer<ret_val>()); + } + template<typename ReturnType, typename... Args, typename... Policies> class_& method(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) { using namespace internal; |