From f0c56346d98a385608f33d5a0a3ca7391d20d1d1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 May 2008 09:25:41 +0000 Subject: [PATCH] http://eressea.upb.de/mantis/view.php?id=1431 "buildings and ships are leaking memory" - remove_building and remove_ship work like their region/unit counterparts --- src/common/gamecode/economy.c | 64 +++++++++++++++++------------------ src/common/gamecode/laws.c | 2 +- src/common/gamecode/randenc.c | 50 +++++++++++++-------------- src/common/gamecode/spy.c | 2 +- src/common/kernel/battle.c | 2 +- src/common/kernel/build.c | 4 +-- src/common/kernel/building.c | 38 ++++++++++++++++++--- src/common/kernel/building.h | 5 ++- src/common/kernel/magic.c | 20 +++++------ src/common/kernel/move.c | 17 +++++----- src/common/kernel/region.c | 10 ++---- src/common/kernel/ship.c | 50 +++++++++++++++++++-------- src/common/kernel/ship.h | 5 ++- src/common/modules/wormhole.c | 21 ++++++------ src/common/spells/spells.c | 51 ++++++++++++---------------- src/common/util/lists.c | 25 -------------- src/common/util/lists.h | 2 -- src/eressea/lua/building.cpp | 18 +++++++--- 18 files changed, 206 insertions(+), 180 deletions(-) diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 166a0d89f..1a21d6b0c 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -978,41 +978,41 @@ maintain(building * b, boolean first) static void gebaeude_stuerzt_ein(region * r, building * b) { - unit *u; - int n, i; - int opfer = 0; - int road = 0; - struct message * msg; + unit *u; + int n, i; + int opfer = 0; + int road = 0; + struct message * msg; - for (u = r->units; u; u = u->next) { - if (u->building == b) { - int loss = 0; + for (u = r->units; u; u = u->next) { + if (u->building == b) { + int loss = 0; - fset(u->faction, FFL_MARK); - freset(u, UFL_OWNER); - leave(r,u); - n = u->number; - for (i = 0; i < n; i++) { - if (rng_double() >= COLLAPSE_SURVIVAL) { - ++loss; - } - } - scale_number(u, u->number - loss); - opfer += loss; - } - } + fset(u->faction, FFL_MARK); + freset(u, UFL_OWNER); + leave(r,u); + n = u->number; + for (i = 0; i < n; i++) { + if (rng_double() >= COLLAPSE_SURVIVAL) { + ++loss; + } + } + scale_number(u, u->number - loss); + opfer += loss; + } + } - msg = msg_message("buildingcrash", "region building opfer road", r, b, opfer, road); - add_message(&r->msgs, msg); - for (u=r->units; u; u=u->next) { - faction * f = u->faction; - if (fval(f, FFL_MARK)) { - freset(u->faction, FFL_MARK); - add_message(&f->msgs, msg); - } - } - msg_release(msg); - destroy_building(b); + msg = msg_message("buildingcrash", "region building opfer road", r, b, opfer, road); + add_message(&r->msgs, msg); + for (u=r->units; u; u=u->next) { + faction * f = u->faction; + if (fval(f, FFL_MARK)) { + freset(u->faction, FFL_MARK); + add_message(&f->msgs, msg); + } + } + msg_release(msg); + remove_building(&r->buildings, b); } void diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 5feb5dc0b..cc6810293 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -2485,7 +2485,7 @@ sinkships(region * r) damage_ship(sh, 0.05); } if (sh->damage >= sh->size * DAMAGE_SCALE) { - destroy_ship(sh); + remove_ship(shp, sh); } if (*shp==sh) shp=&sh->next; } diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index 0f8d0f230..0fb0ccdb9 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -427,7 +427,6 @@ void chaos(region * r) { unit *u = NULL, *u2; - building *b, *b2; if (rng_int() % 100 < 8) { switch (rng_int() % 3) { @@ -474,7 +473,9 @@ chaos(region * r) while (sh) { ship * nsh = sh->next; damage_ship(sh, 0.50); - if (sh->damage >= sh->size * DAMAGE_SCALE) destroy_ship(sh); + if (sh->damage >= sh->size * DAMAGE_SCALE) { + remove_ship(&sh->region->ships, sh); + } sh = nsh; } @@ -487,10 +488,8 @@ chaos(region * r) } ADDMSG(&r->msgs, msg_message("tidalwave", "region", r)); - for (b = rbuildings(r); b;) { - b2 = b->next; - destroy_building(b); - b = b2; + while (r->buildings) { + remove_building(&r->buildings, r->buildings); } terraform(r, T_OCEAN); } @@ -760,7 +759,6 @@ melt_iceberg(region *r) { attrib *a; unit *u; - building *b, *b2; for (u=r->units; u; u=u->next) freset(u->faction, FFL_SELECT); for (u=r->units; u; u=u->next) if (!fval(u->faction, FFL_SELECT)) { @@ -773,10 +771,9 @@ melt_iceberg(region *r) if (a) a_remove(&r->attribs, a); /* Gebäude löschen */ - for (b = rbuildings(r); b; b = b2) { - b2 = b->next; - destroy_building(b); - } + while (r->buildings) { + remove_building(&r->buildings, r->buildings); + } /* in Ozean wandeln */ terraform(r, T_OCEAN); @@ -875,7 +872,7 @@ move_iceberg(region *r) ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des", "ship", sh)); } - destroy_ship(sh); + remove_ship(&sh->region->ships, sh); } else if (u!=NULL) { ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg", "ship", sh)); @@ -985,7 +982,7 @@ godcurse(void) unit * u = shipowner(sh); if (u) ADDMSG(&u->faction->msgs, msg_message("godcurse_destroy_ship", "ship", sh)); - destroy_ship(sh); + remove_ship(&sh->region->ships, sh); } sh = shn; } @@ -1122,11 +1119,10 @@ void randomevents(void) { #if KARMA_MODULE - faction *f; + faction *f; #endif /* KARMA_MODULE */ - region *r; - building *b, *b2; - unit *u; + region *r; + unit *u; icebergs(); godcurse(); @@ -1191,14 +1187,16 @@ randomevents(void) /* Monumente zerfallen, Schiffe verfaulen */ for (r = regions; r; r = r->next) { - for (b = rbuildings(r); b; b = b2) { - b2 = b->next; + building ** blist = &r->buildings; + while (*blist) { + building * b = *blist; if (fval(b->type, BTF_DECAY) && !buildingowner(r, b)) { b->size -= max(1, (b->size * 20) / 100); if (b->size == 0) { - destroy_building(b); + remove_building(blist, r->buildings); } } + if (*blist==b) blist=&b->next; } } @@ -1213,7 +1211,7 @@ randomevents(void) "unit region", u, r)); u_setfaction(u, get_monsters()); } - } + } } } @@ -1226,7 +1224,7 @@ randomevents(void) for(u = f->units; u; u=u->nextF) { if (rng_int()%100 < 2*level) { ADDMSG(&u->faction->msgs, - msg_message("becomewere", "unit region", u, u->region)); + msg_message("becomewere", "unit region", u, u->region)); fset(u, UFL_WERE); } } @@ -1245,16 +1243,16 @@ randomevents(void) if (!i) continue; chaoscounts(r, -(int) (i * ((double) (rng_int() % 10)) / 100.0)); } - + #ifdef HERBS_ROT /* Kräuter verrotten */ for (r = regions; r; r = r->next) { for (u = r->units; u; u=u->next) { item **itmp = &u->items, *hbag = *i_find(&u->items, olditemtype[I_SACK_OF_CONSERVATION]); int rot_chance = HERBROTCHANCE; - + if (hbag) rot_chance = (HERBROTCHANCE*2)/5; - + while (*itmp) { item * itm = *itmp; int n = itm->number; @@ -1270,7 +1268,7 @@ randomevents(void) } } #endif - + dissolve_units(); check_split(); #if KARMA_MODULE diff --git a/src/common/gamecode/spy.c b/src/common/gamecode/spy.c index 4a28851de..9c79284a2 100644 --- a/src/common/gamecode/spy.c +++ b/src/common/gamecode/spy.c @@ -566,7 +566,7 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur) if (enemy_discovers_spy_msg) msg_release(enemy_discovers_spy_msg); if (sink_msg) msg_release(sink_msg); /* finally, get rid of the ship */ - destroy_ship(sh); + remove_ship(&sh->region->ships, sh); vset_destroy(&informed); vset_destroy(&survivors); } diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 74308410f..3b4da4c16 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -2572,7 +2572,7 @@ aftermath(battle * b) ship * sh = *sp; freset(sh, SF_DAMAGED); if (sh->damage >= sh->size * DAMAGE_SCALE) { - destroy_ship(sh); + remove_ship(sp, sh); } if (*sp==sh) sp=&sh->next; } diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index b0e0f6cee..ffc060047 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -384,7 +384,7 @@ destroy_cmd(unit * u, struct order * ord) ADDMSG(&u->faction->msgs, msg_message("destroy", "building unit", b, u)); con = b->type->construction; - destroy_building(b); + remove_building(&r->buildings, b); } else { /* partial destroy */ b->size -= n; @@ -411,7 +411,7 @@ destroy_cmd(unit * u, struct order * ord) ADDMSG(&u->faction->msgs, msg_message("shipdestroy", "unit region ship", u, r, sh)); con = sh->type->construction; - destroy_ship(sh); + remove_ship(&sh->region->ships, sh); } else { /* partial destroy */ sh->size -= (sh->type->construction->maxsize * n)/100; diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index def3e82ff..bb4b375aa 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -394,7 +394,7 @@ read_building_reference(struct building ** b, struct storage * store) *b = findbuilding(var.i); if (*b==NULL) ur_add(var, (void**)b, resolve_building); return AT_READ_OK; - } + } } void @@ -452,8 +452,13 @@ new_building(const struct building_type * btype, region * r, const struct locale return b; } +static building * deleted_buildings; + +/** remove a building from the region. + * remove_building lets units leave the building + */ void -destroy_building(building * b) +remove_building(building ** blist, building * b) { unit *u; direction_t d; @@ -467,7 +472,9 @@ destroy_building(building * b) bt_tunnel = bt_find("tunnel"); } - if (!bfindhash(b->no)) return; + assert(bfindhash(b->no)); + + handle_event(b->attribs, "destroy", b); for (u=b->region->units; u; u=u->next) { if (u->building == b) leave(b->region, u); } @@ -486,8 +493,29 @@ destroy_building(building * b) } /* Stattdessen nur aus Liste entfernen, aber im Speicher halten. */ - choplist(&b->region->buildings, b); - handle_event(b->attribs, "destroy", b); + while (*blist && *blist!=b) blist = &(*blist)->next; + *blist = b->next; + b->region = NULL; + b->next = deleted_buildings; + deleted_buildings = b; +} + +void +free_building(building * b) +{ + while (b->attribs) a_remove (&b->attribs, b->attribs); + free(b->name); + free(b->display); + free(b); +} + +void +free_buildings(void) +{ + while (deleted_buildings) { + building * b = deleted_buildings; + deleted_buildings = b->next; + } } extern struct attrib_type at_icastle; diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index ac1d1866c..e44f49620 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -123,7 +123,10 @@ int buildingeffsize(const building * b, boolean img); void bhash(struct building * b); void bunhash(struct building * b); int buildingcapacity(const struct building * b); -void destroy_building(struct building * b); + +extern void remove_building(struct building * *blist, struct building * b); +extern void free_building(struct building * b); +extern void free_buildings(void); const struct building_type * findbuildingtype(const char * name, const struct locale * lang); diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index a049f4c8e..183d01f36 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -144,17 +144,17 @@ a_writeicastle(const attrib * a, struct storage * store) static int a_ageicastle(struct attrib * a) { - icastle_data * data = (icastle_data*)a->data.v; - if (data->time<=0) { - building * b = data->building; - region * r = b->region; + icastle_data * data = (icastle_data*)a->data.v; + if (data->time<=0) { + building * b = data->building; + region * r = b->region; ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b)); - /* destroy_building lets units leave the building */ - destroy_building(b); - return 0; - } - else data->time--; - return 1; + /* remove_building lets units leave the building */ + remove_building(&r->buildings, b); + return 0; + } + else data->time--; + return 1; } static void diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index 80c353b92..451e50707 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -481,23 +481,24 @@ static ship * do_maelstrom(region *r, unit *u) { int damage; + ship * sh = u->ship; damage = rng_int()%150 - eff_skill(u, SK_SAILING, r)*5; if (damage <= 0) { - return u->ship; + return sh; } damage_ship(u->ship, 0.01*damage); - if (u->ship->damage >= u->ship->size * DAMAGE_SCALE) { + if (sh->damage >= sh->size * DAMAGE_SCALE) { ADDMSG(&u->faction->msgs, msg_message("entermaelstrom", - "region ship damage sink", r, u->ship, damage, 1)); - destroy_ship(u->ship); + "region ship damage sink", r, sh, damage, 1)); + remove_ship(&sh->region->ships, sh); return NULL; } ADDMSG(&u->faction->msgs, msg_message("entermaelstrom", - "region ship damage sink", r, u->ship, damage, 0)); + "region ship damage sink", r, sh, damage, 0)); return u->ship; } @@ -776,7 +777,7 @@ drifting_ships(region * r) damage_ship(sh, 0.02); if (sh->damage>=sh->size * DAMAGE_SCALE) { - destroy_ship(sh); + remove_ship(shp, sh); } } @@ -1782,7 +1783,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep) if (sh->damage>=sh->size * DAMAGE_SCALE) { ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh)); - destroy_ship(sh); + remove_ship(&sh->region->ships, sh); sh = NULL; } @@ -2322,7 +2323,7 @@ destroy_damaged_ships(void) for(sh=r->ships;sh;) { shn = sh->next; if (sh->damage>=sh->size * DAMAGE_SCALE) { - destroy_ship(sh); + remove_ship(&sh->region->ships, sh); } sh = shn; } diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 2156c12ce..0468aee80 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -951,19 +951,15 @@ free_region(region * r) while (r->buildings) { building * b = r->buildings; r->buildings = b->next; - bunhash(b); - free(b->name); - free(b->display); - free(b); + bunhash(b); /* must be done here, because remove_building does it, and wasn't called */ + free_building(b); } while (r->ships) { ship * s = r->ships; r->ships = s->next; sunhash(s); - free(s->name); - free(s->display); - free(s); + free_ship(s); } free(r); diff --git a/src/common/kernel/ship.c b/src/common/kernel/ship.c index 5bfc514c5..11229decd 100644 --- a/src/common/kernel/ship.c +++ b/src/common/kernel/ship.c @@ -24,6 +24,7 @@ #include "skill.h" /* util includes */ +#include #include #include #include @@ -162,32 +163,33 @@ captain(ship *sh, region *r) } /* Alte Schiffstypen: */ - +static ship * deleted_ships; ship * new_ship(const ship_type * stype, const struct locale * lang, region * r) { - static char buffer[7 + IDSIZE + 1]; - ship *sh = (ship *) calloc(1, sizeof(ship)); + static char buffer[7 + IDSIZE + 1]; + ship *sh = (ship *) calloc(1, sizeof(ship)); - sh->no = newcontainerid(); - sh->coast = NODIRECTION; - sh->type = stype; - sh->region = r; + sh->no = newcontainerid(); + sh->coast = NODIRECTION; + sh->type = stype; + sh->region = r; - sprintf(buffer, "%s %s", LOC(lang, stype->name[0]), shipid(sh)); - sh->name = strdup(buffer); - shash(sh); + sprintf(buffer, "%s %s", LOC(lang, stype->name[0]), shipid(sh)); + sh->name = strdup(buffer); + shash(sh); addlist(&r->ships, sh); - return sh; + return sh; } void -destroy_ship(ship * sh) +remove_ship(ship ** slist, ship * sh) { region * r = sh->region; unit * u = r->units; + handle_event(sh->attribs, "destroy", sh); while (u) { if (u->ship == sh) { leave_ship(u); @@ -195,8 +197,28 @@ destroy_ship(ship * sh) u = u->next; } sunhash(sh); - choplist(&r->ships, sh); - handle_event(sh->attribs, "destroy", sh); + while (*slist && *slist!=sh) slist = &(*slist)->next; + *slist = sh->next; + sh->next = deleted_ships; + deleted_ships = sh; +} + +void +free_ship(ship * s) +{ + while (s->attribs) a_remove(&s->attribs, s->attribs); + free(s->name); + free(s->display); + free(s); +} + +void +free_ships(void) +{ + while (deleted_ships) { + ship * s = deleted_ships; + deleted_ships = s->next; + } } const char * diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index f5d1bc5cd..af8bc6e72 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -97,7 +97,10 @@ extern const struct ship_type * findshiptype(const char *s, const struct locale extern void register_ships(void); extern void write_ship_reference(const struct ship * sh, struct storage * store); -extern void destroy_ship(struct ship * s); +extern void remove_ship(struct ship ** slist, struct ship * s); +extern void free_ship(struct ship * s); +extern void free_ships(void); + #ifdef __cplusplus } diff --git a/src/common/modules/wormhole.c b/src/common/modules/wormhole.c index 7eee84fba..939aface1 100644 --- a/src/common/modules/wormhole.c +++ b/src/common/modules/wormhole.c @@ -23,10 +23,12 @@ #include #include #include +#include /* util includes */ #include #include +#include #include /* libc includes */ @@ -51,7 +53,7 @@ cmp_age(const void * v1, const void *v2) typedef struct wormhole_data { building * entry; - building * exit; + region * exit; } wormhole_data; static void @@ -80,10 +82,10 @@ wormhole_age(struct attrib * a) if (u->number>maxtransport || has_limited_skills(u)) { m = msg_message("wormhole_requirements", "unit region", u, u->region); } else if (data->exit!=NULL) { - move_unit(u, data->exit->region, NULL); + move_unit(u, data->exit, NULL); maxtransport -= u->number; - m = msg_message("wormhole_exit", "unit region", u, data->exit->region); - add_message(&data->exit->region->msgs, m); + m = msg_message("wormhole_exit", "unit region", u, data->exit); + add_message(&data->exit->msgs, m); } if (m!=NULL) { add_message(&u->faction->msgs, m); @@ -92,11 +94,8 @@ wormhole_age(struct attrib * a) } } - /* it's important that destroy_building doesn't change b->region, because - * otherwise the tunnel would no longer be bi-directional after this */ - destroy_building(data->entry); + remove_building(&r->buildings, data->entry); ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r)); - assert(data->entry->region==r); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ return -1; @@ -140,8 +139,10 @@ make_wormhole(const building_type * bt_wormhole, region * r1, region * r2) attrib * a2 = a_add(&b2->attribs, a_new(&at_wormhole)); wormhole_data * d1 = (wormhole_data*)a1->data.v; wormhole_data * d2 = (wormhole_data*)a2->data.v; - d1->entry = d2->exit = b1; - d2->entry = d1->exit = b2; + d1->entry = b1; + d2->entry = b2; + d1->exit = b2->region; + d2->exit = b1->region; b1->size = bt_wormhole->maxsize; b2->size = bt_wormhole->maxsize; ADDMSG(&r1->msgs, msg_message("wormhole_appear", "region", r1)); diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 81c3d5bea..d95ac5b28 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -1604,7 +1604,6 @@ destroy_all_roads(region *r) static int sp_great_drought(castorder *co) { - building *b, *b2; unit *u; boolean terraform = false; region *r = co->rt; @@ -1664,10 +1663,8 @@ sp_great_drought(castorder *co) set_number(u, 0); } } - for (b = r->buildings; b;) { - b2 = b->next; - destroy_building(b); - b = b2; + while (r->buildings) { + remove_building(&r->buildings, r->buildings); } } break; @@ -2271,39 +2268,28 @@ static int sp_earthquake(castorder *co) { int kaputt; - building *burg; - unit *u; region *r = co->rt; unit *mage = co->magician.u; int cast_level = co->level; message * msg; + building **blist = &r->buildings; - for (burg = r->buildings; burg; burg = burg->next) { - if (burg->size == 0 ) - continue; + while (*blist) { + building * burg = *blist; - /* Schutzzauber */ - if (is_cursed(burg->attribs, C_MAGICWALLS, 0)) - continue; - - /* Magieresistenz */ - if (target_resists_magic(mage, burg, TYP_BUILDING, 0)) - continue; - - kaputt = min(10 * cast_level, burg->size / 4); - kaputt = max(kaputt, 1); - burg->size -= kaputt; - if (burg->size == 0 ) { - /* alle Einheiten hinausbefördern */ - for(u = r->units; u; u = u->next ) { - if (u->building == burg ) { - u->building = 0; - freset(u, UFL_OWNER); + if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) { + /* Magieresistenz */ + if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) { + kaputt = min(10 * cast_level, burg->size / 4); + kaputt = max(kaputt, 1); + burg->size -= kaputt; + if (burg->size == 0) { + /* TODO: sollten die Insassen nicht Schaden nehmen? */ + remove_building(blist, burg); } } - /* TODO: sollten die Insassen nicht Schaden nehmen? */ - destroy_building(burg); } + if (*blist==burg) blist=&burg->next; } /* melden, 1x pro Partei */ @@ -3198,11 +3184,16 @@ dc_read_compat(struct attrib * a, storage * store) variant var; int duration = store->r_int(store); double strength = store->r_flt(store); + short rx, ry; var.i = store->r_id(store); u = findunit(var.i); - read_region_reference(&r, store); + /* this only affects really old data. no need to change: */ + rx = store->r_int(store); + ry = store->r_int(store); + r = findregion(rx, ry); + if (r!=NULL) { variant effect; curse * c; diff --git a/src/common/util/lists.c b/src/common/util/lists.c index 671464a20..9bbfcbb4f 100644 --- a/src/common/util/lists.c +++ b/src/common/util/lists.c @@ -87,16 +87,6 @@ insertlist(void_list ** l, void_list * p) } -void -promotelist(void *l, void *p) -{ - - /* remove entry p from list l; insert p again at the beginning of l */ - - choplist(l, p); - insertlist((void_list **)l, (void_list *)p); -} - void removelist(void *l, void *p) { @@ -124,21 +114,6 @@ freelist(void *p1) } } -void -invert_list(void * heap) -{ - void_list * x = NULL; - void_list * m = *(void_list**)heap; - while (m) - { - void_list * d = m; - m = m->next; - d->next = x; - x = d; - } - *(void **)heap = x; -} - unsigned int listlen(void *l) { diff --git a/src/common/util/lists.h b/src/common/util/lists.h index 1dfdd5c4b..557ce0553 100644 --- a/src/common/util/lists.h +++ b/src/common/util/lists.h @@ -39,7 +39,6 @@ typedef struct void_list { void addlist(void *l1, void *p1); void choplist(void * l, void * p); void translist(void *l1, void *l2, void *p); -void promotelist(void *l, void *p); #ifndef MALLOCDBG void freelist(void *p1); void removelist(void *l, void *p); @@ -49,7 +48,6 @@ void removelist(void *l, void *p); #endif unsigned int listlen(void *l); -void invert_list(void * heap); #define addlist2(l, p) (*l = p, l = &p->next) void *listelem(void *l, int n); diff --git a/src/eressea/lua/building.cpp b/src/eressea/lua/building.cpp index 272de8bdd..878469829 100644 --- a/src/eressea/lua/building.cpp +++ b/src/eressea/lua/building.cpp @@ -118,11 +118,21 @@ building_getregion(const building& b) } static void -building_setregion(building& b, region& r) +building_setregion(building& bld, region& r) { - choplist(&b.region->buildings, &b); - addlist(&r.buildings, &b); - b.region = &r; + building * b = &bld; + building ** blist = &b->region->buildings; + while (*blist && *blist!=b) { + blist = &(*blist)->next; + } + *blist = b->next; + b->next = NULL; + + blist = &r.buildings; + while (*blist && *blist!=b) blist = &(*blist)->next; + *blist = b; + + b->region = &r; } static std::ostream&