I've been playing with making something like secondlife, using Ogre  
(scenegraph) and v8. Here is one of the ogre classes (the vector3  
class) exposed as a javascript object. I believe it'll leak memory a  
bit - I plan on fixing with MakeWeak later on.

Might be a nice reference for someone.

Ben

#include <v8.h>
#include <Ogre.h>

#define V8CALLBACK(type, name)\
  v8::Handle<v8::Value> type ## _ ## name(const v8::Arguments& args)
#define V8_GETTER(type, property) \
   v8::Handle<v8::Value> type ## _get ##  
property(v8::Local<v8::String> property, const v8::AccessorInfo& args)
#define V8_SETTER(type, property) \
   void type ## _set ## property(v8::Local<v8::String> property,  
v8::Local<v8::Value> value, const v8::AccessorInfo& args)
#define V8INTERNAL(type)\
        (static_cast<type>(v8::Local<v8::External>::Cast(args.Holder()- 
 >GetInternalField(0))->Value()))
#define V8ARGUMENT(type, index)\
        (static_cast<type>(v8::Local<v8::External>::Cast(args[index]- 
 >ToObject()->GetInternalField(0))->Value()))
#define V8ARGUMENTTYPE(type, index)\
   ( \
     args[index]->IsObject() \
     && (args[index]->ToObject()->InternalFieldCount()==2) \
     && (*v8::String::Utf8Value(args[index]->ToObject()- 
 >GetInternalField(1)->ToString())==std::string(type))  \
   )

namespace JSVector{

   v8::Handle<v8::ObjectTemplate> instance_template;
   v8::Handle<v8::FunctionTemplate> function_template;

   V8CALLBACK(Vector,getDistance){
     if (!V8ARGUMENTTYPE("Vector", 0))
       return ThrowException(v8::String::New("Invalid argument"));

     return v8::Number::New(V8INTERNAL(Ogre::Vector3*)- 
 >distance(*V8ARGUMENT(Ogre::Vector3*, 0)));
   }

   V8CALLBACK(Vector,getLength){
     return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->length());
   }

   V8CALLBACK(Vector,getNormalized){
     return JSVector::New(V8INTERNAL(Ogre::Vector3*)->normalisedCopy());
   }

   V8_GETTER(Vector,x){
     return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->x);
   }

   V8_SETTER(Vector,x){
     V8INTERNAL(Ogre::Vector3*)->x = value->NumberValue();
   }

   V8_GETTER(Vector,y){
     return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->y);
   }

   V8_SETTER(Vector,y){
     V8INTERNAL(Ogre::Vector3*)->y = value->NumberValue();
   }

   V8_GETTER(Vector,z){
     return v8::Number::New(V8INTERNAL(Ogre::Vector3*)->z);
   }

   V8_SETTER(Vector,z){
     V8INTERNAL(Ogre::Vector3*)->z = value->NumberValue();
   }

   /* Sets internal fields with our idiom of storing the class name in  
the second field */
   void setInternalFields(v8::Persistent<v8::Object> p, Ogre::Vector3  
v){
     p->SetInternalField(0, v8::External::New(new  
Ogre::Vector3(v.ptr())));
     p->SetInternalField(1, v8::String::New("Vector"));
   }

   /* Construct a new vector */
   V8CALLBACK(Vector,create){
     if (!args.IsConstructCall())
       return ThrowException(v8::String::New("Cannot call constructor  
as function"));

     v8::Persistent<v8::Object> self =  
v8::Persistent<v8::Object>::New(args.Holder());
     setInternalFields(self, Ogre::Vector3::ZERO);

     return self;
   }

   /* Only called from c++ */
   v8::Handle<v8::Value> New(Ogre::Vector3 v){
     v8::Persistent<v8::Object> instance =  
v8::Persistent<v8::Object>::New(function_template->GetFunction()- 
 >NewInstance());
     setInternalFields(instance, v);
     return instance;
   }

   /* Create the function and instance templates and register the  
Vector constructor */

   void Initialize(v8::Handle<v8::ObjectTemplate> global){
     // Function Template
     function_template = v8::FunctionTemplate::New(Vector_create);
     function_template->SetClassName(v8::String::New("Vector"));

     // Instance template
     instance_template = function_template->InstanceTemplate();
     instance_template->SetInternalFieldCount(2);

     instance_template->SetAccessor(v8::String::New("x"), Vector_getx,  
Vector_setx);
     instance_template->SetAccessor(v8::String::New("y"), Vector_gety,  
Vector_sety);
     instance_template->SetAccessor(v8::String::New("z"), Vector_getz,  
Vector_setz);
     instance_template->Set("getDistance",  
v8::FunctionTemplate::New(Vector_getDistance));
     instance_template->Set("getLength",  
v8::FunctionTemplate::New(Vector_getLength));
     instance_template->Set("getNormalized",  
v8::FunctionTemplate::New(Vector_getNormalized));

     global->Set(v8::String::New("Vector"), function_template); // add  
our Point object
   }

}

--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to