diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-06 06:55:25 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-06 06:55:25 +0000 |
commit | bf3dd3cc6b32fd98b82f5e22a9ab1fddbe38f8d9 (patch) | |
tree | a5f3d7b91e1b0f5a70660ab80d6c4c1d8f5a33c8 /gin/object_template_builder.h | |
parent | c80725d518df535f6e08e61d5bab47600046a646 (diff) | |
download | chromium_src-bf3dd3cc6b32fd98b82f5e22a9ab1fddbe38f8d9.zip chromium_src-bf3dd3cc6b32fd98b82f5e22a9ab1fddbe38f8d9.tar.gz chromium_src-bf3dd3cc6b32fd98b82f5e22a9ab1fddbe38f8d9.tar.bz2 |
Gin: Add support for binding JS methods to C++ instance methods.
Also:
- Added support for computed properties to ObjectTemplateBuilder
- Realized it was possible for CreateFunctionTemplate to be just one template
BUG=
R=abarth@chromium.org, jyasskin@chromium.org
Review URL: https://codereview.chromium.org/103703002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239126 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin/object_template_builder.h')
-rw-r--r-- | gin/object_template_builder.h | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/gin/object_template_builder.h b/gin/object_template_builder.h index 87e2633..9af5e4f 100644 --- a/gin/object_template_builder.h +++ b/gin/object_template_builder.h @@ -6,13 +6,64 @@ #define GIN_OBJECT_TEMPLATE_BUILDER_H_ #include "base/bind.h" +#include "base/callback.h" #include "base/strings/string_piece.h" +#include "base/template_util.h" #include "gin/converter.h" #include "gin/function_template.h" #include "v8/include/v8.h" namespace gin { +namespace { + +// Base template - used only for non-member function pointers. Other types +// either go to one of the below specializations, or go here and fail to compile +// because of base::Bind(). +template<typename T, typename Enable = void> +struct CallbackTraits { + static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate, + T callback) { + return CreateFunctionTemplate(isolate, base::Bind(callback)); + } +}; + +// Specialization for base::Callback. +template<typename T> +struct CallbackTraits<base::Callback<T> > { + static v8::Handle<v8::FunctionTemplate> CreateTemplate( + v8::Isolate* isolate, const base::Callback<T>& callback) { + return CreateFunctionTemplate(isolate, callback); + } +}; + +// Specialization for member function pointers. We need to handle this case +// specially because the first parameter for callbacks to MFP should typically +// come from the the JavaScript "this" object the function was called on, not +// from the first normal parameter. +template<typename T> +struct CallbackTraits<T, typename base::enable_if< + base::is_member_function_pointer<T>::value >::type> { + static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate, + T callback) { + return CreateFunctionTemplate(isolate, base::Bind(callback), + HolderIsFirstArgument); + } +}; + +// This specialization allows people to construct function templates directly if +// they need to do fancier stuff. +template<> +struct CallbackTraits<v8::Handle<v8::FunctionTemplate> > { + static v8::Handle<v8::FunctionTemplate> CreateTemplate( + v8::Handle<v8::FunctionTemplate> templ) { + return templ; + } +}; + +} // namespace + + // ObjectTemplateBuilder provides a handy interface to creating // v8::ObjectTemplate instances with various sorts of properties. class ObjectTemplateBuilder { @@ -28,15 +79,28 @@ class ObjectTemplateBuilder { return SetImpl(name, ConvertToV8(isolate_, val)); } + // In the following methods, T and U can be function pointer, member function + // pointer, base::Callback, or v8::FunctionTemplate. Most clients will want to + // use one of the first two options. Also see gin::CreateFunctionTemplate() + // for creating raw function templates. template<typename T> - ObjectTemplateBuilder& SetMethod(const base::StringPiece& name, T val) { - return SetMethod(name, base::Bind(val)); + ObjectTemplateBuilder& SetMethod(const base::StringPiece& name, + const T& callback) { + return SetImpl(name, CallbackTraits<T>::CreateTemplate(isolate_, callback)); } - template<typename T> - ObjectTemplateBuilder& SetMethod(const base::StringPiece& name, - const base::Callback<T>& callback) { - return SetImpl(name, CreateFunctionTemplate(isolate_, callback)); + ObjectTemplateBuilder& SetProperty(const base::StringPiece& name, + const T& getter) { + return SetPropertyImpl(name, + CallbackTraits<T>::CreateTemplate(isolate_, getter), + v8::Local<v8::FunctionTemplate>()); + } + template<typename T, typename U> + ObjectTemplateBuilder& SetProperty(const base::StringPiece& name, + const T& getter, const U& setter) { + return SetPropertyImpl(name, + CallbackTraits<T>::CreateTemplate(isolate_, getter), + CallbackTraits<U>::CreateTemplate(isolate_, setter)); } v8::Local<v8::ObjectTemplate> Build(); @@ -44,6 +108,9 @@ class ObjectTemplateBuilder { private: ObjectTemplateBuilder& SetImpl(const base::StringPiece& name, v8::Handle<v8::Data> val); + ObjectTemplateBuilder& SetPropertyImpl( + const base::StringPiece& name, v8::Handle<v8::FunctionTemplate> getter, + v8::Handle<v8::FunctionTemplate> setter); v8::Isolate* isolate_; |