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.&nbsp;
	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;
}

Attachment: test.js
Description: JavaScript source

Reply via email to