fix json config for terrains, some other stuff.

This commit is contained in:
Enno Rehling 2014-06-13 17:36:05 -07:00
parent 2033aabf60
commit 24dc006e43
9 changed files with 151 additions and 52 deletions

View File

@ -8,6 +8,7 @@ end
function test_read_race() function test_read_race()
local f local f
eressea.free_game()
f = faction.create("orc@example.com", "orc", "en") f = faction.create("orc@example.com", "orc", "en")
assert_equal(nil, f) assert_equal(nil, f)
assert_not_nil(eressea.config) assert_not_nil(eressea.config)
@ -18,6 +19,7 @@ end
function test_read_ship() function test_read_ship()
local s local s
eressea.free_game()
s = ship.create(nil, "boat") s = ship.create(nil, "boat")
assert_equal(nil, s) assert_equal(nil, s)
assert_not_nil(eressea.config) assert_not_nil(eressea.config)

View File

@ -127,7 +127,7 @@ static int tolua_ship_create(lua_State * L)
const ship_type *stype = st_find(sname); const ship_type *stype = st_find(sname);
if (stype) { if (stype) {
ship *sh = new_ship(stype, r, default_locale); ship *sh = new_ship(stype, r, default_locale);
sh->size = stype->construction->maxsize; sh->size = stype->construction ? stype->construction->maxsize : 1;
tolua_pushusertype(L, (void *)sh, TOLUA_CAST "ship"); tolua_pushusertype(L, (void *)sh, TOLUA_CAST "ship");
return 1; return 1;
} else { } else {

View File

@ -159,6 +159,12 @@ void bt_register(building_type * type)
ql_push(&buildingtypes, (void *)type); ql_push(&buildingtypes, (void *)type);
} }
void free_buildingtypes(void) {
ql_foreach(buildingtypes, free);
ql_free(buildingtypes);
buildingtypes = 0;
}
building_type *bt_get_or_create(const char *name) building_type *bt_get_or_create(const char *name)
{ {
if (name != NULL) { if (name != NULL) {

View File

@ -75,6 +75,7 @@ extern "C" {
building_type *bt_get_or_create(const char *name); building_type *bt_get_or_create(const char *name);
const building_type *bt_find(const char *name); const building_type *bt_find(const char *name);
void free_buildingtypes(void);
void register_buildings(void); void register_buildings(void);
void bt_register(struct building_type *type); void bt_register(struct building_type *type);
int bt_effsize(const struct building_type *btype, int bt_effsize(const struct building_type *btype,

View File

@ -77,14 +77,33 @@ void json_construction(cJSON *json, construction **consp) {
*consp = cons; *consp = cons;
} }
void json_building(cJSON *json, building_type *st) { void json_terrain(cJSON *json, terrain_type *ter) {
cJSON *child;
if (json->type!=cJSON_Object) {
log_error("terrain %s is not a json object: %d\n", json->string, json->type);
return;
}
for (child=json->child;child;child=child->next) {
log_error("terrain %s contains unknown attribute %s\n", json->string, child->string);
}
}
void json_building(cJSON *json, building_type *bt) {
cJSON *child; cJSON *child;
if (json->type!=cJSON_Object) { if (json->type!=cJSON_Object) {
log_error("building %s is not a json object: %d\n", json->string, json->type); log_error("building %s is not a json object: %d\n", json->string, json->type);
return; return;
} }
for (child=json->child;child;child=child->next) { for (child=json->child;child;child=child->next) {
log_error("building %s contains unknown attribute %s\n", json->string, child->string); switch(child->type) {
case cJSON_Object:
if (strcmp(child->string, "construction")==0) {
json_construction(child, &bt->construction);
}
break;
default:
log_error("building %s contains unknown attribute %s\n", json->string, child->string);
}
} }
} }
@ -177,10 +196,21 @@ void json_race(cJSON *json, race *rc) {
} }
} }
void json_terrains(cJSON *json) {
cJSON *child;
if (json->type!=cJSON_Object) {
log_error("terrains is not a json object: %d\n", json->type);
return;
}
for (child=json->child;child;child=child->next) {
json_terrain(child, terrain_get_or_create(child->string));
}
}
void json_buildings(cJSON *json) { void json_buildings(cJSON *json) {
cJSON *child; cJSON *child;
if (json->type!=cJSON_Object) { if (json->type!=cJSON_Object) {
log_error("ships is not a json object: %d\n", json->type); log_error("buildings is not a json object: %d\n", json->type);
return; return;
} }
for (child=json->child;child;child=child->next) { for (child=json->child;child;child=child->next) {
@ -216,17 +246,21 @@ void json_config(cJSON *json) {
log_error("config is not a json object: %d\n", json->type); log_error("config is not a json object: %d\n", json->type);
return; return;
} }
child = cJSON_GetObjectItem(json, "races"); for (child=json->child;child;child=child->next) {
if (child && child->type==cJSON_Object) { if (strcmp(child->string, "races")==0) {
json_races(child); json_races(child);
} }
child = cJSON_GetObjectItem(json, "ships"); else if (strcmp(child->string, "ships")==0) {
if (child && child->type==cJSON_Object) { json_ships(child);
json_ships(child); }
} else if (strcmp(child->string, "buildings")==0) {
child = cJSON_GetObjectItem(json, "buildings"); json_buildings(child);
if (child && child->type==cJSON_Object) { }
json_buildings(child); else if (strcmp(child->string, "terrains")==0) {
json_terrains(child);
} else {
log_error("config contains unknown attribute %s\n", child->string);
}
} }
} }

View File

@ -1,8 +1,9 @@
#include <platform.h> #include <platform.h>
#include "types.h" #include "types.h"
#include "jsonconf.h" #include "jsonconf.h"
#include "race.h"
#include "building.h" #include "building.h"
#include "race.h"
#include "terrain.h"
#include "ship.h" #include "ship.h"
#include <CuTest.h> #include <CuTest.h>
#include <cJSON.h> #include <cJSON.h>
@ -100,10 +101,53 @@ static void test_ships(CuTest * tc)
test_cleanup(); test_cleanup();
} }
static void test_buildings(CuTest * tc)
{
const char * data = "{\"buildings\": { \"house\" : { "
"\"construction\" : { \"maxsize\" : 20, \"reqsize\" : 10, \"minskill\" : 1 }"
"}}}";
cJSON *json = cJSON_Parse(data);
const building_type *bt;
test_cleanup();
CuAssertPtrNotNull(tc, json);
CuAssertPtrEquals(tc, 0, buildingtypes);
json_config(json);
CuAssertPtrNotNull(tc, buildingtypes);
bt = bt_find("house");
CuAssertPtrNotNull(tc, bt);
CuAssertPtrNotNull(tc, bt->construction);
CuAssertIntEquals(tc, 10, bt->construction->reqsize);
CuAssertIntEquals(tc, 20, bt->construction->maxsize);
CuAssertIntEquals(tc, 1, bt->construction->minskill);
test_cleanup();
}
static void test_terrains(CuTest * tc)
{
const char * data = "{\"terrains\": { \"plain\" : {} }}";
cJSON *json = cJSON_Parse(data);
test_cleanup();
CuAssertPtrNotNull(tc, json);
CuAssertPtrEquals(tc, 0, (void *)get_terrain("plain"));
json_config(json);
CuAssertPtrNotNull(tc, get_terrain("plain"));
test_cleanup();
}
CuSuite *get_jsonconf_suite(void) CuSuite *get_jsonconf_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_ships); SUITE_ADD_TEST(suite, test_ships);
SUITE_ADD_TEST(suite, test_buildings);
SUITE_ADD_TEST(suite, test_terrains);
SUITE_ADD_TEST(suite, test_races); SUITE_ADD_TEST(suite, test_races);
SUITE_ADD_TEST(suite, test_flags); SUITE_ADD_TEST(suite, test_flags);
return suite; return suite;

View File

@ -78,33 +78,48 @@ void test_clear_terrains(void)
const terrain_type *terrains(void) const terrain_type *terrains(void)
{ {
return registered_terrains; return registered_terrains;
} }
static const char *plain_name(const struct region *r) static const char *plain_name(const struct region *r)
{ {
/* TODO: xml defined */ /* TODO: xml defined */
if (r_isforest(r)) if (r_isforest(r)) {
return "forest"; return "forest";
return r->terrain->_name; }
return r->terrain->_name;
} }
void register_terrain(struct terrain_type *terrain) static terrain_type *terrain_find_i(const char *name)
{ {
assert(terrain->next == NULL), terrain->next = registered_terrains; terrain_type *terrain;
registered_terrains = terrain; for (terrain = registered_terrains; terrain; terrain = terrain->next) {
if (strcmp("plain", terrain->_name) == 0) if (strcmp(terrain->_name, name) == 0) {
terrain->name = &plain_name; break;
}
}
return terrain;
} }
const struct terrain_type *get_terrain(const char *name) const terrain_type *get_terrain(const char *name) {
{ return terrain_find_i(name);
const struct terrain_type *terrain; }
for (terrain = registered_terrains; terrain; terrain = terrain->next) {
if (strcmp(terrain->_name, name) == 0) terrain_type * terrain_get_or_create(const char *name) {
break; terrain_type *terrain = terrain_find_i(name);
} if (!terrain) {
return terrain; terrain = (terrain_type *)calloc(sizeof(terrain_type), 1);
if (terrain) {
terrain->_name = _strdup(name);
terrain->next = registered_terrains;
registered_terrains = terrain;
if (strcmp("plain", name) == 0) {
// TODO: this is awful, it belongs in config
terrain->name = &plain_name;
}
}
}
return terrain;
} }
static const terrain_type *newterrains[MAXTERRAINS]; static const terrain_type *newterrains[MAXTERRAINS];

View File

@ -70,9 +70,9 @@ extern "C" {
struct terrain_type *next; struct terrain_type *next;
} terrain_type; } terrain_type;
extern terrain_type *terrain_get_or_create(const char *name);
extern const terrain_type *terrains(void); extern const terrain_type *terrains(void);
extern void register_terrain(struct terrain_type *terrain); extern const terrain_type *get_terrain(const char *name);
extern const struct terrain_type *get_terrain(const char *name);
extern const char *terrain_name(const struct region *r); extern const char *terrain_name(const struct region *r);
extern void init_terrains(void); extern void init_terrains(void);

View File

@ -56,29 +56,26 @@ struct unit *test_create_unit(struct faction *f, struct region *r)
void test_cleanup(void) void test_cleanup(void)
{ {
test_clear_terrains(); test_clear_terrains();
test_clear_resources(); test_clear_resources();
global.functions.maintenance = NULL; global.functions.maintenance = NULL;
global.functions.wage = NULL; global.functions.wage = NULL;
default_locale = 0; default_locale = 0;
free_locales(); free_locales();
free_spells(); free_spells();
free_shiptypes(); free_buildingtypes();
free_races(); free_shiptypes();
free_spellbooks(); free_races();
free_gamedata(); free_spellbooks();
free_gamedata();
} }
terrain_type * terrain_type *
test_create_terrain(const char * name, unsigned int flags) test_create_terrain(const char * name, unsigned int flags)
{ {
terrain_type * t; terrain_type * t = terrain_get_or_create(name);
assert(!get_terrain(name));
t = (terrain_type*)calloc(1, sizeof(terrain_type));
t->_name = _strdup(name); t->_name = _strdup(name);
t->flags = flags; t->flags = flags;
register_terrain(t);
return t; return t;
} }