diff options
Diffstat (limited to 'gin/function_template.h')
-rw-r--r-- | gin/function_template.h | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/gin/function_template.h b/gin/function_template.h new file mode 100644 index 0000000..9c5b154 --- /dev/null +++ b/gin/function_template.h @@ -0,0 +1,85 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/callback.h" +#include "base/logging.h" +#include "gin/arguments.h" +#include "gin/converter.h" +#include "gin/public/gin_embedders.h" +#include "gin/public/wrapper_info.h" +#include "gin/wrappable.h" + +#include "v8/include/v8.h" + +namespace gin { + +class PerIsolateData; + +template<typename T> +struct RemoveConstRef { + typedef T Type; +}; +template<typename T> +struct RemoveConstRef<const T&> { + typedef T Type; +}; + +class CallbackHolderBase : public Wrappable { + public: + static void EnsureRegistered(PerIsolateData* isolate_data); + virtual WrapperInfo* GetWrapperInfo() OVERRIDE; + static WrapperInfo kWrapperInfo; + protected: + virtual ~CallbackHolderBase() {} +}; + +template<> +struct Converter<CallbackHolderBase*> + : public WrappableConverter<CallbackHolderBase> {}; + +template<typename Sig> +class CallbackHolder : public CallbackHolderBase { + public: + CallbackHolder(const base::Callback<Sig>& callback) + : callback(callback) {} + base::Callback<Sig> callback; + private: + virtual ~CallbackHolder() {} +}; + +// TODO(aa): Generate the overloads below with pump. + +template<typename P1, typename P2> +static void DispatchToCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + CallbackHolderBase* holder_base = NULL; + CHECK(args.GetData(&holder_base)); + + typedef CallbackHolder<void(P1, P2)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename RemoveConstRef<P1>::Type a1; + typename RemoveConstRef<P2>::Type a2; + if (!args.GetNext(&a1) || + !args.GetNext(&a2)) { + args.ThrowError(); + return; + } + + holder->callback.Run(a1, a2); +} + +template<typename P1, typename P2> +v8::Local<v8::FunctionTemplate> CreateFunctionTempate( + v8::Isolate* isolate, + const base::Callback<void(P1, P2)>& callback) { + typedef CallbackHolder<void(P1, P2)> HolderT; + scoped_refptr<HolderT> holder(new HolderT(callback)); + return v8::FunctionTemplate::New( + &DispatchToCallback<P1, P2>, + ConvertToV8<CallbackHolderBase*>(isolate, holder.get())); +} + +} // namespace gin |