vlad,
I think the attached example is what you want. But, I can't say if
it's the "proper" way as I'm still learning the api. This was just
one of my test files.
-august.
>
> Is there anyone out there that knows how to do this, or if this is
> even possible?
>
> > Hi,
> >
> > I've been trying to add static variables getter/setter to function
> > templates, but have not found the proper way to do it.
> > I have successfully added instance getters/setters and instance
> > variable callbacks. Also, I was able to get the static function calls
> > working.
> >
> > Let's assume class Foo;
> >
> > // I have successfully installed C++ callbacks for objects in the
> > following statements:
> > var f = new Foo;
> > f.someVar = x;
> > var y = f.someVar;
> > f.bar();
> > Foo.staticCall();
> >
> > But I have not been able to do this:
> > Foo.staticVariable = x;
> > var y = Foo.staticVariable;
> >
> > I've been looking all day at v8.h,, process.cc, this mailing list, but
> > have not found the proper code snippets to make it happen.
> >
--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---
#include <v8.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace v8;
using namespace std;
class CppObject {
public:
CppObject(): x_(0), y_(0), text_("hello") { }
~CppObject() {};
void SetText( string str) { text_ = str;};
void SetPosition( int X, int Y) {x_=X;y_=Y; printDetails();};
void printDetails() { cout << "text: " << text_ << endl << "x,y: " << x_ << "," << y_ << endl;};
int x_;
int y_;
string text_;
};
Handle<Value> GetPointX(Local<String> property,
const AccessorInfo &info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
int value = static_cast<CppObject*>(ptr)->x_;
return Integer::New(value);
}
void SetPointX(Local<String> property, Local<Value> value,
const AccessorInfo& info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<CppObject*>(ptr)->x_ = value->Int32Value();
}
Handle<Value> GetPointY(Local<String> property,
const AccessorInfo &info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
int value = static_cast<CppObject*>(ptr)->y_;
return Integer::New(value);
}
void SetPointY(Local<String> property, Local<Value> value,
const AccessorInfo& info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<CppObject*>(ptr)->y_ = value->Int32Value();
}
string ObjectToString(Local<Value> value) {
String::Utf8Value utf8_value(value);
return string(*utf8_value);
}
Handle<Value> GetText(Local<String> property,
const AccessorInfo &info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
string value = static_cast<CppObject*>(ptr)->text_;
return String::New(value.c_str(), value.length());
}
void SetText(Local<String> property, Local<Value> value,
const AccessorInfo& info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<CppObject*>(ptr)->text_ = ObjectToString(value);
}
Handle<Value> ObjMethod_SetPosition(const Arguments& args)
{
Handle<Value> result;
Local<Object> self = args.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<CppObject*>(ptr)->SetPosition( (args[0])->Int32Value(), (args[1])->Int32Value() );
return result;
}
// Called when the js CppObject object is being garbage collected
// delete the C++ object and ClearWeak on the Persistent handle,
// as is done in the v8 tests.
void CppObject_Destroy(Persistent<Value> self, void* parameter)
{
delete static_cast<CppObject*>(parameter);
self.ClearWeak();
//--g_instances;
}
// js Point constructor function, called when you `new Point(...)' in js
Handle<Value> CppObject_Create(const Arguments& args)
{
// throw if called without `new'
if (!args.IsConstructCall())
return ThrowException(String::New("Cannot call constructor as function"));
// throw if we didn't get 2 args
//if (args.Length() != 2)
// return ThrowException(String::New("Expected two integer arguments"));
// create the C++ Point to be wrapped
CppObject* cppobj = new CppObject();
if (args.Length() > 0)
cppobj->x_ = args[0]->Int32Value();
if (args.Length() > 1)
cppobj->y_ = args[1]->Int32Value();
if (args.Length() > 2)
cppobj->text_ = ObjectToString(args[2]);
// make a persistant handle for the instance and make it
// weak so we get a callback when it is garbage collected
Persistent<Object> self = Persistent<Object>::New(args.Holder());
self.MakeWeak( cppobj, CppObject_Destroy );
// set internal field to the C++ point
self->SetInternalField(0, External::New(cppobj));
//++g_instances;
return self;
}
// Read a file into a v8 String.
// Should be called from within a HandleScope
Handle<String> ReadFile(const char* filename)
{
ifstream fin(filename);
if (!fin) {
return Handle<String>();
}
ostringstream os;
os << fin.rdbuf();
return String::New(os.str().c_str());
}
int main(int argc, char* argv[]) {
if (argc < 2) {
cout << "usage: "<< argv[0] << " file.js" << endl;
return 1;
}
// Create a stack-allocated handle scope.
HandleScope handle_scope;
Handle<FunctionTemplate> func_templ = FunctionTemplate::New( CppObject_Create );
func_templ->SetClassName(String::New("CppObject"));
//Handle<ObjectTemplate> func_proto = func_templ->PrototypeTemplate();
//func_proto->SetAccessor(String::New("x"), GetPointX, SetPointX);
//func_proto->SetAccessor(String::New("y"), GetPointY, SetPointY);
//func_proto->SetAccessor(String::New("text"), GetText, SetText);
Handle<ObjectTemplate> func_inst = func_templ->InstanceTemplate();
func_inst->SetInternalFieldCount(1);
func_inst->SetAccessor(String::New("x"), GetPointX, SetPointX);
func_inst->SetAccessor(String::New("y"), GetPointY, SetPointY);
func_inst->SetAccessor(String::New("text"), GetText, SetText);
func_inst->Set("SetPosition", FunctionTemplate::New(ObjMethod_SetPosition));
// the global object template
Handle<ObjectTemplate> globals = ObjectTemplate::New();
globals->Set(String::New("CppObject"), func_templ);
// Create a new context.
Persistent<Context> context = Context::New(0, globals);
// Enter the created context for compiling and
// running the hello world script.
Context::Scope context_scope(context);
// Create a string containing the JavaScript source code.
//Handle<String> source = String::New("co = new CppImage(); co.x = 5;");
Handle<String> source = ReadFile( argv[1] );
// Compile the source code.
Handle<Script> script = Script::Compile(source);
// Run the script to get the result.
cout << "about to run" << endl;
Handle<Value> result = script->Run();
cout << "run ranit" << endl;
// Dispose the persistent context.
context.Dispose();
// Convert the result to an ASCII string and print it.
String::AsciiValue ascii(result);
printf("%s\n", *ascii);
return 0;
}
test.js
Description: JavaScript source
