forked from github/server
separate ally_ api from allies_ api,
delete unallied factions, start worrying about serialization.
This commit is contained in:
parent
1364750687
commit
558390a4a6
6 changed files with 133 additions and 11 deletions
|
@ -1047,7 +1047,7 @@ static void show_allies_cr(FILE * F, const faction * f, const group *g)
|
||||||
data.F = F;
|
data.F = F;
|
||||||
data.f = f;
|
data.f = f;
|
||||||
struct ally *sf = g ? g->allies : f->allies;
|
struct ally *sf = g ? g->allies : f->allies;
|
||||||
allies_walk(sf, print_ally_cb, &data);
|
ally_walk(sf, print_ally_cb, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prints allies */
|
/* prints allies */
|
||||||
|
|
|
@ -19,6 +19,105 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.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 {
|
typedef struct ally {
|
||||||
struct ally *next;
|
struct ally *next;
|
||||||
struct faction *faction;
|
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;
|
ally *al_clone = NULL, **al_end = &al_clone;
|
||||||
|
|
||||||
for (; al; al = al->next) {
|
for (; al; al = al->next) {
|
||||||
|
@ -60,7 +159,7 @@ ally *allies_clone(const ally *al) {
|
||||||
return al_clone;
|
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;
|
ally *al;
|
||||||
for (al = allies; al; al = al->next) {
|
for (al = allies; al; al = al->next) {
|
||||||
|
|
|
@ -29,14 +29,20 @@ extern "C" {
|
||||||
struct gamedata;
|
struct gamedata;
|
||||||
struct unit;
|
struct unit;
|
||||||
struct ally;
|
struct ally;
|
||||||
|
struct allies;
|
||||||
|
|
||||||
extern struct attrib_type at_npcfaction;
|
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 read_allies(struct gamedata * data, struct ally **alist);
|
||||||
void write_allies(struct gamedata * data, const struct ally *alist);
|
void write_allies(struct gamedata * data, const struct ally *alist);
|
||||||
typedef int (*cb_allies_walk)(struct ally *, struct faction *, int, void *);
|
typedef int (*cb_ally_walk)(struct ally *, struct faction *, int, void *);
|
||||||
int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata);
|
int ally_walk(struct ally *allies, cb_ally_walk callback, void *udata);
|
||||||
struct ally *allies_clone(const struct ally *al);
|
struct ally *ally_clone(const struct ally *al);
|
||||||
void allies_free(struct ally *al);
|
void allies_free(struct ally *al);
|
||||||
|
|
||||||
struct ally* ally_find(struct ally*al, const struct faction *f);
|
struct ally* ally_find(struct ally*al, const struct faction *f);
|
||||||
|
|
|
@ -30,10 +30,10 @@ static void test_allies_clone(CuTest * tc)
|
||||||
|
|
||||||
test_setup();
|
test_setup();
|
||||||
f = test_create_faction(NULL);
|
f = test_create_faction(NULL);
|
||||||
CuAssertPtrEquals(tc, NULL, allies_clone(NULL));
|
CuAssertPtrEquals(tc, NULL, ally_clone(NULL));
|
||||||
|
|
||||||
ally_set(&al, f, HELP_GUARD);
|
ally_set(&al, f, HELP_GUARD);
|
||||||
ac = allies_clone(al);
|
ac = ally_clone(al);
|
||||||
CuAssertPtrNotNull(tc, ac);
|
CuAssertPtrNotNull(tc, ac);
|
||||||
CuAssertTrue(tc, al != ac);
|
CuAssertTrue(tc, al != ac);
|
||||||
CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f));
|
CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f));
|
||||||
|
@ -43,10 +43,27 @@ static void test_allies_clone(CuTest * tc)
|
||||||
test_teardown();
|
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 *get_ally_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_ally);
|
SUITE_ADD_TEST(suite, test_ally);
|
||||||
|
SUITE_ADD_TEST(suite, test_allies);
|
||||||
SUITE_ADD_TEST(suite, test_allies_clone);
|
SUITE_ADD_TEST(suite, test_allies_clone);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ group *new_group(faction * f, const char *name, int gid)
|
||||||
|
|
||||||
static void init_group(faction * f, group * g)
|
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)
|
static group *find_groupbyname(group * g, const char *name)
|
||||||
|
|
|
@ -1587,7 +1587,7 @@ static void
|
||||||
show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
|
show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
int num_allies = 0;
|
int num_allies = 0;
|
||||||
allies_walk(allies, count_allies_cb, &num_allies);
|
ally_walk(allies, count_allies_cb, &num_allies);
|
||||||
|
|
||||||
if (num_allies > 0) {
|
if (num_allies > 0) {
|
||||||
struct show_s show;
|
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;
|
show.num_allies = num_allies;
|
||||||
sbs_init(&show.sbs, buf, size);
|
sbs_init(&show.sbs, buf, size);
|
||||||
|
|
||||||
allies_walk(allies, show_allies_cb, &show);
|
ally_walk(allies, show_allies_cb, &show);
|
||||||
sbs_strcat(&show.sbs, ".");
|
sbs_strcat(&show.sbs, ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue