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()
local f
eressea.free_game()
f = faction.create("orc@example.com", "orc", "en")
assert_equal(nil, f)
assert_not_nil(eressea.config)
@ -18,6 +19,7 @@ end
function test_read_ship()
local s
eressea.free_game()
s = ship.create(nil, "boat")
assert_equal(nil, s)
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);
if (stype) {
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");
return 1;
} else {

View File

@ -159,6 +159,12 @@ void bt_register(building_type * 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)
{
if (name != NULL) {

View File

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

View File

@ -77,14 +77,33 @@ void json_construction(cJSON *json, construction **consp) {
*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;
if (json->type!=cJSON_Object) {
log_error("building %s is not a json object: %d\n", json->string, json->type);
return;
}
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) {
cJSON *child;
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;
}
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);
return;
}
child = cJSON_GetObjectItem(json, "races");
if (child && child->type==cJSON_Object) {
json_races(child);
}
child = cJSON_GetObjectItem(json, "ships");
if (child && child->type==cJSON_Object) {
json_ships(child);
}
child = cJSON_GetObjectItem(json, "buildings");
if (child && child->type==cJSON_Object) {
json_buildings(child);
for (child=json->child;child;child=child->next) {
if (strcmp(child->string, "races")==0) {
json_races(child);
}
else if (strcmp(child->string, "ships")==0) {
json_ships(child);
}
else if (strcmp(child->string, "buildings")==0) {
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 "types.h"
#include "jsonconf.h"
#include "race.h"
#include "building.h"
#include "race.h"
#include "terrain.h"
#include "ship.h"
#include <CuTest.h>
#include <cJSON.h>
@ -100,10 +101,53 @@ static void test_ships(CuTest * tc)
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 *suite = CuSuiteNew();
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_flags);
return suite;

View File

@ -78,33 +78,48 @@ void test_clear_terrains(void)
const terrain_type *terrains(void)
{
return registered_terrains;
return registered_terrains;
}
static const char *plain_name(const struct region *r)
{
/* TODO: xml defined */
if (r_isforest(r))
return "forest";
return r->terrain->_name;
/* TODO: xml defined */
if (r_isforest(r)) {
return "forest";
}
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;
registered_terrains = terrain;
if (strcmp("plain", terrain->_name) == 0)
terrain->name = &plain_name;
terrain_type *terrain;
for (terrain = registered_terrains; terrain; terrain = terrain->next) {
if (strcmp(terrain->_name, name) == 0) {
break;
}
}
return terrain;
}
const struct terrain_type *get_terrain(const char *name)
{
const struct terrain_type *terrain;
for (terrain = registered_terrains; terrain; terrain = terrain->next) {
if (strcmp(terrain->_name, name) == 0)
break;
}
return terrain;
const terrain_type *get_terrain(const char *name) {
return terrain_find_i(name);
}
terrain_type * terrain_get_or_create(const char *name) {
terrain_type *terrain = terrain_find_i(name);
if (!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];

View File

@ -70,9 +70,9 @@ extern "C" {
struct terrain_type *next;
} terrain_type;
extern terrain_type *terrain_get_or_create(const char *name);
extern const terrain_type *terrains(void);
extern void register_terrain(struct terrain_type *terrain);
extern const struct terrain_type *get_terrain(const char *name);
extern const terrain_type *get_terrain(const char *name);
extern const char *terrain_name(const struct region *r);
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)
{
test_clear_terrains();
test_clear_resources();
global.functions.maintenance = NULL;
global.functions.wage = NULL;
default_locale = 0;
free_locales();
free_spells();
free_shiptypes();
free_races();
free_spellbooks();
free_gamedata();
test_clear_terrains();
test_clear_resources();
global.functions.maintenance = NULL;
global.functions.wage = NULL;
default_locale = 0;
free_locales();
free_spells();
free_buildingtypes();
free_shiptypes();
free_races();
free_spellbooks();
free_gamedata();
}
terrain_type *
test_create_terrain(const char * name, unsigned int flags)
{
terrain_type * t;
assert(!get_terrain(name));
t = (terrain_type*)calloc(1, sizeof(terrain_type));
terrain_type * t = terrain_get_or_create(name);
t->_name = _strdup(name);
t->flags = flags;
register_terrain(t);
return t;
}