我目前正在用 C++ 编写一个 Node 插件,我遇到了一个问题,我需要创建并返回一个 v8 数组,其中填充了 v8 包装的 C++ 对象实例。
目前,代码看起来像这样
v8::Handle<v8::Value> Controller::nodeArray(const v8::Arguments& args)
{
v8::HandleScope scope;
Controller* controller= ObjectWrap::Unwrap<Controller>(args.This());
const std::vector<Foobar*>* foobars = controller->getFoobars();
unsigned int foobarCount = foobars->size();
v8::Handle<v8::Array> foobarsArray = v8::Array::New(foobarCount);
std::vector<Foobar*>::const_iterator foobar = foobars->begin();
for(unsigned int i = 0; i < foobarCount; i++)
{
// Need to create a v8 Object that wraps a single instance of a
// Foobar object in "foobars"
// Then push the object to the v8 Array?
// foobarsArray->Set(i, [some Foobar instance]);
snake++;
}
return foobarsArray;
}
但是,我在for
循环中尝试了几种不同的方法,但均无济于事。我应该怎么做呢?
Foobar 和 SuperFoo
以下是 中定义的Init
初始化程序和nodeNew
构造函数Foobar
,以及 和 的头Foobar
文件SuperFoo
。
#define BUILDING_NODE_EXTENSION
#ifndef FOOBAR_H_
#define FOOBAR_H_
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <node.h>
#include <string>
#include <vector>
#include <iostream>
#include "EnvironmentObject.h"
#include "SuperFoo.h"
#include "Grid.h"
#include "GridSection.h"
#include "Point.h"
#include "Teams.h"
#include "Vector.h"
class SuperFoo;
class Grid;
class Foobar : public SuperFoo
{
public:
Foobar();
virtual ~Foobar();
Foobar(int id, const Point& location, const int& team, const Grid& world);
Foobar(const Foobar& snake);
// Node Implementation
static void Init(v8::Handle<v8::Object> target);
private:
// Node Implementation
static v8::Handle<v8::Value> nodeNew(const v8::Arguments& args);
static v8::Handle<v8::Value> nodeGetID(const v8::Arguments& args);
static v8::Handle<v8::Value> nodeGetTeam(const v8::Arguments& args);
static v8::Handle<v8::Value> nodeGetState(const v8::Arguments& args);
static v8::Handle<v8::Value> nodeGetVelocity(const v8::Arguments& args);
int id_;
int team_;
int state_;
Vector* velocity_;
const Grid* world_;
};
#endif /* FOOBAR_H_ */
#define BUILDING_NODE_EXTENSION
#ifndef GAMEOBJECT_H_
#define GAMEOBJECT_H_
#include <string>
#include <node.h>
#include "Point.h"
#include "Vector.h"
class SuperFoo : public node::ObjectWrap
{
public:
SuperFoo()
: collidable_(true), stationary_(true) {}
virtual ~SuperFoo();
SuperFoo(const std::string& type, const Point& position);
SuperFoo(const SuperFoo& object);
virtual bool collide(SuperFoo& object) = 0;
Point getPosition() const;
std::string getType() const;
void setPosition(const Point& position);
bool isCollidable() const;
bool isStationary() const;
void setCollidable(bool coolide);
void setStationary(bool stationary);
protected:
Point* position_;
private:
// Node Implementation
static v8::Handle<v8::Value> nodeGetPosition(const v8::Arguments& args);
std::string* type_;
bool collidable_;
bool stationary_;
};
#endif /* SUPERFOO_H_ */
void Foobar::Init(v8::Handle<v8::Object> target)
{
// Prepare constructor template
v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(nodeNew);
tpl->SetClassName(v8::String::NewSymbol("Foobar"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prototype functions
tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("getID"), v8::FunctionTemplate::New(nodeGetID)->GetFunction());
tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("getVelocity"), v8::FunctionTemplate::New(nodeGetVelocity)->GetFunction());
tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("getState"), v8::FunctionTemplate::New(nodeGetState)->GetFunction());
v8::Persistent<v8::Function> constructor = v8::Persistent<v8::Function>::New(tpl->GetFunction());
target->Set(v8::String::NewSymbol("Foobar"), constructor);
}
v8::Handle<v8::Value> Foobar::nodeNew(const v8::Arguments& args)
{
v8::HandleScope scope;
int id = args[0]->NumberValue();
Point* position = ObjectWrap::Unwrap<Point>(args[1]->ToObject());
int team = args[2]->NumberValue();
Grid* world = ObjectWrap::Unwrap<Grid>(args[3]->ToObject());
Foobar* foobar = new Foobar(id, *position, team, *world);
foobar->Wrap(args.This());
return args.This();
}
v8::Handle<v8::Value> Controller::nodeSpawnFoobar(const v8::Arguments& args)
{
Controller* gridController = ObjectWrap::Unwrap<Controller>(args.This());
int team = args[0]->NumberValue();
gridController->createFoobar(foobarID++, team);
return v8::Undefined();
}
void Controller::spawnFoobar(int id, int team)
{
Point createPosition;
if(team == Teams::kBlue)
{
createPosition = world_->getAreaPosition(Teams::kBlue)->getPosition();
}
else if (team == Teams::kRed)
{
createPosition = world_->getAreaPosition(Teams::kRed)->getPosition();
}
int xh = createPosition.get()[0] - EnvironmentObject::kAreaSize / 2
int yh = createPosition.get()[1] + EnvironmentObject::kAreaSize / 2;
int x = (rand() % EnvironmentObject::kAreaSize) + xh;
int y = (rand() % EnvironmentObject::kAreaSize) + yh - EnvironmentObject::kAreaSize;
foobars_->push_back(new Foobar(id, Point(x, y), team, *world_));
}
Javascript 调用
这是该方法的使用方式
this.update = function() {
if([some event]) {
controller.createFoobar();
console.log(this.getFoobars())
}
}
this.getFoobars = function() {
var foobars = controller.getFoobars();
var foobarsArray = new Array();
for(i = 0; i < foobars.length; i++) {
var foobar = foobar[i];
var position = foobar.getPosition();
var posX = position.getX();
var posY = position.getY();
var positionPoint = new Point(posX, posY);
var velocity = foobar.getVelocity();
var toX = velocity.getToX();
var toY = velocity.getToX();
var velocityVector = new Vector(toX, toY);
var foobarObj = {
id: foobar.getID(),
team: foobar.getTeam(),
position: positionPoint,
velocity: velocityVector,
state: foobar.getState()
}
foobarsArray.push(foobarObj);
}
return miniSnakesArray;
};