Index: gin/wrappable.h |
diff --git a/gin/wrappable.h b/gin/wrappable.h |
index 741bf8ff6d11b72ef7a3ffc4297868aa2346adf4..8f8feb5c31b0b62649ff13e40eef9d3bd0b8fcfd 100644 |
--- a/gin/wrappable.h |
+++ b/gin/wrappable.h |
@@ -11,32 +11,29 @@ |
namespace gin { |
-// Wrappable is an abstract base class for C++ objects that have cooresponding |
-// v8 wrapper objects. To retain a Wrappable object on the stack, use a |
-// gin::Handle. |
-class Wrappable { |
- public: |
- // Subclasses must return the WrapperInfo object associated with the |
- // v8::ObjectTemplate for their subclass. When creating a v8 wrapper for |
- // this object, we'll look up the appropriate v8::ObjectTemplate in the |
- // PerIsolateData using this WrapperInfo pointer. |
- virtual WrapperInfo* GetWrapperInfo() = 0; |
+template<typename T> |
+struct WrappableTraits { |
+ static WrapperInfo kWrapperInfo; |
+}; |
+ |
+template<typename T> |
+WrapperInfo WrappableTraits<T>::kWrapperInfo = { |
+ gin::kEmbedderNativeGin |
+}; |
- // Subclasses much also contain a static member variable named |kWrapperInfo| |
- // of type WrapperInfo: |
- // |
- // static WrapperInfo kWrapperInfo; |
- // |
- // If |obj| is a concrete instance of the subclass, then obj->GetWrapperInfo() |
- // must return &kWrapperInfo. |
- // |
- // We use both the dynamic |GetWrapperInfo| function and the static |
- // |kWrapperInfo| member variable during wrapping and the unwrapping. During |
- // wrapping, we use GetWrapperInfo() to make sure we use the correct |
- // v8::ObjectTemplate for the object regardless of the declared C++ type. |
- // During unwrapping, we use the static member variable to prevent type errors |
- // during the downcast from Wrappable to the subclass. |
+// Wrappable is a base class for C++ objects that have cooresponding v8 wrapper |
+// objects. To retain a Wrappable object on the stack, use a gin::Handle. |
+// |
+// Usage: |
+// class MyClass : Wrappable<MyClass> { |
+// ... |
+// }; |
+template<typename T> |
+class Wrappable; |
+ |
+class WrappableBase { |
+ public: |
// Retrieve (or create) the v8 wrapper object cooresponding to this object. |
// To customize the wrapper created for a subclass, override GetWrapperInfo() |
Aaron Boodman
2013/12/06 06:36:24
I don't get this comment. What would overriding Ge
|
// instead of overriding this function. |
@@ -49,24 +46,36 @@ class Wrappable { |
// the object will leak because we use the weak callback from the wrapper |
// as the signal to delete the wrapped object. |
+ virtual WrapperInfo* GetWrapperInfo() = 0; |
+ |
protected: |
- Wrappable(); |
- virtual ~Wrappable(); |
+ WrappableBase(); |
+ virtual ~WrappableBase(); |
private: |
static void WeakCallback( |
- const v8::WeakCallbackData<v8::Object, Wrappable>& data); |
+ const v8::WeakCallbackData<v8::Object, WrappableBase>& data); |
v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); |
v8::Persistent<v8::Object> wrapper_; // Weak |
- DISALLOW_COPY_AND_ASSIGN(Wrappable); |
+ DISALLOW_COPY_AND_ASSIGN(WrappableBase); |
}; |
+ |
+template<typename T> |
+class Wrappable : public WrappableBase { |
+ public: |
+ virtual WrapperInfo* GetWrapperInfo() { |
+ return &WrappableTraits<T>::kWrapperInfo; |
+ } |
+}; |
+ |
+ |
// This converter handles any subclass of Wrappable. |
template<typename T> |
struct Converter<T*, typename base::enable_if< |
- base::is_convertible<T*, Wrappable*>::value>::type> { |
+ base::is_convertible<T*, Wrappable<T>*>::value>::type> { |
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) { |
return val->GetWrapper(isolate); |
} |
@@ -85,7 +94,7 @@ struct Converter<T*, typename base::enable_if< |
// If this fails, the object is managed by Gin, but it's not wrapping an |
// instance of T. |
- if (info != &T::kWrapperInfo) |
+ if (info != &WrappableTraits<T>::kWrapperInfo) |
return false; |
void* pointer = obj->GetAlignedPointerFromInternalField(kEncodedValueIndex); |