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:
parent
e3d8dd1b82
commit
06b3e512d7
@ -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
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user