handle.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef GIN_HANDLE_H_
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define GIN_HANDLE_H_
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/converter.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace gin {
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// You can use gin::Handle on the stack to retain a gin::Wrappable object.
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Currently we don't have a mechanism for retaining a gin::Wrappable object
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// in the C++ heap because strong references from C++ to V8 can cause memory
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// leaks.
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template<typename T>
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class Handle {
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Handle() : object_(NULL) {}
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Handle(v8::Handle<v8::Value> wrapper, T* object)
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : wrapper_(wrapper),
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      object_(object) {
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool IsEmpty() const { return !object_; }
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Clear() {
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapper_.Clear();
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    object_ = NULL;
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  T* operator->() const { return object_; }
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Handle<v8::Value> ToV8() const { return wrapper_; }
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  T* get() const { return object_; }
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  v8::Handle<v8::Value> wrapper_;
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  T* object_;
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template<typename T>
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct Converter<gin::Handle<T> > {
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    const gin::Handle<T>& val) {
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return val.ToV8();
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     gin::Handle<T>* out) {
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    T* object = NULL;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!Converter<T*>::FromV8(isolate, val, &object)) {
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *out = gin::Handle<T>(val, object);
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This function is a convenient way to create a handle from a raw pointer
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// without having to write out the type of the object explicitly.
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template<typename T>
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gin::Handle<T> CreateHandle(v8::Isolate* isolate, T* object) {
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return gin::Handle<T>(object->GetWrapper(isolate), object);
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace gin
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // GIN_HANDLE_H_
69