// Copyright 2014 Cheng Zhao. All rights reserved. // Use of this source code is governed by MIT license that can be found in the // LICENSE file. #ifndef NATIVE_MATE_SCOPED_PERSISTENT_H_ #define NATIVE_MATE_SCOPED_PERSISTENT_H_ #include "base/memory/ref_counted.h" #include "native_mate/converter.h" #include "v8/include/v8.h" namespace mate { // A v8::Persistent handle to a V8 value which destroys and clears the // underlying handle on destruction. template class ScopedPersistent { public: ScopedPersistent() : isolate_(v8::Isolate::GetCurrent()) {} ScopedPersistent(v8::Isolate* isolate, v8::Local handle) : isolate_(isolate) { reset(isolate, v8::Local::Cast(handle)); } ~ScopedPersistent() { reset(); } void reset(v8::Isolate* isolate, v8::Local handle) { if (!handle.IsEmpty()) { isolate_ = isolate; handle_.Reset(isolate, handle); } else { reset(); } } void reset() { handle_.Reset(); } bool IsEmpty() const { return handle_.IsEmpty(); } v8::Local NewHandle() const { return NewHandle(isolate_); } v8::Local NewHandle(v8::Isolate* isolate) const { if (handle_.IsEmpty()) return v8::Local(); return v8::Local::New(isolate, handle_); } template void SetWeak(P* parameter, C callback) { handle_.SetWeak(parameter, callback); } v8::Isolate* isolate() const { return isolate_; } private: v8::Isolate* isolate_; v8::Persistent handle_; DISALLOW_COPY_AND_ASSIGN(ScopedPersistent); }; template class RefCountedPersistent : public ScopedPersistent, public base::RefCounted> { public: RefCountedPersistent() {} RefCountedPersistent(v8::Isolate* isolate, v8::Local handle) : ScopedPersistent(isolate, handle) { } protected: friend class base::RefCounted>; ~RefCountedPersistent() {} private: DISALLOW_COPY_AND_ASSIGN(RefCountedPersistent); }; template struct Converter > { static v8::Local ToV8(v8::Isolate* isolate, const ScopedPersistent& val) { return val.NewHandle(isolate); } static bool FromV8(v8::Isolate* isolate, v8::Local val, ScopedPersistent* out) { v8::Local converted; if (!Converter >::FromV8(isolate, val, &converted)) return false; out->reset(isolate, converted); return true; } }; } // namespace mate #endif // NATIVE_MATE_SCOPED_PERSISTENT_H_