blob: 3c2ed5f7def52eff69a764b5778bde5e421b30db [file] [log] [blame]
// 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_