From dd618d24fc2500ec49fe536936ea404e92cc7150 Mon Sep 17 00:00:00 2001 From: Chad Austin Date: Fri, 15 Feb 2013 16:49:36 -0800 Subject: [PATCH] implement an api for allowing JS subclasses of C++ interfaces --- system/include/emscripten/bind.h | 64 +++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 28fe1f3a8..a807be4cb 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -277,6 +277,11 @@ namespace emscripten { } namespace internal { + template + ClassType* operator_new(Args... args) { + return new ClassType(args...); + } + template ClassType* raw_constructor( typename internal::BindingType::WireType... args @@ -595,7 +600,49 @@ namespace emscripten { //////////////////////////////////////////////////////////////////////////////// // CLASSES //////////////////////////////////////////////////////////////////////////////// - // TODO: support class definitions without constructors. + + // abstract classes + template + class wrapper : public T { + public: + wrapper(const val& wrapped) + : wrapped(wrapped) + {} + + template + ReturnType call(const char* name, Args... args) const { + return Caller::call(wrapped, name, args...); + } + + private: + // this class only exists because you can't partially specialize function templates + template + struct Caller { + static ReturnType call(const val& v, const char* name, Args... args) { + return v.call(name, args...).template as(); + } + }; + + template + struct Caller { + 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 class class_ { @@ -626,6 +673,21 @@ namespace emscripten { return *this; } + template + class_& allow_subclass() { + using namespace internal; + + // TODO: unique or anonymous name + class_("WrapperType") + .template constructor() + ; + + return classmethod( + "implement", + &operator_new, + allow_raw_pointer()); + } + template class_& method(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) { using namespace internal;