diff --git a/src/vu8/Class.hpp b/src/vu8/Class.hpp index 65bae3a..6042e95 100644 --- a/src/vu8/Class.hpp +++ b/src/vu8/Class.hpp @@ -9,12 +9,15 @@ #include #include #include +#include #include #include #include #include +#include + #include #include @@ -64,7 +67,7 @@ struct ClassSingletonFactory { template class ClassSingleton - : detail::LazySingleton< ClassSingleton >, + : private detail::LazySingleton< ClassSingleton >, public ClassSingletonFactory, Factory> { friend class ClassSingletonFactory, Factory>; @@ -96,20 +99,38 @@ class ClassSingleton } template - static inline typename boost::disable_if< - boost::is_same, ValueHandle >::type - ForwardReturn(T *obj, const v8::Arguments& args) { + static inline typename + boost::enable_if, + ValueHandle >::type ForwardReturn (T *obj, const v8::Arguments& args) { return ToV8(Invoke

(obj, args)); } template - static inline typename boost::enable_if< - boost::is_same, ValueHandle >::type - ForwardReturn(T *obj, const v8::Arguments& args) { + static inline typename + boost::enable_if, + ValueHandle >::type ForwardReturn (T *obj, const v8::Arguments& args) { Invoke

(obj, args); return v8::Undefined(); } + template + static inline typename + boost::enable_if::type ForwardReturn (T *obj, const v8::Arguments& args) { + typedef typename P::ClassSingleton LocalSelf; + typedef typename P::return_type ReturnType; + + v8::HandleScope scope; + ReturnType* return_value = new ReturnType(Invoke

(obj, args)); + v8::Local localObj = + LocalSelf::Instance().func_->GetFunction()->NewInstance(); + v8::Persistent persistentObj = + v8::Persistent::New(localObj); + persistentObj->SetInternalField(0, v8::External::New(return_value)); + persistentObj.MakeWeak(return_value, &LocalSelf::MadeWeak); + return scope.Close(localObj); + } + // every method is run inside a handle scope template static inline ValueHandle Forward(const v8::Arguments& args) { diff --git a/src/vu8/detail/ProtoHelper.hpp b/src/vu8/detail/ProtoHelper.hpp index 1aa3b89..89f1590 100644 --- a/src/vu8/detail/ProtoHelper.hpp +++ b/src/vu8/detail/ProtoHelper.hpp @@ -7,11 +7,17 @@ # include # include # include +# include # ifndef VU8_PROTO_MAX_SIZE # define VU8_PROTO_MAX_SIZE VU8_PP_ITERATION_LIMIT # endif -namespace vu8 { namespace detail { +namespace vu8 { + +template struct Class; +template struct ClassSingleton; + +namespace detail { namespace mpl = boost::mpl; @@ -48,12 +54,30 @@ template : FunProtoBase { typedef mpl::vector arguments; typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A)); + typedef boost::false_type IS_RETURN_WRAPPED_CLASS; +}; + +template +struct MemFunProto ( BOOST_PP_ENUM_PARAMS(n, A) )> : FunProtoBase { + typedef mpl::vector arguments; + typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A)); + typedef boost::true_type IS_RETURN_WRAPPED_CLASS; + typedef vu8::ClassSingleton ClassSingleton; }; template struct MemFunProto : FunProtoBase { typedef mpl::vector arguments; typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A)) const; + typedef boost::false_type IS_RETURN_WRAPPED_CLASS; +}; + +template +struct MemFunProto ( BOOST_PP_ENUM_PARAMS(n, A) )> : FunProtoBase { + typedef mpl::vector arguments; + typedef R(C::*method_type)(BOOST_PP_ENUM_PARAMS(n, A)) const; + typedef boost::true_type IS_RETURN_WRAPPED_CLASS; + typedef vu8::ClassSingleton ClassSingleton; }; } } diff --git a/src/vu8/detail/TypeTraits.hpp b/src/vu8/detail/TypeTraits.hpp new file mode 100644 index 0000000..368cb56 --- /dev/null +++ b/src/vu8/detail/TypeTraits.hpp @@ -0,0 +1,43 @@ +#ifndef TYPETRAITS_HPP_ +#define TYPETRAITS_HPP_ + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +namespace vu8 { + +template struct remove_reference_and_const { + typedef typename boost::remove_const< + typename boost::remove_reference::type + >::type type; +}; + +template +struct is_to_v8_convertible : public boost::false_type { }; + +template +struct is_to_v8_convertible +>::type> : public boost::true_type { }; + +#define VU8_TO_V8_CONV_TYPE_TRAIT_SPEC(T,M,spec) \ +template \ +struct is_to_v8_convertible \ +>::type> : public boost::true_type { }; \ +/**/ + +VU8_TO_V8_CONV_TYPE_TRAIT_SPEC(T,T,v8::Handle); +VU8_TO_V8_CONV_TYPE_TRAIT_SPEC(T,typename remove_reference_and_const::type, std::string); +} + +#endif /* TYPETRAITS_HPP_ */