1
0
forked from 0ad/0ad

Modified the way objects are converted from JS to C++ to make it easier to use.

This was SVN commit r2404.
This commit is contained in:
Matei 2005-06-19 22:43:07 +00:00
parent e3d8dd1b82
commit 06b3e512d7
7 changed files with 101 additions and 132 deletions

View File

@ -1,10 +1,10 @@
const SIZE = 128;
init(SIZE, "snow forest", 0);
init(SIZE, new RandomTerrain("snow", "snow forest"), 0);
createMulti(
new ClumpPlacer(20.0, 0.01, 0.01),
new LayeredPainter([1], ["snow grass 2", "snow grass 2|wrld_flora_pine"]),
new AvoidTerrainConstraint("snow grass 2"),
new AvoidTextureConstraint("snow grass 2"),
350,
1000
);

View File

@ -8,7 +8,7 @@ TYPE_RANDOMTERRAIN = 4,
TYPE_LAYEREDPAINTER = 5,
TYPE_AVOIDAREACONSTRAINT = 6,
TYPE_CLUMPPLACER = 7,
TYPE_AVOIDTERRAINCONSTRAINT = 8,
TYPE_AVOIDTEXTURECONSTRAINT = 8,
TYPE_ANDCONSTRAINT = 9;
// Utility functions
@ -42,74 +42,56 @@ function chooseRand() {
// Area placers
function RectPlacer(x1, y1, x2, y2) {
this.TYPE = TYPE_RECTPLACER;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.raw = function() {
return [TYPE_RECTPLACER, this.x1, this.y1, this.x2, this.y2];
}
}
function TerrainPainter(terrain) {
this.TYPE = TYPE_TERRAINPAINTER;
this.terrain = terrain;
this.raw = function() {
return [TYPE_TERRAINPAINTER, this.terrain];
}
}
function NullConstraint() {
this.raw = function() {
return [TYPE_NULLCONSTRAINT];
}
this.TYPE = TYPE_NULLCONSTRAINT;
}
function RandomTerrain() {
this.TYPE = TYPE_RANDOMTERRAIN;
this.terrains = argsToArray(arguments);
this.raw = function() {
return [TYPE_RANDOMTERRAIN, this.terrains];
}
}
function LayeredPainter(widths, terrains) {
this.TYPE = TYPE_LAYEREDPAINTER;
this.widths = widths;
this.terrains = terrains;
this.raw = function() {
return [TYPE_LAYEREDPAINTER, this.widths, this.terrains];
}
}
function AvoidAreaConstraint(area) {
this.TYPE = TYPE_AVOIDAREACONSTRAINT;
this.area = area;
this.raw = function() {
return [TYPE_AVOIDAREACONSTRAINT, this.area];
}
}
function ClumpPlacer(size, coherence, smoothness, x, y) {
this.TYPE = TYPE_CLUMPPLACER;
this.size = size;
this.coherence = coherence;
this.smoothness = smoothness;
this.x = x ? x : -1;
this.y = y ? y : -1;
this.raw = function() {
return [TYPE_CLUMPPLACER, this.size, this.coherence, this.smoothness, this.x, this.y];
}
}
function AvoidTerrainConstraint(texture) {
function AvoidTextureConstraint(texture) {
this.TYPE = TYPE_AVOIDTEXTURECONSTRAINT;
this.texture = texture;
this.raw = function() {
return [TYPE_AVOIDTERRAINCONSTRAINT, this.texture];
}
}
function AndConstraint(a, b) {
this.TYPE = TYPE_ANDCONSTRAINT;
this.a = a;
this.b = b;
this.raw = function() {
return [TYPE_ANDCONSTRAINT, this.a, this.b];
}
}
function createMulti(centeredPlacer, painter, constraint, num, maxFail) {
@ -128,5 +110,5 @@ function createMulti(centeredPlacer, painter, constraint, num, maxFail) {
bad++;
}
}
return (good==num) ? ret : null;
return ret;
}

View File

@ -205,7 +205,7 @@ JSBool addEntity(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *r
jsdouble x, y, orientation;
JS_ValueToNumber(cx, argv[2], &x);
JS_ValueToNumber(cx, argv[3], &y);
JS_ValueToNumber(cx, argv[5], &orientation);
JS_ValueToNumber(cx, argv[4], &orientation);
theMap->addEntity(new Entity(type, player, x,0,y, orientation));
@ -273,4 +273,4 @@ JSBool createArea(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *
*rval = INT_TO_JSVAL(id);
}
return JS_TRUE;
}
}

View File

@ -9,72 +9,60 @@
using namespace std;
bool GetRaw(JSContext* cx, jsval val, JSObject** retObj, int* retType) {
if(!JSVAL_IS_OBJECT(val)) return false;
JSObject* obj = JSVAL_TO_OBJECT(val);
jsval ret;
if(!JS_CallFunctionName(cx, obj, "raw", 0, 0, &ret)) {
return false;
}
if(!JSVAL_IS_OBJECT(ret)) return false;
*retObj = JSVAL_TO_OBJECT(ret);
if(!JS_IsArrayObject(cx, *retObj)) return false;
jsuint len;
JS_GetArrayLength(cx, *retObj, &len);
if(len==0) return false;
jsval rval;
JS_GetElement(cx, *retObj, 0, &rval);
if(!JSVAL_IS_INT(rval)) return 0;
*retType = JSVAL_TO_INT(rval);
int GetType(JSContext* cx, jsval val) {
int ret;
if(!GetIntField(cx, val, "TYPE", ret)) return 0;
return ret;
}
bool GetIntField(JSContext* cx, jsval obj, const char* name, int& ret) {
jsval val;
if(!GetJsvalField(cx, obj, name, val)) return false;
if(!JSVAL_IS_INT(val)) return false;
ret = JSVAL_TO_INT(val);
return true;
}
bool ParseFields(JSContext* cx, JSObject* array, const char* format, ...) {
int len = strlen(format);
jsuint arLen;
JS_GetArrayLength(cx, array, &arLen);
if(arLen != len+1) return false;
va_list ap;
va_start(ap, format); // start at next arg after format
for(int i=0; i<len; i++)
{
jsval val;
JS_GetElement(cx, array, i+1, &val);
if(format[i] == 'i') {
int* r = va_arg(ap, int*);
if(!JSVAL_IS_INT(val)) return false;
*r = JSVAL_TO_INT(val);
}
else if(format[i] == 'n') {
float* r = va_arg(ap, float*);
if(!JSVAL_IS_NUMBER(val)) return false;
jsdouble jsd;
JS_ValueToNumber(cx, val, &jsd);
*r = jsd;
}
else if(format[i] == 's') {
string* r = va_arg(ap, string*);
if(!JSVAL_IS_STRING(val)) return false;
*r = JS_GetStringBytes(JS_ValueToString(cx, val));
}
else if(format[i] == '*') {
jsval* r = va_arg(ap, jsval*);
*r = val;
}
else
{
cerr << "Internal Error: unsupported type '" << format[i] << "' for ParseFields!\n";
Shutdown(1);
return false;
}
}
va_end(ap);
bool GetBoolField(JSContext* cx, jsval obj, const char* name, int& ret) {
jsval val;
if(!GetJsvalField(cx, obj, name, val)) return false;
if(!JSVAL_IS_BOOLEAN(val)) return false;
ret = JSVAL_TO_BOOLEAN(val);
return true;
}
bool GetFloatField(JSContext* cx, jsval obj, const char* name, float& ret) {
jsval val;
if(!GetJsvalField(cx, obj, name, val)) return false;
if(!JSVAL_IS_NUMBER(val)) return false;
jsdouble jsdbl;
JS_ValueToNumber(cx, val, &jsdbl);
ret = jsdbl;
return true;
}
bool GetStringField(JSContext* cx, jsval obj, const char* name, std::string& ret) {
jsval val;
if(!GetJsvalField(cx, obj, name, val)) return false;
if(!JSVAL_IS_STRING(val)) return false;
ret = JS_GetStringBytes(JSVAL_TO_STRING(val));
return true;
}
bool GetArrayField(JSContext* cx, jsval obj, const char* name, std::vector<jsval>& ret) {
ret.clear();
jsval val;
if(!GetJsvalField(cx, obj, name, val)) return false;
if(!ParseArray(cx, val, ret)) return false;
return true;
}
bool GetJsvalField(JSContext* cx, jsval obj, const char* name, jsval& ret) {
if(!JSVAL_IS_OBJECT(obj)) return false;
JSObject* fieldObj = JSVAL_TO_OBJECT(obj);
return JS_GetProperty(cx, fieldObj, name, &ret);
}
bool ParseArray(JSContext* cx, jsval val, vector<jsval>& ret) {
ret.clear();
if(!JSVAL_IS_OBJECT(val)) return false;
@ -91,24 +79,22 @@ bool ParseArray(JSContext* cx, jsval val, vector<jsval>& ret) {
}
AreaPainter* ParsePainter(JSContext* cx, jsval val) {
JSObject* obj; int type;
if(!GetRaw(cx, val, &obj, &type)) return 0;
jsval jsv, jsv2;
Terrain* terrain = 0;
vector<jsval> array;
vector<Terrain*> terrains;
vector<int> widths;
switch(type) {
switch(GetType(cx, val)) {
case TYPE_TERRAINPAINTER:
if(!ParseFields(cx, obj, "*", &jsv)) return 0;
if(!GetJsvalField(cx, val, "terrain", jsv)) return 0;
terrain = ParseTerrain(cx, jsv);
if(terrain==0) return 0;
return new TerrainPainter(terrain);
case TYPE_LAYEREDPAINTER:
if(!ParseFields(cx, obj, "**", &jsv, &jsv2)) return 0;
if(!GetJsvalField(cx, val, "widths", jsv)) return 0;
if(!GetJsvalField(cx, val, "terrains", jsv2)) return 0;
if(!ParseArray(cx, jsv, array)) return 0;
for(int i=0; i<array.size(); i++) {
if(!JSVAL_IS_INT(array[i])) return 0;
@ -129,20 +115,24 @@ AreaPainter* ParsePainter(JSContext* cx, jsval val) {
}
AreaPlacer* ParsePlacer(JSContext* cx, jsval val) {
JSObject* obj; int type;
if(!GetRaw(cx, val, &obj, &type)) return 0;
jsval jsv;
int x, y, x1, y1, x2, y2, num, maxFail;
float size, coherence, smoothness;
switch(type) {
switch(GetType(cx, val)) {
case TYPE_RECTPLACER:
if(!ParseFields(cx, obj, "iiii", &x1, &y1, &x2, &y2)) return 0;
if(!GetIntField(cx, val, "x1", x1)) return 0;
if(!GetIntField(cx, val, "y1", y1)) return 0;
if(!GetIntField(cx, val, "x2", x2)) return 0;
if(!GetIntField(cx, val, "y2", y2)) return 0;
return new RectPlacer(x1, y1, x2, y2);
case TYPE_CLUMPPLACER:
if(!ParseFields(cx, obj, "nnnii", &size, &coherence, &smoothness, &x, &y)) return 0;
if(!GetFloatField(cx, val, "size", size)) return 0;
if(!GetFloatField(cx, val, "coherence", coherence)) return 0;
if(!GetFloatField(cx, val, "smoothness", smoothness)) return 0;
if(!GetIntField(cx, val, "x", x)) return 0;
if(!GetIntField(cx, val, "y", y)) return 0;
return new ClumpPlacer(size, coherence, smoothness, x, y);
default:
@ -153,30 +143,27 @@ AreaPlacer* ParsePlacer(JSContext* cx, jsval val) {
Constraint* ParseConstraint(JSContext* cx, jsval val) {
if(JSVAL_IS_NULL(val)) return new NullConstraint();
JSObject* obj; int type;
if(!GetRaw(cx, val, &obj, &type)) return 0;
int areaId;
string texture;
jsval jsv, jsv2;
Constraint* c1, *c2;
switch(type) {
switch(GetType(cx, val)) {
case TYPE_NULLCONSTRAINT:
if(!ParseFields(cx, obj, "")) return 0;
return new NullConstraint();
case TYPE_AVOIDAREACONSTRAINT:
if(!ParseFields(cx, obj, "i", &areaId)) return 0;
if(!GetIntField(cx, val, "area", areaId)) return 0;
if(areaId <= 0 || areaId > theMap->areas.size()) return 0;
return new AvoidAreaConstraint(theMap->areas[areaId-1]);
case TYPE_AVOIDTERRAINCONSTRAINT:
if(!ParseFields(cx, obj, "s", &texture)) return 0;
return new AvoidTerrainConstraint(theMap->getId(texture));
case TYPE_AVOIDTEXTURECONSTRAINT:
if(!GetStringField(cx, val, "texture", texture)) return 0;
return new AvoidTextureConstraint(theMap->getId(texture));
case TYPE_ANDCONSTRAINT:
if(!ParseFields(cx, obj, "**", &jsv, &jsv2)) return 0;
if(!GetJsvalField(cx, val, "a", jsv)) return 0;
if(!GetJsvalField(cx, val, "b", jsv2)) return 0;
if(!(c1 = ParseConstraint(cx, jsv))) return 0;
if(!(c2 = ParseConstraint(cx, jsv2))) return 0;
return new AndConstraint(c1, c2);
@ -194,18 +181,13 @@ Terrain* ParseTerrain(JSContext* cx, jsval val) {
}
else {
// complex terrain type
JSObject* obj; int type;
if(!GetRaw(cx, val, &obj, &type)) return 0;
jsval jsv;
Terrain* terrain = 0;
vector<jsval> array;
vector<Terrain*> terrains;
switch(type) {
switch(GetType(cx, val)) {
case TYPE_RANDOMTERRAIN:
if(!ParseFields(cx, obj, "*", &jsv)) return 0;
if(!ParseArray(cx, jsv, array)) return 0;
if(!GetArrayField(cx, val, "terrains", array)) return 0;
for(int i=0; i<array.size(); i++) {
terrain = ParseTerrain(cx, array[i]);
if(terrain==0) return 0;

View File

@ -18,14 +18,19 @@ TYPE_RANDOMTERRAIN = 4,
TYPE_LAYEREDPAINTER = 5,
TYPE_AVOIDAREACONSTRAINT = 6,
TYPE_CLUMPPLACER = 7,
TYPE_AVOIDTERRAINCONSTRAINT = 8,
TYPE_AVOIDTEXTURECONSTRAINT = 8,
TYPE_ANDCONSTRAINT = 9;
// Helper functions to parse objects from array versions
// Helper functions to parse objects from JS versions
JSObject* GetRaw(JSContext* cx, jsval val);
int GetType(JSContext* cx, jsval val);
bool GetIntField(JSContext* cx, jsval obj, const char* name, int& ret);
bool GetBoolField(JSContext* cx, jsval obj, const char* name, int& ret);
bool GetFloatField(JSContext* cx, jsval obj, const char* name, float& ret);
bool GetStringField(JSContext* cx, jsval obj, const char* name, std::string& ret);
bool GetArrayField(JSContext* cx, jsval obj, const char* name, std::vector<jsval>& ret);
bool GetJsvalField(JSContext* cx, jsval obj, const char* name, jsval& ret);
bool ParseFields(JSContext* cx, JSObject* array, const char* format, ...);
bool ParseArray(JSContext* cx, jsval val, std::vector<jsval>& ret);
AreaPainter* ParsePainter(JSContext* cx, jsval val);

View File

@ -21,13 +21,13 @@ bool AvoidAreaConstraint::allows(Map* m, int x, int y)
return m->area[x][y] != area;
}
// AvoidTerrainConstraint
// AvoidTextureConstraint
AvoidTerrainConstraint::AvoidTerrainConstraint(int textureId) {
AvoidTextureConstraint::AvoidTextureConstraint(int textureId) {
this->textureId = textureId;
}
bool AvoidTerrainConstraint::allows(Map* m, int x, int y)
bool AvoidTextureConstraint::allows(Map* m, int x, int y)
{
return m->texture[x][y] != textureId;
}

View File

@ -18,11 +18,11 @@ public:
virtual bool allows(Map* m, int x, int y);
};
class AvoidTerrainConstraint : public Constraint {
class AvoidTextureConstraint : public Constraint {
private:
int textureId;
public:
AvoidTerrainConstraint(int textureId);
AvoidTextureConstraint(int textureId);
virtual bool allows(Map* m, int x, int y);
};