Fix closure compile through a series of stupid hacks
[chromium-blink-merge.git] / gin / wrappable.h
blobf7d82b0d5a71953cdc84ecec013d9094d5237848
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
3 // found in the LICENSE file.
5 #ifndef GIN_WRAPPABLE_H_
6 #define GIN_WRAPPABLE_H_
8 #include "base/template_util.h"
9 #include "gin/converter.h"
10 #include "gin/gin_export.h"
11 #include "gin/public/wrapper_info.h"
13 namespace gin {
15 // Wrappable is a base class for C++ objects that have corresponding v8 wrapper
16 // objects. To retain a Wrappable object on the stack, use a gin::Handle.
18 // USAGE:
19 // // my_class.h
20 // class MyClass : Wrappable<MyClass> {
21 // public:
22 // static WrapperInfo kWrapperInfo;
24 // // Optional, only required if non-empty template should be used.
25 // virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
26 // v8::Isolate* isolate);
27 // ...
28 // };
30 // // my_class.cc
31 // WrapperInfo MyClass::kWrapperInfo = {kEmbedderNativeGin};
33 // gin::ObjectTemplateBuilder MyClass::GetObjectTemplateBuilder(
34 // v8::Isolate* isolate) {
35 // return Wrappable<MyClass>::GetObjectTemplateBuilder(isolate)
36 // .SetValue("foobar", 42);
37 // }
39 // Subclasses should also typically have private constructors and expose a
40 // static Create function that returns a gin::Handle. Forcing creators through
41 // this static Create function will enforce that clients actually create a
42 // wrapper for the object. If clients fail to create a wrapper for a wrappable
43 // object, the object will leak because we use the weak callback from the
44 // wrapper as the signal to delete the wrapped object.
46 // Wrappable<T> explicitly does not support further subclassing of T.
47 // Subclasses of Wrappable<T> should be declared final. Because Wrappable<T>
48 // caches the object template using &T::kWrapperInfo as the key, all subclasses
49 // would share a single object template. This will lead to hard to debug crashes
50 // that look like use-after-free errors.
52 namespace internal {
54 GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
55 v8::Local<v8::Value> val,
56 WrapperInfo* info);
58 } // namespace internal
60 class ObjectTemplateBuilder;
62 // Non-template base class to share code between templates instances.
63 class GIN_EXPORT WrappableBase {
64 protected:
65 WrappableBase();
66 virtual ~WrappableBase();
68 // Overrides of this method should be declared final and not overridden again.
69 virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
71 v8::Local<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
72 WrapperInfo* wrapper_info);
74 private:
75 static void FirstWeakCallback(
76 const v8::WeakCallbackInfo<WrappableBase>& data);
77 static void SecondWeakCallback(
78 const v8::WeakCallbackInfo<WrappableBase>& data);
80 v8::Global<v8::Object> wrapper_; // Weak
82 DISALLOW_COPY_AND_ASSIGN(WrappableBase);
86 template<typename T>
87 class Wrappable : public WrappableBase {
88 public:
89 // Retrieve (or create) the v8 wrapper object cooresponding to this object.
90 v8::Local<v8::Object> GetWrapper(v8::Isolate* isolate) {
91 return GetWrapperImpl(isolate, &T::kWrapperInfo);
94 protected:
95 Wrappable() {}
96 virtual ~Wrappable() {}
98 private:
99 DISALLOW_COPY_AND_ASSIGN(Wrappable);
103 // This converter handles any subclass of Wrappable.
104 template<typename T>
105 struct Converter<T*, typename base::enable_if<
106 base::is_convertible<T*, WrappableBase*>::value>::type> {
107 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
108 return val->GetWrapper(isolate);
111 static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, T** out) {
112 *out = static_cast<T*>(static_cast<WrappableBase*>(
113 internal::FromV8Impl(isolate, val, &T::kWrapperInfo)));
114 return *out != NULL;
118 } // namespace gin
120 #endif // GIN_WRAPPABLE_H_