separate ally_ api from allies_ api,

delete unallied factions,
start worrying about serialization.
This commit is contained in:
Enno Rehling 2018-10-28 13:45:36 +01:00
parent 1364750687
commit 558390a4a6
6 changed files with 133 additions and 11 deletions

View File

@ -1047,7 +1047,7 @@ static void show_allies_cr(FILE * F, const faction * f, const group *g)
data.F = F;
data.f = f;
struct ally *sf = g ? g->allies : f->allies;
allies_walk(sf, print_ally_cb, &data);
ally_walk(sf, print_ally_cb, &data);
}
/* prints allies */

View File

@ -19,6 +19,105 @@
#include <string.h>
#include <stdlib.h>
#define BLOCKSIZE 15
typedef struct allies {
struct allies *next;
int num;
const struct faction *factions[BLOCKSIZE];
int status[BLOCKSIZE];
} allies;
static void block_insert(allies *al, const struct faction *f, int status) {
int i = al->num++;
al->status[i] = status;
al->factions[i] = f;
/* TODO: heapify */
}
static int block_search(allies *al, const struct faction *f) {
int i;
/* TODO: binary search */
for (i = 0; i != al->num; ++i) {
if (al->factions[i] == f) {
return i;
}
}
return BLOCKSIZE;
}
int allies_get(allies *al, const struct faction *f)
{
for (; al; al = al->next) {
int i = block_search(al, f);
if (i != BLOCKSIZE) {
return al->status[i];
}
}
return 0;
}
void allies_set(allies **p_al, const struct faction *f, int status)
{
while (*p_al) {
allies *al = *p_al;
int i = block_search(al, f);
if (i != BLOCKSIZE) {
if (status == 0) {
if (--al->num != i) {
al->factions[i] = al->factions[al->num];
al->status[i] = al->status[al->num];
/* TODO: repair heap up or down */
}
else if (al->num == 0) {
*p_al = al->next;
free(al);
return;
}
}
else {
al->status[i] = status;
}
return;
}
if (al->num < BLOCKSIZE) {
block_insert(al, f, status);
return;
}
p_al = &al->next;
}
*p_al = calloc(1, sizeof(allies));
block_insert(*p_al, f, status);
}
void allies_write(gamedata * data, const allies *alist)
{
const allies *al;
for (al = alist; al; al = al->next) {
int i;
for (i = 0; i != al->num; ++i) {
const faction * f = al->factions[i];
if (f && f->_alive) {
write_faction_reference(f, data->store);
WRITE_INT(data->store, al->status[i]);
}
}
}
write_faction_reference(NULL, data->store);
}
void allies_read(gamedata * data, allies **sfp)
{
for (;;) {
int aid, state;
READ_INT(data->store, &aid);
/* TODO: deal with unresolved factions, somehow */
if (aid >=0) {
break;
}
READ_INT(data->store, &state);
}
}
typedef struct ally {
struct ally *next;
struct faction *faction;
@ -47,7 +146,7 @@ void allies_free(ally *al)
}
}
ally *allies_clone(const ally *al) {
ally *ally_clone(const ally *al) {
ally *al_clone = NULL, **al_end = &al_clone;
for (; al; al = al->next) {
@ -60,7 +159,7 @@ ally *allies_clone(const ally *al) {
return al_clone;
}
int allies_walk(ally *allies, cb_allies_walk callback, void *udata)
int ally_walk(ally *allies, cb_ally_walk callback, void *udata)
{
ally *al;
for (al = allies; al; al = al->next) {

View File

@ -29,14 +29,20 @@ extern "C" {
struct gamedata;
struct unit;
struct ally;
struct allies;
extern struct attrib_type at_npcfaction;
int allies_get(struct allies *al, const struct faction *f);
void allies_set(struct allies **p_al, const struct faction *f, int status);
void allies_write(struct gamedata * data, const struct allies *alist);
void allies_read(struct gamedata * data, struct allies **sfp);
void read_allies(struct gamedata * data, struct ally **alist);
void write_allies(struct gamedata * data, const struct ally *alist);
typedef int (*cb_allies_walk)(struct ally *, struct faction *, int, void *);
int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata);
struct ally *allies_clone(const struct ally *al);
typedef int (*cb_ally_walk)(struct ally *, struct faction *, int, void *);
int ally_walk(struct ally *allies, cb_ally_walk callback, void *udata);
struct ally *ally_clone(const struct ally *al);
void allies_free(struct ally *al);
struct ally* ally_find(struct ally*al, const struct faction *f);

View File

@ -30,10 +30,10 @@ static void test_allies_clone(CuTest * tc)
test_setup();
f = test_create_faction(NULL);
CuAssertPtrEquals(tc, NULL, allies_clone(NULL));
CuAssertPtrEquals(tc, NULL, ally_clone(NULL));
ally_set(&al, f, HELP_GUARD);
ac = allies_clone(al);
ac = ally_clone(al);
CuAssertPtrNotNull(tc, ac);
CuAssertTrue(tc, al != ac);
CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f));
@ -43,10 +43,27 @@ static void test_allies_clone(CuTest * tc)
test_teardown();
}
static void test_allies(CuTest *tc) {
struct allies * al = NULL;
struct faction * f;
test_setup();
f = test_create_faction(NULL);
CuAssertIntEquals(tc, 0, allies_get(al, f));
allies_set(&al, f, 42);
CuAssertIntEquals(tc, 42, allies_get(al, f));
allies_set(&al, f, 0);
CuAssertIntEquals(tc, 0, allies_get(al, f));
CuAssertPtrEquals(tc, NULL, al);
test_teardown();
}
CuSuite *get_ally_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_ally);
SUITE_ADD_TEST(suite, test_allies);
SUITE_ADD_TEST(suite, test_allies_clone);
return suite;
}

View File

@ -69,7 +69,7 @@ group *new_group(faction * f, const char *name, int gid)
static void init_group(faction * f, group * g)
{
g->allies = allies_clone(f->allies);
g->allies = ally_clone(f->allies);
}
static group *find_groupbyname(group * g, const char *name)

View File

@ -1587,7 +1587,7 @@ static void
show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
{
int num_allies = 0;
allies_walk(allies, count_allies_cb, &num_allies);
ally_walk(allies, count_allies_cb, &num_allies);
if (num_allies > 0) {
struct show_s show;
@ -1595,7 +1595,7 @@ show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
show.num_allies = num_allies;
sbs_init(&show.sbs, buf, size);
allies_walk(allies, show_allies_cb, &show);
ally_walk(allies, show_allies_cb, &show);
sbs_strcat(&show.sbs, ".");
}
}