我目前正在用C ++编写一个Node插件,我遇到了一个问题,我需要制作并返回一个用v8包装的C ++对象实例填充的v8数组。
目前,代码看起来像这样
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
循环中尝试了几种不同的东西,但无济于事。我该怎么做呢?
以下是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_));
}
以下是该方法的使用方法
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;
};
答案 0 :(得分:3)
只要使用Foobar
构造函数创建了nodeNew
个实例,或者更具体地说,只要在对象的某个位置调用了Wrap
,就应该能够这样做:
v8::Local<v8::Array> foobarsArray = v8::Array::New(foobarCount);
for(unsigned int i = 0; i < foobarCount; i++){
foobarsArray->Set(i, (*foobars)[i]->handle_);
}
return scope.Close(foobarsArray);
Node也有一些帮助来缩短Init
:
// Prototype functions
node::SetPrototypeMethod(tpl, "getID", nodeGetID);
node::SetPrototypeMethod(tpl, "getVelocity", nodeGetVelocity);
node::SetPrototypeMethod(tpl, "getState", nodeGetState);
在您的情况下,由于您没有直接在JS中创建Foobar
实例,您需要保存对构造函数的引用,并使用它来创建新实例,而不是调用{{1 }}。如果你考虑你编写的代码,new Foobar
对JavaScript方面知之甚少,因为知道如何使用正确的方法创建对象的v8构造函数对象。
Foobar