refactoring: use add_ally instead of manually crating the structure all over the code.

This commit is contained in:
Enno Rehling 2014-10-31 15:13:05 +01:00
parent c8d5d52412
commit f27a77d288
6 changed files with 143 additions and 151 deletions

View File

@ -430,10 +430,8 @@ void set_alliance(faction * a, faction * b, int status)
sfp = &sf->next; sfp = &sf->next;
} }
if (*sfp == NULL) { if (*sfp == NULL) {
ally *sf = *sfp = malloc(sizeof(ally)); ally *sf = ally_add(sfp, b);
sf->next = NULL;
sf->status = status; sf->status = status;
sf->faction = b;
return; return;
} }
(*sfp)->status |= status; (*sfp)->status |= status;

View File

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -50,203 +50,200 @@ static int maxgid;
static group *new_group(faction * f, const char *name, int gid) static group *new_group(faction * f, const char *name, int gid)
{ {
group **gp = &f->groups; group **gp = &f->groups;
int index = gid % GMAXHASH; int index = gid % GMAXHASH;
group *g = calloc(sizeof(group), 1); group *g = calloc(sizeof(group), 1);
while (*gp) while (*gp)
gp = &(*gp)->next; gp = &(*gp)->next;
*gp = g; *gp = g;
maxgid = _max(gid, maxgid); maxgid = _max(gid, maxgid);
g->name = _strdup(name); g->name = _strdup(name);
g->gid = gid; g->gid = gid;
g->nexthash = ghash[index]; g->nexthash = ghash[index];
return ghash[index] = g; return ghash[index] = g;
} }
static void init_group(faction * f, group * g) static void init_group(faction * f, group * g)
{ {
ally *a, **an; ally *a, **an;
an = &g->allies; an = &g->allies;
for (a = f->allies; a; a = a->next) for (a = f->allies; a; a = a->next)
if (a->faction) { if (a->faction) {
ally *ga = calloc(sizeof(ally), 1); ally *ga = ally_add(an, a->faction);
*ga = *a; ga->status = a->status;
*an = ga; an = &ga->next;
an = &ga->next; }
}
} }
static group *find_groupbyname(group * g, const char *name) static group *find_groupbyname(group * g, const char *name)
{ {
while (g && unicode_utf8_strcasecmp(name, g->name) != 0) while (g && unicode_utf8_strcasecmp(name, g->name) != 0)
g = g->next; g = g->next;
return g; return g;
} }
static group *find_group(int gid) static group *find_group(int gid)
{ {
int index = gid % GMAXHASH; int index = gid % GMAXHASH;
group *g = ghash[index]; group *g = ghash[index];
while (g && g->gid != gid) while (g && g->gid != gid)
g = g->nexthash; g = g->nexthash;
return g; return g;
} }
static int read_group(attrib * a, void *owner, struct storage *store) static int read_group(attrib * a, void *owner, struct storage *store)
{ {
group *g; group *g;
int gid; int gid;
READ_INT(store, &gid); READ_INT(store, &gid);
a->data.v = g = find_group(gid); a->data.v = g = find_group(gid);
if (g != 0) { if (g != 0) {
g->members++; g->members++;
return AT_READ_OK; return AT_READ_OK;
} }
return AT_READ_FAIL; return AT_READ_FAIL;
} }
static void static void
write_group(const attrib * a, const void *owner, struct storage *store) write_group(const attrib * a, const void *owner, struct storage *store)
{ {
group *g = (group *) a->data.v; group *g = (group *)a->data.v;
WRITE_INT(store, g->gid); WRITE_INT(store, g->gid);
} }
attrib_type at_group = { /* attribute for units assigned to a group */ attrib_type at_group = { /* attribute for units assigned to a group */
"grp", "grp",
DEFAULT_INIT, DEFAULT_INIT,
DEFAULT_FINALIZE, DEFAULT_AGE, write_group, read_group, ATF_UNIQUE}; DEFAULT_FINALIZE, DEFAULT_AGE, write_group, read_group, ATF_UNIQUE };
void free_group(group * g) void free_group(group * g)
{ {
int index = g->gid % GMAXHASH; int index = g->gid % GMAXHASH;
group **g_ptr = ghash + index; group **g_ptr = ghash + index;
while (*g_ptr && (*g_ptr)->gid != g->gid) while (*g_ptr && (*g_ptr)->gid != g->gid)
g_ptr = &(*g_ptr)->nexthash; g_ptr = &(*g_ptr)->nexthash;
assert(*g_ptr == g); assert(*g_ptr == g);
*g_ptr = g->nexthash; *g_ptr = g->nexthash;
while (g->allies) { while (g->allies) {
ally *a = g->allies; ally *a = g->allies;
g->allies = a->next; g->allies = a->next;
free(a); free(a);
} }
free(g->name); free(g->name);
free(g); free(g);
} }
group * get_group(const struct unit *u) group * get_group(const struct unit *u)
{ {
if (fval(u, UFL_GROUP)) { if (fval(u, UFL_GROUP)) {
attrib * a = a_find(u->attribs, &at_group); attrib * a = a_find(u->attribs, &at_group);
if (a) { if (a) {
return (group *) a->data.v; return (group *)a->data.v;
}
} }
} return 0;
return 0;
} }
void set_group(struct unit *u, struct group *g) void set_group(struct unit *u, struct group *g)
{ {
attrib *a = NULL; attrib *a = NULL;
if (fval(u, UFL_GROUP)) { if (fval(u, UFL_GROUP)) {
a = a_find(u->attribs, &at_group); a = a_find(u->attribs, &at_group);
} }
if (a) { if (a) {
group *og = (group *) a->data.v; group *og = (group *)a->data.v;
if (og == g) if (og == g)
return; return;
--og->members; --og->members;
} }
if (g) { if (g) {
if (!a) { if (!a) {
a = a_add(&u->attribs, a_new(&at_group)); a = a_add(&u->attribs, a_new(&at_group));
fset(u, UFL_GROUP); fset(u, UFL_GROUP);
}
a->data.v = g;
g->members++;
}
else if (a) {
a_remove(&u->attribs, a);
freset(u, UFL_GROUP);
} }
a->data.v = g;
g->members++;
} else if (a) {
a_remove(&u->attribs, a);
freset(u, UFL_GROUP);
}
} }
bool join_group(unit * u, const char *name) bool join_group(unit * u, const char *name)
{ {
group *g = NULL; group *g = NULL;
if (name && name[0]) { if (name && name[0]) {
g = find_groupbyname(u->faction->groups, name); g = find_groupbyname(u->faction->groups, name);
if (g == NULL) { if (g == NULL) {
g = new_group(u->faction, name, ++maxgid); g = new_group(u->faction, name, ++maxgid);
init_group(u->faction, g); init_group(u->faction, g);
}
} }
}
set_group(u, g); set_group(u, g);
return true; return true;
} }
void write_groups(struct storage *store, group * g) void write_groups(struct storage *store, group * g)
{ {
while (g) { while (g) {
ally *a; ally *a;
WRITE_INT(store, g->gid); WRITE_INT(store, g->gid);
WRITE_STR(store, g->name); WRITE_STR(store, g->name);
for (a = g->allies; a; a = a->next) { for (a = g->allies; a; a = a->next) {
if (a->faction) { if (a->faction) {
write_faction_reference(a->faction, store); write_faction_reference(a->faction, store);
WRITE_INT(store, a->status); WRITE_INT(store, a->status);
} }
}
WRITE_INT(store, 0);
a_write(store, g->attribs, g);
WRITE_SECTION(store);
g = g->next;
} }
WRITE_INT(store, 0); WRITE_INT(store, 0);
a_write(store, g->attribs, g);
WRITE_SECTION(store);
g = g->next;
}
WRITE_INT(store, 0);
} }
void read_groups(struct storage *store, faction * f) void read_groups(struct storage *store, faction * f)
{ {
for (;;) {
ally **pa;
group *g;
int gid;
char buf[1024];
READ_INT(store, &gid);
if (gid == 0)
break;
READ_STR(store, buf, sizeof(buf));
g = new_group(f, buf, gid);
pa = &g->allies;
for (;;) { for (;;) {
ally *a; ally **pa;
variant fid; group *g;
READ_INT(store, &fid.i); int gid;
if (fid.i <= 0) char buf[1024];
break;
if (global.data_version < STORAGE_VERSION && fid.i == 0)
break;
a = malloc(sizeof(ally));
*pa = a;
pa = &a->next;
READ_INT(store, &a->status);
a->faction = findfaction(fid.i); READ_INT(store, &gid);
if (!a->faction) if (gid == 0)
ur_add(fid, &a->faction, resolve_faction); break;
READ_STR(store, buf, sizeof(buf));
g = new_group(f, buf, gid);
pa = &g->allies;
for (;;) {
ally *a;
variant fid;
READ_INT(store, &fid.i);
if (fid.i <= 0)
break;
if (global.data_version < STORAGE_VERSION && fid.i == 0)
break;
a = ally_add(pa, findfaction(fid.i));
READ_INT(store, &a->status);
if (!a->faction)
ur_add(fid, &a->faction, resolve_faction);
}
*pa = 0;
a_read(store, &g->attribs, g);
} }
*pa = 0;
a_read(store, &g->attribs, g);
}
} }

View File

@ -19,6 +19,7 @@ void test_pool(CuTest *tc) {
faction *f; faction *f;
region *r; region *r;
struct resource_type *rtype; struct resource_type *rtype;
ally *al;
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
@ -45,11 +46,10 @@ void test_pool(CuTest *tc) {
CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_POOLED_SLACK, INT_MAX)); CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_POOLED_SLACK, INT_MAX));
CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_POOLED_SLACK | GET_POOLED_RESERVE, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_POOLED_SLACK | GET_POOLED_RESERVE, INT_MAX));
u3->faction->allies = calloc(1, sizeof(ally)); al = ally_add(&u3->faction->allies, f);
u3->faction->allies->faction = f; al->status = HELP_GUARD;
u3->faction->allies->status = HELP_GUARD;
CuAssertIntEquals(tc, 0, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); CuAssertIntEquals(tc, 0, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX));
u3->faction->allies->status = HELP_MONEY; al->status = HELP_MONEY;
CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_SLACK, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_SLACK, INT_MAX));
CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_RESERVE, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_RESERVE, INT_MAX));
CuAssertIntEquals(tc, 400, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); CuAssertIntEquals(tc, 400, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX));

View File

@ -1119,8 +1119,7 @@ static ally **addally(const faction * f, ally ** sfp, int aid, int state)
if (state == 0) if (state == 0)
return sfp; return sfp;
sf = calloc(1, sizeof(ally)); sf = ally_add(sfp, af);
sf->faction = af;
if (!sf->faction) { if (!sf->faction) {
variant id; variant id;
id.i = aid; id.i = aid;

View File

@ -1348,10 +1348,8 @@ int ally_cmd(unit * u, struct order *ord)
return 0; return 0;
} }
else { else {
sf = calloc(1, sizeof(ally)); sf = ally_add(sfp, f);
sf->faction = f;
sf->status = 0; sf->status = 0;
addlist(sfp, sf);
} }
} }
switch (keyword) { switch (keyword) {

View File

@ -93,6 +93,7 @@ static void test_contact(CuTest * tc)
unit *u1, *u2, *u3; unit *u1, *u2, *u3;
building *b; building *b;
building_type *btype; building_type *btype;
ally *al;
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
@ -110,9 +111,8 @@ static void test_contact(CuTest * tc)
u_set_building(u1, b); u_set_building(u1, b);
CuAssertIntEquals(tc, 0, can_contact(r, u1, u2)); CuAssertIntEquals(tc, 0, can_contact(r, u1, u2));
u1->faction->allies = calloc(1, sizeof(ally)); al = ally_add(&u1->faction->allies, u2->faction);
u1->faction->allies->faction = u2->faction; al->status = HELP_ALL;
u1->faction->allies->status = HELP_ALL;
CuAssertIntEquals(tc, HELP_GIVE, can_contact(r, u1, u2)); CuAssertIntEquals(tc, HELP_GIVE, can_contact(r, u1, u2));
u_set_building(u2, b); u_set_building(u2, b);
CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); CuAssertIntEquals(tc, 1, can_contact(r, u1, u2));