From efca8cee43f5968401304db80b255cf7dfce9190 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 25 Feb 2011 07:23:02 -0800 Subject: [PATCH] The list of alliance members is now also a quicklist, and the lua binding for faction_list iteration can disappear. --- src/bindings/bind_faction.c | 13 +----- src/bindings/bind_faction.h | 1 - src/bindings/bindings.c | 27 ++++++++++++- src/kernel/alliance.c | 80 +++++++++++++++++-------------------- src/kernel/alliance.h | 2 +- src/kernel/config.c | 15 ++++--- src/kernel/reports.c | 7 ++-- src/kernel/save.c | 6 +-- src/util/quicklist.c | 1 + 9 files changed, 79 insertions(+), 73 deletions(-) diff --git a/src/bindings/bind_faction.c b/src/bindings/bind_faction.c index 44caf3618..045aeea05 100644 --- a/src/bindings/bind_faction.c +++ b/src/bindings/bind_faction.c @@ -26,6 +26,7 @@ without prior permission by the authors of Eressea. #include #include +#include #include #include @@ -43,18 +44,6 @@ int tolua_factionlist_next(lua_State *L) 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) { faction * self = (faction *)tolua_tousertype(L, 1, 0); diff --git a/src/bindings/bind_faction.h b/src/bindings/bind_faction.h index c89750062..c390c5606 100644 --- a/src/bindings/bind_faction.h +++ b/src/bindings/bind_faction.h @@ -16,7 +16,6 @@ extern "C" { struct lua_State; int tolua_factionlist_next(struct lua_State *L); - int tolua_factionlist_iter(struct lua_State *L); void tolua_faction_open(struct lua_State *L); #ifdef __cplusplus diff --git a/src/bindings/bindings.c b/src/bindings/bindings.c index 09f863ccd..400df4a5c 100644 --- a/src/bindings/bindings.c +++ b/src/bindings/bindings.c @@ -55,6 +55,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -91,6 +92,24 @@ int tolua_orderlist_next(lua_State *L) 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) { 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) { 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"); lua_setmetatable(L, -2); + lua_pushnumber(L, 0); + *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; } @@ -1052,6 +1074,7 @@ tolua_eressea_open(lua_State* L) tolua_usertype(L, TOLUA_CAST "item"); tolua_usertype(L, TOLUA_CAST "alliance"); tolua_usertype(L, TOLUA_CAST "event"); + tolua_usertype(L, TOLUA_CAST "faction_list"); tolua_module(L, NULL, 0); tolua_beginmodule(L, NULL); diff --git a/src/kernel/alliance.c b/src/kernel/alliance.c index cfacb00c2..fc8cbb452 100644 --- a/src/kernel/alliance.c +++ b/src/kernel/alliance.c @@ -33,6 +33,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include @@ -49,11 +50,7 @@ void free_alliance(alliance * al) { free(al->name); - while (al->members) { - faction_list * m = al->members; - al->members = m->next; - free(m); - } + if (al->members) ql_free(al->members); free(al); } @@ -111,7 +108,7 @@ alliance_get_leader(alliance * al) { if (!al->_leader) { if (al->members) { - al->_leader = al->members->data; + al->_leader = (faction *)ql_get(al->members, 0); } } return al->_leader; @@ -120,7 +117,7 @@ alliance_get_leader(alliance * al) static void 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->u = u; tr->next = transactions[type]; @@ -372,24 +369,24 @@ alliancejoin(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!=NULL) { - faction_list ** flistp = &f->alliance->members; - while (*flistp) { - faction_list * flist = *flistp; - if ((*flistp)->data==f) { - *flistp = flist->next; + int qi; + quicklist ** flistp = &f->alliance->members; + + for (qi=0;*flistp;ql_advance(flistp, &qi, 1)) { + faction * data = (faction *)ql_get(*flistp, qi); + if (data==f) { + ql_delete(flistp, qi); break; } - flistp = &flist->next; } if (f->alliance->_leader==f) { if (f->alliance->members) { - f->alliance->_leader = f->alliance->members->data; + f->alliance->_leader = (faction *)ql_get(f->alliance->members, 0); } else { f->alliance->_leader = NULL; } @@ -398,22 +395,11 @@ setalliance(struct faction * f, alliance * al) f->alliance = al; f->alliance_joindate = turn; if (al!=NULL) { - faction_list ** flistp = &al->members; - while (*flistp) { - flistp = &(*flistp)->next; - } - if (flist==NULL) { - flist = malloc(sizeof(faction_list)); - flist->data = f; - } - *flistp = flist; - flist->next = NULL; + ql_push(&al->members, f); if (al->_leader==NULL) { al->_leader = f; } - flist = NULL; } - free(flist); } const char * @@ -456,15 +442,15 @@ alliancevictory(void) } while (al!=NULL) { if (!fval(al, FFL_MARK)) { - faction_list * flist = al->members; - while (flist!=0) { - faction * f = flist->data; + int qi; + quicklist * flist = al->members; + for (qi=0;flist;ql_advance(&flist, &qi, 1)) { + faction * f = (faction *)ql_get(flist, qi); if (f->alliance==al) { ADDMSG(&f->msgs, msg_message("alliance::lost", "alliance", al)); destroyfaction(f); } - flist = flist->next; } } else { 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 }; 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); - faction_list * flist = al->members; + quicklist * flist = al->members; + int qi; boolean found = false; assert(itype!=NULL); - for (;flist && !found;flist=flist->next) { - unit * u = flist->data->units; + for (qi=0;flist && !found;ql_advance(&flist, &qi, 1)) { + 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) { found = true; break; @@ -501,9 +489,11 @@ victorycondition(const alliance * al, const char * name) return 1; } else if (strcmp(name, "phoenix")==0) { - faction_list * flist = al->members; - for (;flist;flist=flist->next) { - faction * f = flist->data; + quicklist * flist = al->members; + int qi; + + for (qi=0;flist;ql_advance(&flist, &qi, 1)) { + faction * f = (faction *)ql_get(flist, qi); if (find_key(f->attribs, atoi36("phnx"))) { return 1; } @@ -527,9 +517,11 @@ victorycondition(const alliance * al, const char * name) * } */ - faction_list * flist = al->members; - for (;flist;flist=flist->next) { - faction * f = flist->data; + quicklist * flist = al->members; + int qi; + + for (qi=0;flist;ql_advance(&flist, &qi, 1)) { + faction * f = (faction *)ql_get(flist, qi); if (find_key(f->attribs, atoi36("pyra"))) { return 1; } diff --git a/src/kernel/alliance.h b/src/kernel/alliance.h index e9cab8b66..e384b0f8f 100644 --- a/src/kernel/alliance.h +++ b/src/kernel/alliance.h @@ -44,7 +44,7 @@ enum { typedef struct alliance { struct alliance * next; struct faction * _leader; - struct faction_list * members; + struct quicklist * members; unsigned int flags; int id; char * name; diff --git a/src/kernel/config.c b/src/kernel/config.c index d0885efd2..4423ad467 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -53,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -60,14 +61,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include #include +#include #include #include -#include -#include /* libxml includes */ #include @@ -507,10 +508,12 @@ allied_skillcount(const faction * f, skill_t sk) { int num = 0; alliance * a = f_get_alliance(f); - faction_list * members = a->members; - while (members!=NULL) { - num += count_skill(members->data, sk); - members=members->next; + quicklist * members = a->members; + int qi; + + for (qi=0;members;ql_advance(&members, &qi, 1)) { + faction * m = (faction *)ql_get(members, qi); + num += count_skill(m, sk); } return num; } diff --git a/src/kernel/reports.c b/src/kernel/reports.c index 7cd973a6c..616c69d1e 100644 --- a/src/kernel/reports.c +++ b/src/kernel/reports.c @@ -924,9 +924,10 @@ get_addresses(report_context * ctx) ql_push(&flist, ctx->f); if (f_get_alliance(ctx->f)) { - faction_list * member = ctx->f->alliance->members; - for (;member;member=member->next) { - ql_set_insert(&flist, member->data); + quicklist * ql = ctx->f->alliance->members; + int qi; + for (qi=0;ql;ql_advance(&ql, &qi, 1)) { + ql_set_insert(&flist, ql_get(ql, qi)); } } diff --git a/src/kernel/save.c b/src/kernel/save.c index ca140d313..19db607ce 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -62,6 +62,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -1178,13 +1179,10 @@ readfaction(struct storage * store) if (allianceid>0) f->alliance = findalliance(allianceid); if (f->alliance) { alliance * al = f->alliance; - faction_list * flist = (faction_list *)malloc(sizeof(faction_list)); if (al->flags&ALF_NON_ALLIED) { assert(!al->members || !"non-allied dummy-alliance has more than one member"); } - flist->data = f; - flist->next = al->members; - al->members = flist; + ql_push(&al->members, f); } else if (rule_region_owners()){ /* compat fix for non-allied factions */ alliance * al = makealliance(0, NULL); diff --git a/src/util/quicklist.c b/src/util/quicklist.c index f5b0bc8bd..e3986eb75 100644 --- a/src/util/quicklist.c +++ b/src/util/quicklist.c @@ -142,6 +142,7 @@ int ql_advance(struct quicklist ** iterator, int * index, int stride) void ql_free(struct quicklist * ql) { + if (!ql) return; if (ql->next) ql_free(ql->next); free(ql); }