| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef GIN_HANDLE_H_ |
| #define GIN_HANDLE_H_ |
| |
| #include "gin/converter.h" |
| |
| namespace gin { |
| |
| // You can use gin::Handle on the stack to retain a gin::Wrappable object. |
| // Currently we don't have a mechanism for retaining a gin::Wrappable object |
| // in the C++ heap because strong references from C++ to V8 can cause memory |
| // leaks. |
| template<typename T> |
| class Handle { |
| public: |
| Handle() : object_(NULL) {} |
| |
| Handle(v8::Local<v8::Value> wrapper, T* object) |
| : wrapper_(wrapper), |
| object_(object) { |
| } |
| |
| bool IsEmpty() const { return !object_; } |
| |
| void Clear() { |
| wrapper_.Clear(); |
| object_ = NULL; |
| } |
| |
| T* operator->() const { return object_; } |
| v8::Local<v8::Value> ToV8() const { return wrapper_; } |
| T* get() const { return object_; } |
| |
| private: |
| v8::Local<v8::Value> wrapper_; |
| T* object_; |
| }; |
| |
| template<typename T> |
| struct Converter<gin::Handle<T> > { |
| static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, |
| const gin::Handle<T>& val) { |
| return val.ToV8(); |
| } |
| static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, |
| gin::Handle<T>* out) { |
| T* object = NULL; |
| if (!Converter<T*>::FromV8(isolate, val, &object)) { |
| return false; |
| } |
| *out = gin::Handle<T>(val, object); |
| return true; |
| } |
| }; |
| |
| // This function is a convenient way to create a handle from a raw pointer |
| // without having to write out the type of the object explicitly. |
| template<typename T> |
| gin::Handle<T> CreateHandle(v8::Isolate* isolate, T* object) { |
| v8::Local<v8::Object> wrapper = object->GetWrapper(isolate); |
| if (wrapper.IsEmpty()) |
| return gin::Handle<T>(); |
| return gin::Handle<T>(wrapper, object); |
| } |
| |
| } // namespace gin |
| |
| #endif // GIN_HANDLE_H_ |