blob: ff52b19a06f57c2d930efbfa149a8f03897f9fe3 [file] [log] [blame]
[email protected]93f9f3602013-11-21 18:38:511// 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.
4
5#ifndef GIN_WRAPPABLE_H_
6#define GIN_WRAPPABLE_H_
7
[email protected]cf76c84a2013-12-06 14:07:078#include "base/template_util.h"
[email protected]93f9f3602013-11-21 18:38:519#include "gin/converter.h"
[email protected]48c21632013-12-12 21:32:3410#include "gin/gin_export.h"
[email protected]93f9f3602013-11-21 18:38:5111#include "gin/public/wrapper_info.h"
12
13namespace gin {
14
[email protected]6fe56102013-12-08 07:10:5815namespace internal {
[email protected]93f9f3602013-11-21 18:38:5116
[email protected]48c21632013-12-12 21:32:3417GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
18 v8::Handle<v8::Value> val,
19 WrapperInfo* info);
[email protected]6fe56102013-12-08 07:10:5820
21} // namespace internal
22
23
24// Wrappable is a base class for C++ objects that have corresponding v8 wrapper
25// objects. To retain a Wrappable object on the stack, use a gin::Handle.
26//
27// USAGE:
28// // my_class.h
29// class MyClass : Wrappable<MyClass> {
[email protected]cb6c2bb2013-12-17 21:47:0430// public:
31// static WrapperInfo kWrapperInfo;
32//
33// // Optional, only required if non-empty template should be used.
[email protected]75a20902013-12-19 15:18:0434// virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
[email protected]cb6c2bb2013-12-17 21:47:0435// v8::Isolate* isolate);
[email protected]6fe56102013-12-08 07:10:5836// ...
37// };
38//
39// // my_class.cc
[email protected]75a20902013-12-19 15:18:0440// WrapperInfo MyClass::kWrapperInfo = {kEmbedderNativeGin};
[email protected]cb6c2bb2013-12-17 21:47:0441//
[email protected]75a20902013-12-19 15:18:0442// gin::ObjectTemplateBuilder MyClass::GetObjectTemplateBuilder(
[email protected]cb6c2bb2013-12-17 21:47:0443// v8::Isolate* isolate) {
[email protected]75a20902013-12-19 15:18:0444// return Wrappable<MyClass>::GetObjectTemplateBuilder(isolate)
45// .SetValue("foobar", 42);
[email protected]cb6c2bb2013-12-17 21:47:0446// }
[email protected]6fe56102013-12-08 07:10:5847//
48// Subclasses should also typically have private constructors and expose a
49// static Create function that returns a gin::Handle. Forcing creators through
50// this static Create function will enforce that clients actually create a
51// wrapper for the object. If clients fail to create a wrapper for a wrappable
52// object, the object will leak because we use the weak callback from the
53// wrapper as the signal to delete the wrapped object.
54template<typename T>
55class Wrappable;
56
[email protected]13c977e62013-12-19 00:52:4457class ObjectTemplateBuilder;
[email protected]6fe56102013-12-08 07:10:5858
59// Non-template base class to share code between templates instances.
[email protected]48c21632013-12-12 21:32:3460class GIN_EXPORT WrappableBase {
[email protected]6fe56102013-12-08 07:10:5861 protected:
62 WrappableBase();
[email protected]695af7f52013-12-11 19:41:0163 virtual ~WrappableBase();
[email protected]cb6c2bb2013-12-17 21:47:0464
[email protected]13c977e62013-12-19 00:52:4465 virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
[email protected]cb6c2bb2013-12-17 21:47:0466
[email protected]13c977e62013-12-19 00:52:4467 v8::Handle<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
68 WrapperInfo* wrapper_info);
[email protected]6fe56102013-12-08 07:10:5869
70 private:
71 static void WeakCallback(
72 const v8::WeakCallbackData<v8::Object, WrappableBase>& data);
73
[email protected]cb6c2bb2013-12-17 21:47:0474 v8::Persistent<v8::Object> wrapper_; // Weak
75
[email protected]6fe56102013-12-08 07:10:5876 DISALLOW_COPY_AND_ASSIGN(WrappableBase);
77};
78
79
80template<typename T>
81class Wrappable : public WrappableBase {
82 public:
[email protected]60531d52013-11-27 02:10:1583 // Retrieve (or create) the v8 wrapper object cooresponding to this object.
84 // To customize the wrapper created for a subclass, override GetWrapperInfo()
85 // instead of overriding this function.
[email protected]6fe56102013-12-08 07:10:5886 v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate) {
[email protected]13c977e62013-12-19 00:52:4487 return GetWrapperImpl(isolate, &T::kWrapperInfo);
[email protected]6fe56102013-12-08 07:10:5888 }
[email protected]d379b0c2013-12-05 05:48:0189
[email protected]93f9f3602013-11-21 18:38:5190 protected:
[email protected]6fe56102013-12-08 07:10:5891 Wrappable() {}
[email protected]695af7f52013-12-11 19:41:0192 virtual ~Wrappable() {}
93
94 private:
[email protected]93f9f3602013-11-21 18:38:5195 DISALLOW_COPY_AND_ASSIGN(Wrappable);
96};
97
[email protected]6fe56102013-12-08 07:10:5898
[email protected]cf76c84a2013-12-06 14:07:0799// This converter handles any subclass of Wrappable.
[email protected]93f9f3602013-11-21 18:38:51100template<typename T>
[email protected]cf76c84a2013-12-06 14:07:07101struct Converter<T*, typename base::enable_if<
[email protected]13c977e62013-12-19 00:52:44102 base::is_convertible<T*, WrappableBase*>::value>::type> {
[email protected]93f9f3602013-11-21 18:38:51103 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
[email protected]cf76c84a2013-12-06 14:07:07104 return val->GetWrapper(isolate);
[email protected]93f9f3602013-11-21 18:38:51105 }
[email protected]cf76c84a2013-12-06 14:07:07106
[email protected]7618ebbb2013-11-27 03:38:26107 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, T** out) {
[email protected]75a20902013-12-19 15:18:04108 *out = static_cast<T*>(static_cast<WrappableBase*>(
109 internal::FromV8Impl(isolate, val, &T::kWrapperInfo)));
[email protected]6fe56102013-12-08 07:10:58110 return *out != NULL;
[email protected]93f9f3602013-11-21 18:38:51111 }
112};
113
114} // namespace gin
115
116#endif // GIN_WRAPPABLE_H_