| // Copyright (c) 2010 The Chromium OS 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 ENTD_JS_OBJECT_WRAPPER_H_ |
| #define ENTD_JS_OBJECT_WRAPPER_H_ |
| |
| #include <string> |
| #include <v8.h> |
| #include <base/basictypes.h> |
| |
| #include "entd/utils.h" |
| |
| namespace entd { |
| |
| // Template class to bind a C++ object to a V8 object. |
| // The class builds a single global Persistent template object and |
| // reserves a single internal field to hold a pointer to the C++ object. |
| // Each C++ object constructs a V8 object and binds itself to it. |
| // Additional bindings happen in SetTemplateBindings(). |
| // |
| // NOTE: This uses the "curiously recurring template pattern" |
| // to implement singleton behavior for function templates. |
| // |
| // Example usage: |
| // class JSSyslog : public JSObjectWrapper<JSSyslog> |
| // { |
| // }; |
| |
| template<typename T> |
| class JSObjectWrapper { |
| public: |
| virtual ~JSObjectWrapper() { |
| obj_.Dispose(); |
| } |
| |
| // JS Object instance management... |
| |
| // Make sure to call JSObjectWrapper<Foo>::Initialize() if overridden by Foo |
| virtual bool Initialize(); |
| |
| // Builds an instance and passes args to ParseConstructorArgs() |
| static v8::Handle<v8::Value> Construct(const v8::Arguments& args); |
| |
| // Subclasses can override this function to parse constructor arguments. |
| // Throw a v8 exception AND return false to indicate a failure, in which |
| // case the newly constructed object will be deleted. |
| virtual bool ParseConstructorArgs(v8::Handle<v8::Object> obj, |
| const v8::Arguments& args) { |
| return true; |
| } |
| |
| // Extract the C++ object pointer from the V8 object internal field 0 |
| static T* Unwrap(v8::Handle<v8::Object> obj); |
| |
| // Unwrap the C++ object pointer from args[index] |
| static T* GetFromArg(const v8::Arguments& args, int index); |
| |
| // JS Function Template management... |
| |
| // GetClassName() must be defined for the derived class: |
| // static const char* GetClassName() { return "foo"; } |
| |
| // Return the V8 template. ManageTemplete will build it if necessary. |
| // Define SetTemplateBindings() to bind JS methods to C++ (see below) |
| static v8::Handle<v8::FunctionTemplate> GetTemplate() { |
| return ManageTemplate(true); |
| } |
| |
| // Call ManageTemplate() with 'false' to destroy the template |
| static void CleanupTemplate() { |
| ManageTemplate(false); |
| } |
| |
| // Accessors |
| v8::Handle<v8::Object> obj() const { return obj_; } |
| |
| private: |
| |
| // ManageTemplate handles construction and destruction of a |
| // singleton function template instance. |
| // |
| // If build is true, construct the template object if necessary, otherwise |
| // dispose of the template if it exists. |
| // |
| // Returns the function template handle (undefined if build is false) |
| static v8::Handle<v8::FunctionTemplate> ManageTemplate(bool build); |
| |
| // Override this to bind methods or data to the template. e.g.: |
| // tmpl_obj->Set(String::New("bar"), FunctionTemplate::New(dispatch_Bar)); |
| static void SetTemplateBindings(v8::Handle<v8::ObjectTemplate> tmpl_obj) {} |
| |
| // V8 Object bound to this C++ instance |
| v8::Persistent<v8::Object> obj_; |
| }; |
| |
| #include "entd/js_object_wrapper-inl.h" |
| |
| } // namespace entd |
| |
| #endif // ENTD_JS_OBJECT_WRAPPER_ |