Index: gin/object_template_builder.h |
diff --git a/gin/object_template_builder.h b/gin/object_template_builder.h |
index 87e2633862c0f175e06594a376536a03b9427480..9891c2bca75865da5334fef15b607d843dea63e0 100644 |
--- a/gin/object_template_builder.h |
+++ b/gin/object_template_builder.h |
@@ -7,12 +7,47 @@ |
#include "base/bind.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 { |
+ |
+// The base template is used for non-member function pointers. |
+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)); |
+ } |
+}; |
+ |
+// This partial specialization is used for member function pointers. |
Jeffrey Yasskin
2013/12/04 20:00:12
You should say what the member-function-pointer sp
|
+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 full specialization is used for v8::FunctionTemplate. |
+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 +63,28 @@ class ObjectTemplateBuilder { |
return SetImpl(name, ConvertToV8(isolate_, val)); |
} |
+ // In the following methods, T and U can be either function pointer, member |
+ // function pointer, or v8::FunctionTemplate. Most clients will want to use |
+ // one of the first two options. 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 +92,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_; |