| OLD | NEW | 
|   1 // Copyright 2013 The Chromium Authors. All rights reserved. |   1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
|   2 // Use of this source code is governed by a BSD-style license that can be |   2 // Use of this source code is governed by a BSD-style license that can be | 
|   3 // found in the LICENSE file. |   3 // found in the LICENSE file. | 
|   4  |   4  | 
|   5 #ifndef GIN_WRAPPABLE_H_ |   5 #ifndef GIN_WRAPPABLE_H_ | 
|   6 #define GIN_WRAPPABLE_H_ |   6 #define GIN_WRAPPABLE_H_ | 
|   7  |   7  | 
|   8 #include "base/memory/ref_counted.h" |  | 
|   9 #include "gin/converter.h" |   8 #include "gin/converter.h" | 
|  10 #include "gin/public/wrapper_info.h" |   9 #include "gin/public/wrapper_info.h" | 
|  11  |  10  | 
|  12 namespace gin { |  11 namespace gin { | 
|  13  |  12  | 
|  14 // Wrappable is an abstract base class for C++ objects that have cooresponding |  13 // Wrappable is an abstract base class for C++ objects that have cooresponding | 
|  15 // v8 wrapper objects. Wrappable are RefCounted, which means they can be |  14 // v8 wrapper objects. To retain a Wrappable object on the stack, use a | 
|  16 // retained either by V8's garbage collector or by a scoped_refptr. |  15 // gin::Handle. | 
|  17 // |  16 class Wrappable { | 
|  18 // WARNING: If you retain a Wrappable object with a scoped_refptr, it's possible |  | 
|  19 //          that the v8 wrapper can "fall off" if the wrapper object is not |  | 
|  20 //          referenced elsewhere in the V8 heap. Although Wrappable opens a |  | 
|  21 //          handle to the wrapper object, we make that handle as weak, which |  | 
|  22 //          means V8 is free to reclaim the wrapper. (We can't make the handle |  | 
|  23 //          strong without risking introducing a memory leak if an object that |  | 
|  24 //          holds a scoped_refptr is reachable from the wrapper.) |  | 
|  25 // |  | 
|  26 class Wrappable : public base::RefCounted<Wrappable> { |  | 
|  27  public: |  17  public: | 
|  28   // Subclasses must return the WrapperInfo object associated with the |  18   // Subclasses must return the WrapperInfo object associated with the | 
|  29   // v8::ObjectTemplate for their subclass. When creating a v8 wrapper for |  19   // v8::ObjectTemplate for their subclass. When creating a v8 wrapper for | 
|  30   // this object, we'll look up the appropriate v8::ObjectTemplate in the |  20   // this object, we'll look up the appropriate v8::ObjectTemplate in the | 
|  31   // PerIsolateData using this WrapperInfo pointer. |  21   // PerIsolateData using this WrapperInfo pointer. | 
|  32   virtual WrapperInfo* GetWrapperInfo() = 0; |  22   virtual WrapperInfo* GetWrapperInfo() = 0; | 
|  33  |  23  | 
|  34   // Subclasses much also contain a static member variable named |kWrapperInfo| |  24   // Subclasses much also contain a static member variable named |kWrapperInfo| | 
|  35   // of type WrapperInfo: |  25   // of type WrapperInfo: | 
|  36   // |  26   // | 
|  37   //   static WrapperInfo kWrapperInfo; |  27   //   static WrapperInfo kWrapperInfo; | 
|  38   // |  28   // | 
|  39   // If |obj| is a concrete instance of the subclass, then obj->GetWrapperInfo() |  29   // If |obj| is a concrete instance of the subclass, then obj->GetWrapperInfo() | 
|  40   // must return &kWrapperInfo. |  30   // must return &kWrapperInfo. | 
|  41   // |  31   // | 
|  42   // We use both the dynamic |GetWrapperInfo| function and the static |  32   // We use both the dynamic |GetWrapperInfo| function and the static | 
|  43   // |kWrapperInfo| member variable during wrapping and the unwrapping. During |  33   // |kWrapperInfo| member variable during wrapping and the unwrapping. During | 
|  44   // wrapping, we use GetWrapperInfo() to make sure we use the correct |  34   // wrapping, we use GetWrapperInfo() to make sure we use the correct | 
|  45   // v8::ObjectTemplate for the object regardless of the declared C++ type. |  35   // v8::ObjectTemplate for the object regardless of the declared C++ type. | 
|  46   // During unwrapping, we use the static member variable to prevent type errors |  36   // During unwrapping, we use the static member variable to prevent type errors | 
|  47   // during the downcast from Wrappable to the subclass. |  37   // during the downcast from Wrappable to the subclass. | 
|  48  |  38  | 
|  49   // Retrieve (or create) the v8 wrapper object cooresponding to this object. |  39   // Retrieve (or create) the v8 wrapper object cooresponding to this object. | 
|  50   // To customize the wrapper created for a subclass, override GetWrapperInfo() |  40   // To customize the wrapper created for a subclass, override GetWrapperInfo() | 
|  51   // instead of overriding this function. |  41   // instead of overriding this function. | 
|  52   v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate); |  42   v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate); | 
|  53  |  43  | 
 |  44   // Subclasses should have private constructors and expose a static Create | 
 |  45   // function that returns a gin::Handle. Forcing creators through this static | 
 |  46   // Create function will enforce that clients actually create a wrapper for | 
 |  47   // the object. If clients fail to create a wrapper for a wrappable object, | 
 |  48   // the object will leak because we use the weak callback from the wrapper | 
 |  49   // as the signal to delete the wrapped object. | 
 |  50  | 
|  54  protected: |  51  protected: | 
|  55   Wrappable(); |  52   Wrappable(); | 
|  56   virtual ~Wrappable(); |  53   virtual ~Wrappable(); | 
|  57  |  54  | 
|  58  private: |  55  private: | 
|  59   friend class base::RefCounted<Wrappable>; |  | 
|  60   friend struct Converter<Wrappable*>; |  56   friend struct Converter<Wrappable*>; | 
|  61  |  57  | 
|  62   static void WeakCallback( |  58   static void WeakCallback( | 
|  63       const v8::WeakCallbackData<v8::Object, Wrappable>& data); |  59       const v8::WeakCallbackData<v8::Object, Wrappable>& data); | 
|  64   v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); |  60   v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); | 
|  65  |  61  | 
|  66   v8::Persistent<v8::Object> wrapper_;  // Weak |  62   v8::Persistent<v8::Object> wrapper_;  // Weak | 
|  67  |  63  | 
|  68   DISALLOW_COPY_AND_ASSIGN(Wrappable); |  64   DISALLOW_COPY_AND_ASSIGN(Wrappable); | 
|  69 }; |  65 }; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  90     // wrapped object. |  86     // wrapped object. | 
|  91     // TODO(abarth): Support unwrapping to a base class. |  87     // TODO(abarth): Support unwrapping to a base class. | 
|  92     *out = static_cast<T*>(wrappable); |  88     *out = static_cast<T*>(wrappable); | 
|  93     return true; |  89     return true; | 
|  94   } |  90   } | 
|  95 }; |  91 }; | 
|  96  |  92  | 
|  97 }  // namespace gin |  93 }  // namespace gin | 
|  98  |  94  | 
|  99 #endif  // GIN_WRAPPABLE_H_ |  95 #endif  // GIN_WRAPPABLE_H_ | 
| OLD | NEW |