blob: c111c5b32c7cddbc2c4827b585fc47c9aeee28e5 [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_INL_H_
#define ENTD_JS_OBJECT_WRAPPER_INL_H_
// virtual
template<typename T>
bool JSObjectWrapper<T>::Initialize() {
// Get the template, building it if necessary.
v8::Handle<v8::FunctionTemplate> t = GetTemplate();
// Create a v8 Object from the template.
obj_ = v8::Persistent<v8::Object>::New(t->GetFunction()->NewInstance());
// Associate it with the C++ Object.
obj_->SetPointerInInternalField(0, this);
return true;
}
// static
template<typename T>
v8::Handle<v8::Value> JSObjectWrapper<T>::Construct(
const v8::Arguments& args) {
if (!args.IsConstructCall()) {
utils::ThrowV8Exception(std::string(T::GetClassName())
+ " must be called as a constructor.");
return v8::Undefined();
}
T* instance = new T();
instance->Initialize();
v8::Handle<v8::Object> obj = instance->obj();
if (!instance->ParseConstructorArgs(obj, args)) {
// TODO(rginda): Remove this delete after we sort out a proper ownership
// model for these JSObjectWrapper objects.
delete instance;
return v8::Undefined();
}
return obj;
}
// static
template<typename T>
T* JSObjectWrapper<T>::Unwrap(v8::Handle<v8::Object> obj) {
// Make sure the argument is valid
if (obj.IsEmpty() || !obj->IsObject())
return NULL;
// Make sure it's of the right type
if (!T::GetTemplate()->HasInstance(obj))
return NULL;
// Paranoia; Should always be true
if (obj->InternalFieldCount() < 1)
return NULL;
T* result = reinterpret_cast<T*>(obj->GetPointerFromInternalField(0));
return result;
}
// static
template<typename T>
T* JSObjectWrapper<T>::GetFromArg(const v8::Arguments& args, int index) {
T* result = NULL;
if (args.Length() > index) {
// Unwrap checks that the argument is really an object
result = Unwrap(v8::Handle<v8::Object>::Cast(args[index]));
}
return result;
}
// static
template<typename T>
v8::Handle<v8::FunctionTemplate> JSObjectWrapper<T>::ManageTemplate(
bool build) {
// Store the template as a static function variable
// This avoids the awkwardness of dealing with static template members
static v8::Persistent<v8::FunctionTemplate> s_template;
// Build the templete if necessary
if (build && s_template.IsEmpty()) {
v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
s_template = v8::Persistent<v8::FunctionTemplate>::New(ft);
s_template->SetClassName(v8::String::New(T::GetClassName()));
v8::Handle<v8::ObjectTemplate> template_object =
s_template->InstanceTemplate();
template_object->SetInternalFieldCount(1);
T::SetTemplateBindings(template_object);
} else if (!build && !s_template.IsEmpty()) {
s_template.Dispose();
}
return s_template;
}
#endif // ENTD_JS_OBJECT_WRAPPER_INL_H_