Cromon

Untitled

Jan 14th, 2013
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.40 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "Utils/TypeTraitsExt.h"
  4.  
  5. namespace JS
  6. {
  7.     class Scope;
  8.  
  9.     namespace detail
  10.     {
  11.         void registerClassTemplate(const std::wstring& clsName, std::shared_ptr<Scope> parent, v8::Persistent<v8::FunctionTemplate> constructor);
  12.     };
  13.  
  14.     template<typename T>
  15.     class Class : public std::enable_shared_from_this<Class<T>>
  16.     {
  17.         friend class Namespace;
  18.  
  19.         template<typename Q>
  20.         class ClassInstance
  21.         {
  22.             std::shared_ptr<Q> mInstance;
  23.  
  24.         public:
  25.             ClassInstance(std::shared_ptr<Q> instance) : mInstance(instance) {
  26.             }
  27.  
  28.             std::shared_ptr<Q> getInstance() { return mInstance; }
  29.         };
  30.  
  31.         template<typename Res, typename... OArgs>
  32.         class FunctionInstance
  33.         {
  34.         private:
  35.             std::function<Res (OArgs...)> mFunction;
  36.  
  37.             template<uint32 size, typename _T, typename... FullArgs, typename... Args>
  38.             Res expand(std::shared_ptr<T> instance, const v8::Arguments& args, Args... curArgs) {
  39.                 return expand<size + 1, FullArgs...>(instance, args, curArgs..., getParam<_T>(args[size]));
  40.             }
  41.  
  42.             template<uint32 size, typename... Args>
  43.             Res expand(std::shared_ptr<T> instance, const v8::Arguments& args, Args... curArgs) {
  44.                 return mFunction(instance.get(), curArgs...);
  45.             }
  46.  
  47.             template<uint32 size, typename _T, typename... FullArgs, typename... Args>
  48.             Res expandUnbound(std::shared_ptr<T> instance, const v8::Arguments& args, Args... curArgs) {
  49.                 return expandUnbound<size + 1, FullArgs...>(instance, args, curArgs..., getParam<_T>(args[size]));
  50.             }
  51.  
  52.             template<uint32 size, typename... Args>
  53.             Res expandUnbound(std::shared_ptr<T> instance, const v8::Arguments& args, Args... curArgs) {
  54.                 return mFunction(instance, curArgs...);
  55.             }
  56.  
  57.             template<uint32 size, typename _T, typename... Args>
  58.             typename Utils::enable_if_not<Utils::IsSharedPtr<_T>::value, Res>::type expandMember(std::shared_ptr<T> instance, const v8::Arguments& args) {
  59.                 return expand<0, Args...>(instance, args);
  60.             }
  61.  
  62.             template<uint32 size, typename _T, typename... Args>
  63.             typename std::enable_if<Utils::IsSharedPtr<_T>::value, Res>::type expandMember(std::shared_ptr<T> instance, const v8::Arguments& args) {
  64.                 return expandUnbound<0, Args...>(instance, args);
  65.             }
  66.  
  67.         public:
  68.             FunctionInstance(std::function<Res (OArgs...)> fun) : mFunction(fun) {
  69.             }
  70.  
  71.             Res callFunction(std::shared_ptr<T> instance, const v8::Arguments& args) {
  72.                 return expandMember<0, OArgs...>(instance, args);
  73.             }
  74.         };
  75.  
  76.         template<typename Res, typename... Args>
  77.         static v8::Handle<v8::Value> __cdecl memberFunctionCallback(const v8::Arguments& args) {
  78.             FunctionInstance<Res, Args...>* fPtr = (FunctionInstance<Res, Args...>*)v8::Local<v8::External>::Cast(args.Data())->Value();
  79.             ClassInstance<T>* inst = (ClassInstance<T>*)v8::Local<v8::External>::Cast(args.This()->GetInternalField(0))->Value();
  80.            
  81.             Res res = fPtr->callFunction(inst->getInstance(), args);
  82.  
  83.             return pushParam<Res>(res);
  84.         }
  85.  
  86.         static void __cdecl destructorCall(v8::Persistent<v8::Value> obj, void* params) {
  87.             ClassInstance<T>* instance = (ClassInstance<T>*)params;
  88.             delete instance;
  89.  
  90.             obj.Dispose();
  91.         }
  92.  
  93.         template<typename... Args>
  94.         static v8::Handle<v8::Value> __cdecl constructorCall(const v8::Arguments& args) {
  95.             if(!args.IsConstructCall())
  96.                 return v8::Undefined();
  97.  
  98.             Class<T>* cls = (Class<T>*)v8::Local<v8::External>::Cast(args.Data())->Value();
  99.  
  100.             ClassInstance<T>* instance = new ClassInstance<T>(cls->expand<0, Args...>(args));
  101.             auto obj = v8::Persistent<v8::Object>::New(cls->mPrototype->NewInstance());
  102.             obj->SetInternalField(0, v8::External::New(instance));
  103.  
  104.             obj.MakeWeak(instance, &Class<T>::destructorCall);
  105.  
  106.             return obj;
  107.         }
  108.  
  109.         template<typename P>
  110.         static void __cdecl defPropertySetCall(v8::Local<v8::String> key, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
  111.             ClassInstance<T>* inst = (ClassInstance<T>*)v8::Local<v8::External>::Cast(info.This()->GetInternalField(0))->Value();
  112.             P T::*memPtr = union_cast<P T::*>(v8::Local<v8::External>::Cast(info.Data())->Value());
  113.  
  114.             inst->getInstance().get()->*memPtr = getParam<P>(value);
  115.         }
  116.  
  117.         template<typename P>
  118.         static v8::Handle<v8::Value> __cdecl defPropertyGetCall(v8::Local<v8::String> key, const v8::AccessorInfo& info) {
  119.             ClassInstance<T>* inst = (ClassInstance<T>*)v8::Local<v8::External>::Cast(info.This()->GetInternalField(0))->Value();
  120.             P T::*memPtr = union_cast<P T::*>(v8::Local<v8::External>::Cast(info.Data())->Value());
  121.  
  122.             const P& value = inst->getInstance().get()->*memPtr;
  123.             return pushParam<P>(value);
  124.         }
  125.  
  126.         template<typename T>
  127.         static typename std::enable_if<std::is_integral<T>::value, v8::Handle<v8::Value>>::type pushParam(const T& value) {
  128.             return v8::Integer::New((int32_t)value);
  129.         }
  130.  
  131.         template<typename T>
  132.         static typename std::enable_if<std::is_floating_point<T>::value, v8::Handle<v8::Value>>::type pushParam(const T& value) {
  133.             return v8::Number::New((double)value);
  134.         }
  135.  
  136.         template<typename T>
  137.         static typename std::enable_if<std::is_integral<T>::value, T>::type getParam(v8::Handle<v8::Value> val) {
  138.             return (T)val->IntegerValue();
  139.         }
  140.  
  141.         template<typename T>
  142.         static typename std::enable_if<std::is_floating_point<T>::value, T>::type getParam(v8::Handle<v8::Value> val) {
  143.             return (T)val->NumberValue();
  144.         }
  145.  
  146.         template<uint32 size, typename _T, typename... FullArgs, typename... Args>
  147.         std::shared_ptr<T> expand(const v8::Arguments& args, Args... curArgs) {
  148.             return expand<size + 1, FullArgs...>(args, curArgs..., getParam<_T>(args[size]));
  149.         }
  150.  
  151.         template<uint32 size, typename... Args>
  152.         std::shared_ptr<T> expand(const v8::Arguments& args, Args... curArgs) {
  153.             return std::make_shared<T>(curArgs...);
  154.         }
  155.  
  156.         template<typename... Args>
  157.         std::shared_ptr<T> callFunction(const v8::Arguments& args) {
  158.             return expand<0, Args...>(args);
  159.         }
  160.  
  161.         v8::Persistent<v8::ObjectTemplate> mPrototype;
  162.         v8::Persistent<v8::FunctionTemplate> mConstructorObj;
  163.         std::wstring mName;
  164.         std::shared_ptr<Scope> mParent;
  165.         std::shared_ptr<Class<T>> mOwnHolder;
  166.  
  167.         void keepAlive() {
  168.             mOwnHolder = shared_from_this();
  169.         }
  170.  
  171.         template<typename Dst, typename Src>
  172.         static Dst union_cast(Src src) {
  173.             union { Src s; Dst d; } u = { src };
  174.             return u.d;
  175.         }
  176.  
  177.     public:
  178.         Class(const std::wstring& name, std::shared_ptr<Scope> parent) {
  179.             mName = name;
  180.             mParent = parent;
  181.            
  182.         }
  183.  
  184.         template<typename Res, typename... Args>
  185.         void def_function(const std::wstring& name, Res (T::*func)(Args...)) {
  186.             v8::Persistent<v8::External> pers = v8::Persistent<v8::External>::New(v8::External::New(new FunctionInstance<Res, T*, Args...>(std::mem_fun<Res, T, Args...>(func))));
  187.             v8::Persistent<v8::FunctionTemplate> funTmpl = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(&Class<T>::memberFunctionCallback<Res, T*, Args...>, pers));
  188.  
  189.             mPrototype->Set(v8::String::New(StringUtils::toAnsi(name).c_str()), funTmpl);
  190.         }
  191.  
  192.         template<typename Res, typename... Args>
  193.         void def_function(const std::wstring& name, std::function<Res (std::shared_ptr<T>, Args...)> fun) {
  194.             v8::Persistent<v8::External> pers = v8::Persistent<v8::External>::New(v8::External::New(new FunctionInstance<Res, std::shared_ptr<T>, Args...>(fun)));
  195.             v8::Persistent<v8::FunctionTemplate> funTmpl = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(&Class<T>::memberFunctionCallback<Res, std::shared_ptr<T>, Args...>, pers));
  196.  
  197.             mPrototype->Set(v8::String::New(StringUtils::toAnsi(name).c_str()), funTmpl);
  198.         }
  199.  
  200.         template<typename Res, typename... Args>
  201.         void def_function(const std::wstring& name, Res (*fun)(std::shared_ptr<T>, Args...)) {
  202.             def_function(name, std::function<Res (std::shared_ptr<T>, Args...)>(fun));
  203.         }
  204.  
  205.         template<typename... Args>
  206.         void def_constructor() {
  207.             mConstructorObj = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(&Class<T>::constructorCall<Args...>, v8::External::New(this)));
  208.             mPrototype = v8::Persistent<v8::ObjectTemplate>::New(mConstructorObj->PrototypeTemplate());
  209.             mPrototype->SetInternalFieldCount(1);
  210.         }
  211.  
  212.         template<typename P>
  213.         void def_property(const std::wstring& name, P T::* ptr) {
  214.             mPrototype->SetAccessor(
  215.                 v8::String::New(StringUtils::toAnsi(name).c_str()),
  216.                 &Class<T>::defPropertyGetCall<P>,
  217.                 &Class<T>::defPropertySetCall<P>,
  218.                 v8::External::New(union_cast<void*>(ptr)));
  219.         }
  220.  
  221.         void finalize() {
  222.             detail::registerClassTemplate(mName, mParent, mConstructorObj);
  223.         }
  224.     };
  225. };
Advertisement
Add Comment
Please, Sign In to add comment