// 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_WRAPPABLE_H_ #define GIN_WRAPPABLE_H_ #include "base/template_util.h" #include "gin/converter.h" #include "gin/gin_export.h" #include "gin/public/wrapper_info.h" namespace gin { namespace internal { GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate, v8::Handle val, WrapperInfo* info); } // namespace internal // Wrappable is a base class for C++ objects that have corresponding v8 wrapper // objects. To retain a Wrappable object on the stack, use a gin::Handle. // // USAGE: // // my_class.h // class MyClass : Wrappable { // ... // }; // // // my_class.cc // INIT_WRAPABLE(MyClass); // // Subclasses should also typically have private constructors and expose a // static Create function that returns a gin::Handle. Forcing creators through // this static Create function will enforce that clients actually create a // wrapper for the object. If clients fail to create a wrapper for a wrappable // object, the object will leak because we use the weak callback from the // wrapper as the signal to delete the wrapped object. template class Wrappable; // Non-template base class to share code between templates instances. class GIN_EXPORT WrappableBase { protected: WrappableBase(); virtual ~WrappableBase(); v8::Handle GetWrapperImpl(v8::Isolate* isolate, WrapperInfo* wrapper_info); v8::Handle CreateWrapper(v8::Isolate* isolate, WrapperInfo* wrapper_info); v8::Persistent wrapper_; // Weak private: static void WeakCallback( const v8::WeakCallbackData& data); DISALLOW_COPY_AND_ASSIGN(WrappableBase); }; template class Wrappable : public WrappableBase { public: // Retrieve (or create) the v8 wrapper object cooresponding to this object. // To customize the wrapper created for a subclass, override GetWrapperInfo() // instead of overriding this function. v8::Handle GetWrapper(v8::Isolate* isolate) { return GetWrapperImpl(isolate, &T::kWrapperInfo); } protected: Wrappable() {} virtual ~Wrappable() {} private: DISALLOW_COPY_AND_ASSIGN(Wrappable); }; // This converter handles any subclass of Wrappable. template struct Converter*>::value>::type> { static v8::Handle ToV8(v8::Isolate* isolate, T* val) { return val->GetWrapper(isolate); } static bool FromV8(v8::Isolate* isolate, v8::Handle val, T** out) { *out = static_cast(internal::FromV8Impl(isolate, val, &T::kWrapperInfo)); return *out != NULL; } }; } // namespace gin #endif // GIN_WRAPPABLE_H_