The list of alliance members is now also a quicklist, and the lua binding for faction_list iteration can disappear.

This commit is contained in:
Enno Rehling 2011-02-25 07:23:02 -08:00
parent d2994d816a
commit efca8cee43
9 changed files with 79 additions and 73 deletions

View File

@ -26,6 +26,7 @@ without prior permission by the authors of Eressea.
#include <util/language.h> #include <util/language.h>
#include <util/log.h> #include <util/log.h>
#include <util/quicklist.h>
#include <lua.h> #include <lua.h>
#include <tolua.h> #include <tolua.h>
@ -43,18 +44,6 @@ int tolua_factionlist_next(lua_State *L)
else return 0; /* no more values to return */ else return 0; /* no more values to return */
} }
int tolua_factionlist_iter(lua_State *L)
{
faction_list** faction_ptr = (faction_list **)lua_touserdata(L, lua_upvalueindex(1));
faction_list* flist = *faction_ptr;
if (flist != NULL) {
tolua_pushusertype(L, (void*)flist->data, TOLUA_CAST "faction");
*faction_ptr = flist->next;
return 1;
}
else return 0; /* no more values to return */
}
static int tolua_faction_get_units(lua_State* L) static int tolua_faction_get_units(lua_State* L)
{ {
faction * self = (faction *)tolua_tousertype(L, 1, 0); faction * self = (faction *)tolua_tousertype(L, 1, 0);

View File

@ -16,7 +16,6 @@ extern "C" {
struct lua_State; struct lua_State;
int tolua_factionlist_next(struct lua_State *L); int tolua_factionlist_next(struct lua_State *L);
int tolua_factionlist_iter(struct lua_State *L);
void tolua_faction_open(struct lua_State *L); void tolua_faction_open(struct lua_State *L);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -55,6 +55,7 @@ without prior permission by the authors of Eressea.
#include <util/language.h> #include <util/language.h>
#include <util/lists.h> #include <util/lists.h>
#include <util/log.h> #include <util/log.h>
#include <util/quicklist.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/rng.h> #include <util/rng.h>
#include <util/storage.h> #include <util/storage.h>
@ -91,6 +92,24 @@ int tolua_orderlist_next(lua_State *L)
else return 0; /* no more values to return */ else return 0; /* no more values to return */
} }
int tolua_quicklist_iter(lua_State *L)
{
quicklist** qlp = (quicklist **)lua_touserdata(L, lua_upvalueindex(1));
quicklist* ql = *qlp;
if (ql != NULL) {
int index = lua_tointeger(L, lua_upvalueindex(2));
const char * type = lua_tostring(L, lua_upvalueindex(3));
void * data = ql_get(ql, index);
tolua_pushusertype(L, data, TOLUA_CAST type);
ql_advance(qlp, &index, 1);
tolua_pushnumber(L, index);
lua_replace(L, lua_upvalueindex(2));
return 1;
}
else return 0; /* no more values to return */
}
int tolua_spelllist_next(lua_State *L) int tolua_spelllist_next(lua_State *L)
{ {
spell_list** spell_ptr = (spell_list **)lua_touserdata(L, lua_upvalueindex(1)); spell_list** spell_ptr = (spell_list **)lua_touserdata(L, lua_upvalueindex(1));
@ -728,14 +747,17 @@ static int
tolua_get_alliance_factions(lua_State* L) tolua_get_alliance_factions(lua_State* L)
{ {
alliance * self = (alliance *)tolua_tousertype(L, 1, 0); alliance * self = (alliance *)tolua_tousertype(L, 1, 0);
faction_list ** faction_ptr = (faction_list**)lua_newuserdata(L, sizeof(faction_list *)); quicklist ** faction_ptr = (quicklist**)lua_newuserdata(L, sizeof(quicklist *));
luaL_getmetatable(L, "faction_list"); luaL_getmetatable(L, "faction_list");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_pushnumber(L, 0);
*faction_ptr = self->members; *faction_ptr = self->members;
lua_pushcclosure(L, tolua_factionlist_iter, 1); lua_pushstring(L, "faction");
lua_pushcclosure(L, tolua_quicklist_iter, 3); /* OBS: this closure has multiple upvalues (list, index, type_name) */
return 1; return 1;
} }
@ -1052,6 +1074,7 @@ tolua_eressea_open(lua_State* L)
tolua_usertype(L, TOLUA_CAST "item"); tolua_usertype(L, TOLUA_CAST "item");
tolua_usertype(L, TOLUA_CAST "alliance"); tolua_usertype(L, TOLUA_CAST "alliance");
tolua_usertype(L, TOLUA_CAST "event"); tolua_usertype(L, TOLUA_CAST "event");
tolua_usertype(L, TOLUA_CAST "faction_list");
tolua_module(L, NULL, 0); tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL); tolua_beginmodule(L, NULL);

View File

@ -33,6 +33,7 @@ without prior permission by the authors of Eressea.
#include <util/base36.h> #include <util/base36.h>
#include <util/language.h> #include <util/language.h>
#include <util/parser.h> #include <util/parser.h>
#include <util/quicklist.h>
#include <util/rng.h> #include <util/rng.h>
#include <util/umlaut.h> #include <util/umlaut.h>
@ -49,11 +50,7 @@ void
free_alliance(alliance * al) free_alliance(alliance * al)
{ {
free(al->name); free(al->name);
while (al->members) { if (al->members) ql_free(al->members);
faction_list * m = al->members;
al->members = m->next;
free(m);
}
free(al); free(al);
} }
@ -111,7 +108,7 @@ alliance_get_leader(alliance * al)
{ {
if (!al->_leader) { if (!al->_leader) {
if (al->members) { if (al->members) {
al->_leader = al->members->data; al->_leader = (faction *)ql_get(al->members, 0);
} }
} }
return al->_leader; return al->_leader;
@ -120,7 +117,7 @@ alliance_get_leader(alliance * al)
static void static void
create_transaction(int type, unit * u, order * ord) create_transaction(int type, unit * u, order * ord)
{ {
alliance_transaction * tr = calloc(1, sizeof(alliance_transaction)); alliance_transaction * tr = (alliance_transaction *)calloc(1, sizeof(alliance_transaction));
tr->ord = ord; tr->ord = ord;
tr->u = u; tr->u = u;
tr->next = transactions[type]; tr->next = transactions[type];
@ -372,24 +369,24 @@ alliancejoin(void)
} }
void void
setalliance(struct faction * f, alliance * al) setalliance(faction * f, alliance * al)
{ {
faction_list * flist = NULL;
if (f->alliance==al) return; if (f->alliance==al) return;
if (f->alliance!=NULL) { if (f->alliance!=NULL) {
faction_list ** flistp = &f->alliance->members; int qi;
while (*flistp) { quicklist ** flistp = &f->alliance->members;
faction_list * flist = *flistp;
if ((*flistp)->data==f) { for (qi=0;*flistp;ql_advance(flistp, &qi, 1)) {
*flistp = flist->next; faction * data = (faction *)ql_get(*flistp, qi);
if (data==f) {
ql_delete(flistp, qi);
break; break;
} }
flistp = &flist->next;
} }
if (f->alliance->_leader==f) { if (f->alliance->_leader==f) {
if (f->alliance->members) { if (f->alliance->members) {
f->alliance->_leader = f->alliance->members->data; f->alliance->_leader = (faction *)ql_get(f->alliance->members, 0);
} else { } else {
f->alliance->_leader = NULL; f->alliance->_leader = NULL;
} }
@ -398,22 +395,11 @@ setalliance(struct faction * f, alliance * al)
f->alliance = al; f->alliance = al;
f->alliance_joindate = turn; f->alliance_joindate = turn;
if (al!=NULL) { if (al!=NULL) {
faction_list ** flistp = &al->members; ql_push(&al->members, f);
while (*flistp) {
flistp = &(*flistp)->next;
}
if (flist==NULL) {
flist = malloc(sizeof(faction_list));
flist->data = f;
}
*flistp = flist;
flist->next = NULL;
if (al->_leader==NULL) { if (al->_leader==NULL) {
al->_leader = f; al->_leader = f;
} }
flist = NULL;
} }
free(flist);
} }
const char * const char *
@ -456,15 +442,15 @@ alliancevictory(void)
} }
while (al!=NULL) { while (al!=NULL) {
if (!fval(al, FFL_MARK)) { if (!fval(al, FFL_MARK)) {
faction_list * flist = al->members; int qi;
while (flist!=0) { quicklist * flist = al->members;
faction * f = flist->data; for (qi=0;flist;ql_advance(&flist, &qi, 1)) {
faction * f = (faction *)ql_get(flist, qi);
if (f->alliance==al) { if (f->alliance==al) {
ADDMSG(&f->msgs, msg_message("alliance::lost", ADDMSG(&f->msgs, msg_message("alliance::lost",
"alliance", al)); "alliance", al));
destroyfaction(f); destroyfaction(f);
} }
flist = flist->next;
} }
} else { } else {
freset(al, FFL_MARK); freset(al, FFL_MARK);
@ -478,18 +464,20 @@ victorycondition(const alliance * al, const char * name)
{ {
const char * gems[] = { "opal", "diamond", "zaphire", "topaz", "beryl", "agate", "garnet", "emerald", NULL }; const char * gems[] = { "opal", "diamond", "zaphire", "topaz", "beryl", "agate", "garnet", "emerald", NULL };
if (strcmp(name, "gems")==0) { if (strcmp(name, "gems")==0) {
const char ** igem = gems; const char ** igem;
for (;*igem;++igem) { for (igem=gems;*igem;++igem) {
const struct item_type * itype = it_find(*igem); const struct item_type * itype = it_find(*igem);
faction_list * flist = al->members; quicklist * flist = al->members;
int qi;
boolean found = false; boolean found = false;
assert(itype!=NULL); assert(itype!=NULL);
for (;flist && !found;flist=flist->next) { for (qi=0;flist && !found;ql_advance(&flist, &qi, 1)) {
unit * u = flist->data->units; faction * f = (faction *)ql_get(flist, 0);
unit * u;
for (;u;u=u->nextF) { for (u=f->units;u;u=u->nextF) {
if (i_get(u->items, itype)>0) { if (i_get(u->items, itype)>0) {
found = true; found = true;
break; break;
@ -501,9 +489,11 @@ victorycondition(const alliance * al, const char * name)
return 1; return 1;
} else if (strcmp(name, "phoenix")==0) { } else if (strcmp(name, "phoenix")==0) {
faction_list * flist = al->members; quicklist * flist = al->members;
for (;flist;flist=flist->next) { int qi;
faction * f = flist->data;
for (qi=0;flist;ql_advance(&flist, &qi, 1)) {
faction * f = (faction *)ql_get(flist, qi);
if (find_key(f->attribs, atoi36("phnx"))) { if (find_key(f->attribs, atoi36("phnx"))) {
return 1; return 1;
} }
@ -527,9 +517,11 @@ victorycondition(const alliance * al, const char * name)
* } * }
*/ */
faction_list * flist = al->members; quicklist * flist = al->members;
for (;flist;flist=flist->next) { int qi;
faction * f = flist->data;
for (qi=0;flist;ql_advance(&flist, &qi, 1)) {
faction * f = (faction *)ql_get(flist, qi);
if (find_key(f->attribs, atoi36("pyra"))) { if (find_key(f->attribs, atoi36("pyra"))) {
return 1; return 1;
} }

View File

@ -44,7 +44,7 @@ enum {
typedef struct alliance { typedef struct alliance {
struct alliance * next; struct alliance * next;
struct faction * _leader; struct faction * _leader;
struct faction_list * members; struct quicklist * members;
unsigned int flags; unsigned int flags;
int id; int id;
char * name; char * name;

View File

@ -53,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* util includes */ /* util includes */
#include <util/attrib.h> #include <util/attrib.h>
#include <util/base36.h> #include <util/base36.h>
#include <util/bsdstring.h>
#include <util/crmessage.h> #include <util/crmessage.h>
#include <util/event.h> #include <util/event.h>
#include <util/functions.h> #include <util/functions.h>
@ -60,14 +61,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/log.h> #include <util/log.h>
#include <util/lists.h> #include <util/lists.h>
#include <util/parser.h> #include <util/parser.h>
#include <util/quicklist.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/rng.h> #include <util/rng.h>
#include <util/sql.h> #include <util/sql.h>
#include <util/translation.h> #include <util/translation.h>
#include <util/unicode.h>
#include <util/umlaut.h> #include <util/umlaut.h>
#include <util/xml.h> #include <util/xml.h>
#include <util/bsdstring.h>
#include <util/unicode.h>
/* libxml includes */ /* libxml includes */
#include <libxml/tree.h> #include <libxml/tree.h>
@ -507,10 +508,12 @@ allied_skillcount(const faction * f, skill_t sk)
{ {
int num = 0; int num = 0;
alliance * a = f_get_alliance(f); alliance * a = f_get_alliance(f);
faction_list * members = a->members; quicklist * members = a->members;
while (members!=NULL) { int qi;
num += count_skill(members->data, sk);
members=members->next; for (qi=0;members;ql_advance(&members, &qi, 1)) {
faction * m = (faction *)ql_get(members, qi);
num += count_skill(m, sk);
} }
return num; return num;
} }

View File

@ -924,9 +924,10 @@ get_addresses(report_context * ctx)
ql_push(&flist, ctx->f); ql_push(&flist, ctx->f);
if (f_get_alliance(ctx->f)) { if (f_get_alliance(ctx->f)) {
faction_list * member = ctx->f->alliance->members; quicklist * ql = ctx->f->alliance->members;
for (;member;member=member->next) { int qi;
ql_set_insert(&flist, member->data); for (qi=0;ql;ql_advance(&ql, &qi, 1)) {
ql_set_insert(&flist, ql_get(ql, qi));
} }
} }

View File

@ -62,6 +62,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/lists.h> #include <util/lists.h>
#include <util/log.h> #include <util/log.h>
#include <util/parser.h> #include <util/parser.h>
#include <util/quicklist.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/resolve.h> #include <util/resolve.h>
#include <util/rng.h> #include <util/rng.h>
@ -1178,13 +1179,10 @@ readfaction(struct storage * store)
if (allianceid>0) f->alliance = findalliance(allianceid); if (allianceid>0) f->alliance = findalliance(allianceid);
if (f->alliance) { if (f->alliance) {
alliance * al = f->alliance; alliance * al = f->alliance;
faction_list * flist = (faction_list *)malloc(sizeof(faction_list));
if (al->flags&ALF_NON_ALLIED) { if (al->flags&ALF_NON_ALLIED) {
assert(!al->members || !"non-allied dummy-alliance has more than one member"); assert(!al->members || !"non-allied dummy-alliance has more than one member");
} }
flist->data = f; ql_push(&al->members, f);
flist->next = al->members;
al->members = flist;
} else if (rule_region_owners()){ } else if (rule_region_owners()){
/* compat fix for non-allied factions */ /* compat fix for non-allied factions */
alliance * al = makealliance(0, NULL); alliance * al = makealliance(0, NULL);

View File

@ -142,6 +142,7 @@ int ql_advance(struct quicklist ** iterator, int * index, int stride)
void ql_free(struct quicklist * ql) void ql_free(struct quicklist * ql)
{ {
if (!ql) return;
if (ql->next) ql_free(ql->next); if (ql->next) ql_free(ql->next);
free(ql); free(ql);
} }