From d9167b8a5919f97a78afd7e24c36bbb5d5b0ae09 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 09:53:23 +0100 Subject: [PATCH 1/6] do not use late resolution for factions, ever --- src/attributes/attributes.c | 2 +- src/kernel/faction.c | 11 ++--------- src/kernel/faction.h | 5 +---- src/kernel/save.c | 7 +++---- src/triggers/changefaction.c | 2 +- src/triggers/createunit.c | 2 +- 6 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 400282ae7..12cb9131f 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -98,7 +98,7 @@ static int obs_read(variant *var, void *owner, struct gamedata *data) obs_data *od = (obs_data *)var->v; UNUSED_ARG(owner); - read_faction_reference(data, &od->f, NULL); + read_faction_reference(data, &od->f); READ_INT(data->store, &od->skill); READ_INT(data->store, &od->timer); return AT_READ_OK; diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 9265d4a8e..f36ef5f8c 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -54,7 +54,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include #include #include @@ -331,20 +330,14 @@ bool checkpasswd(const faction * f, const char *passwd) return true; } -void resolve_faction(faction *f) -{ - resolve(RESOLVE_FACTION | f->no, f); -} - -int read_faction_reference(gamedata * data, faction **fp, resolve_fun fun) +int read_faction_reference(gamedata * data, faction **fp) { int id; READ_INT(data->store, &id); if (id > 0) { *fp = findfaction(id); if (*fp == NULL) { - *fp = NULL; - ur_add(RESOLVE_FACTION | id, (void **)fp, fun); + *fp = faction_create(id); } } else { diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 04070c91a..0c579603a 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -133,10 +133,7 @@ extern "C" { void write_faction_reference(const struct faction *f, struct storage *store); - int read_faction_reference(struct gamedata *data, struct faction **fp, resolve_fun fun); - -#define RESOLVE_FACTION (TYP_FACTION << 24) - void resolve_faction(struct faction *f); + int read_faction_reference(struct gamedata *data, struct faction **fp); void renumber_faction(faction * f, int no); void free_factions(void); diff --git a/src/kernel/save.c b/src/kernel/save.c index 8c4b408c9..928c1938a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -123,7 +123,7 @@ static void read_alliances(gamedata *data) READ_INT(store, &al->flags); } if (data->version >= ALLIANCELEADER_VERSION) { - read_faction_reference(data, &al->_leader, NULL); + read_faction_reference(data, &al->_leader); READ_INT(store, &id); } else { @@ -248,7 +248,7 @@ static void read_owner(gamedata *data, region_owner ** powner) owner->flags = 0; } if (data->version >= OWNER_3_VERSION) { - read_faction_reference(data, &owner->last_owner, NULL); + read_faction_reference(data, &owner->last_owner); } else if (data->version >= OWNER_2_VERSION) { int id; @@ -261,7 +261,7 @@ static void read_owner(gamedata *data, region_owner ** powner) else { owner->last_owner = NULL; } - read_faction_reference(data, &owner->owner, NULL); + read_faction_reference(data, &owner->owner); *powner = owner; } else { @@ -1087,7 +1087,6 @@ faction *read_faction(gamedata * data) if (data->version >= REGIONOWNER_VERSION) { read_spellbook(FactionSpells() ? &f->spellbook : 0, data, get_spell_level_faction, (void *)f); } - resolve_faction(f); return f; } diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c index 8aa73168d..8b1ead479 100644 --- a/src/triggers/changefaction.c +++ b/src/triggers/changefaction.c @@ -87,7 +87,7 @@ static int changefaction_read(trigger * t, gamedata *data) changefaction_data *td = (changefaction_data *)t->data.v; read_unit_reference(data, &td->unit, NULL); - return read_faction_reference(data, &td->faction, NULL) > 0 ? AT_READ_OK : AT_READ_FAIL; + return read_faction_reference(data, &td->faction) > 0 ? AT_READ_OK : AT_READ_FAIL; } trigger_type tt_changefaction = { diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index d4dd8f983..5adabc7ea 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -94,7 +94,7 @@ static int createunit_read(trigger * t, gamedata *data) int id; int result = AT_READ_OK; - id = read_faction_reference(data, &td->f, NULL); + id = read_faction_reference(data, &td->f); if (id <= 0) { result = AT_READ_FAIL; } From 85fe80d858d9939b0097533d70df9a8031468d89 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 10:16:49 +0100 Subject: [PATCH 2/6] unit_create function instead of wild calloc calls. --- src/kernel/save.c | 5 +---- src/kernel/unit.c | 12 +++++++----- src/kernel/unit.h | 7 ++++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index 928c1938a..ceaf78ee1 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -420,10 +420,7 @@ unit *read_unit(gamedata *data) u_setfaction(u, NULL); } else { - u = (unit *)calloc(1, sizeof(unit)); - assert_alloc(u); - u->no = n; - uhash(u); + u = unit_create(n); } READ_INT(data->store, &n); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index d0737eaba..8b2248d39 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1375,6 +1375,12 @@ void name_unit(unit * u) } } +unit *unit_create(int id) +{ + unit *u = (unit *)calloc(1, sizeof(unit)); + createunitid(u, id); + return u; +} /** creates a new unit. * * @param dname: name, set to NULL to get a default. @@ -1383,7 +1389,7 @@ void name_unit(unit * u) unit *create_unit(region * r, faction * f, int number, const struct race *urace, int id, const char *dname, unit * creator) { - unit *u = (unit *)calloc(1, sizeof(unit)); + unit *u = unit_create(id); assert(urace); u_setrace(u, urace); @@ -1395,10 +1401,6 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, set_number(u, number); - /* die nummer der neuen einheit muss vor name_unit generiert werden, - * da der default name immer noch 'Nummer u->no' ist */ - createunitid(u, id); - /* zuerst in die Region setzen, da zb Drachennamen den Regionsnamen * enthalten */ if (r) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 86c2e2e61..e08ca1ef3 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -206,10 +206,11 @@ extern "C" { int invisible(const struct unit *target, const struct unit *viewer); void free_unit(struct unit *u); - extern void name_unit(struct unit *u); - extern struct unit *create_unit(struct region *r1, struct faction *f, + void name_unit(struct unit *u); + struct unit *unit_create(int id); + struct unit *create_unit(struct region *r1, struct faction *f, int number, const struct race *rc, int id, const char *dname, - struct unit *creator); + struct unit *creator); void uhash(struct unit *u); void uunhash(struct unit *u); From ba9af6d765eb250ababad9bc4f67b7e80761eb0b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:08:59 +0100 Subject: [PATCH 3/6] 1. region_create(uid) 2. read_region_reference never gets a callback, so save it. --- src/attributes/targetregion.c | 2 +- src/kernel/curse.c | 2 +- src/kernel/region.c | 33 ++++++++++++++++++--------------- src/kernel/region.h | 3 ++- src/triggers/createunit.c | 2 +- src/triggers/gate.c | 2 +- src/wormhole.c | 2 +- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/attributes/targetregion.c b/src/attributes/targetregion.c index 600d2e184..4f5a2101a 100644 --- a/src/attributes/targetregion.c +++ b/src/attributes/targetregion.c @@ -36,7 +36,7 @@ write_targetregion(const variant *var, const void *owner, struct storage *store) static int read_targetregion(variant *var, void *owner, gamedata *data) { - if (read_region_reference(data, (region **)&var->v, NULL) <= 0) { + if (read_region_reference(data, (region **)&var->v) <= 0) { return AT_READ_FAIL; } return AT_READ_OK; diff --git a/src/kernel/curse.c b/src/kernel/curse.c index 62e7ab9b2..bf3c8fef0 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -229,7 +229,7 @@ int curse_read(variant *var, void *owner, gamedata *data) READ_INT(store, &c->data.i); } if (c->type->typ == CURSETYP_REGION) { - int rr = read_region_reference(data, (region **)&c->data.v, NULL); + int rr = read_region_reference(data, (region **)&c->data.v); if (ur == 0 && rr == 0 && !c->data.v) { return AT_READ_FAIL; } diff --git a/src/kernel/region.c b/src/kernel/region.c index fee51d13c..192469b8e 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -242,7 +242,7 @@ static void unhash_uid(region * r) uidhash[key].r = NULL; } -static void hash_uid(region * r) +static void rhash_uid(region * r) { int uid = r->uid; for (;;) { @@ -761,32 +761,35 @@ static region *last; static unsigned int max_index = 0; +region *region_create(int uid) +{ + region *r = (region *)calloc(1, sizeof(region)); + assert_alloc(r); + r->uid = uid; + rhash_uid(r); + return r; +} + region *new_region(int x, int y, struct plane *pl, int uid) { region *r; pnormalize(&x, &y, pl); r = rfindhash(x, y); - - if (r) { - log_error("duplicate region discovered: %s(%d,%d)\n", regionname(r, NULL), x, y); - if (r->units) - log_error("duplicate region contains units\n"); - return r; + if (!r) { + r = region_create(uid); } - r = (region *)calloc(sizeof(region), 1); - assert_alloc(r); r->x = x; r->y = y; - r->uid = uid; r->age = 1; r->_plane = pl; rhash(r); - hash_uid(r); - if (last) + if (last) { addlist(&last, r); - else + } + else { addlist(®ions, r); + } last = r; assert(r->next == NULL); r->index = ++max_index; @@ -1263,7 +1266,7 @@ void resolve_region(region *r) resolve(RESOLVE_REGION | r->uid, r); } -int read_region_reference(gamedata * data, region **rp, resolve_fun fun) +int read_region_reference(gamedata * data, region **rp) { struct storage * store = data->store; int id = 0; @@ -1271,7 +1274,7 @@ int read_region_reference(gamedata * data, region **rp, resolve_fun fun) READ_INT(store, &id); *rp = findregionbyid(id); if (*rp == NULL) { - ur_add(RESOLVE_REGION | id, (void **)rp, fun); + ur_add(RESOLVE_REGION | id, (void **)rp, NULL); } return id; } diff --git a/src/kernel/region.h b/src/kernel/region.h index bf932e9c3..436434024 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -225,6 +225,7 @@ extern "C" { const char *write_regionname(const struct region *r, const struct faction *f, char *buffer, size_t size); + struct region *region_create(int uid); struct region *new_region(int x, int y, struct plane *pl, int uid); void remove_region(region ** rlist, region * r); void terraform_region(struct region *r, const struct terrain_type *terrain); @@ -252,7 +253,7 @@ extern "C" { #define RESOLVE_REGION (TYP_REGION << 24) void resolve_region(region *r); void write_region_reference(const struct region *r, struct storage *store); - int read_region_reference(struct gamedata *data, region **rp, resolve_fun fun); + int read_region_reference(struct gamedata *data, region **rp); const char *regionname(const struct region *r, const struct faction *f); diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index 5adabc7ea..82155de55 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -99,7 +99,7 @@ static int createunit_read(trigger * t, gamedata *data) result = AT_READ_FAIL; } - read_region_reference(data, &td->r, NULL); + read_region_reference(data, &td->r); td->race = read_race_reference(data->store); if (!td->race) { result = AT_READ_FAIL; diff --git a/src/triggers/gate.c b/src/triggers/gate.c index 065be8cf8..bd67e56f4 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -76,7 +76,7 @@ static int gate_read(trigger * t, gamedata *data) { gate_data *gd = (gate_data *)t->data.v; int bc = read_building_reference(data, &gd->gate, NULL); - int rc = read_region_reference(data, &gd->target, NULL); + int rc = read_region_reference(data, &gd->target); if (bc <= 0 && rc <= 0) { return AT_READ_FAIL; diff --git a/src/wormhole.c b/src/wormhole.c index 382e64d16..1ce6686c9 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -103,7 +103,7 @@ static int wormhole_read(variant *var, void *owner, struct gamedata *data) if (data->version < ATTRIBOWNER_VERSION) { READ_INT(data->store, NULL); } - id = read_region_reference(data, (region **)&var->v, NULL); + id = read_region_reference(data, (region **)&var->v); return (id <= 0) ? AT_READ_FAIL : AT_READ_OK; } From fc4f32f8e0044d5d62d4947906b78659002c4be2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:13:05 +0100 Subject: [PATCH 4/6] read_building_reference does not need a callback --- src/kernel/building.c | 4 ++-- src/kernel/building.h | 2 +- src/modules/xmas.c | 2 +- src/triggers/gate.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 3a3d7e4e5..8cbe5c180 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -359,7 +359,7 @@ void resolve_building(building *b) resolve(RESOLVE_BUILDING | b->no, b); } -int read_building_reference(gamedata * data, building **bp, resolve_fun fun) +int read_building_reference(gamedata * data, building **bp) { int id; READ_INT(data->store, &id); @@ -367,7 +367,7 @@ int read_building_reference(gamedata * data, building **bp, resolve_fun fun) *bp = findbuilding(id); if (*bp == NULL) { *bp = NULL; - ur_add(RESOLVE_BUILDING | id, (void**)bp, fun); + ur_add(RESOLVE_BUILDING | id, (void**)bp, NULL); } } else { diff --git a/src/kernel/building.h b/src/kernel/building.h index af605b448..2a0a77cde 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -166,7 +166,7 @@ extern "C" { void resolve_building(building *b); void write_building_reference(const struct building *b, struct storage *store); - int read_building_reference(struct gamedata * data, struct building **bp, resolve_fun fun); + int read_building_reference(struct gamedata * data, struct building **bp); struct building *findbuilding(int n); diff --git a/src/modules/xmas.c b/src/modules/xmas.c index aa296866a..a8b87026a 100644 --- a/src/modules/xmas.c +++ b/src/modules/xmas.c @@ -50,7 +50,7 @@ static void xmasgate_write(const trigger * t, struct storage *store) static int xmasgate_read(trigger * t, struct gamedata *data) { - if (read_building_reference(data, (building **)&t->data.v, NULL) <= 0) { + if (read_building_reference(data, (building **)&t->data.v) <= 0) { return AT_READ_FAIL; } return AT_READ_OK; diff --git a/src/triggers/gate.c b/src/triggers/gate.c index bd67e56f4..ac3e44b88 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -75,7 +75,7 @@ static void gate_write(const trigger * t, struct storage *store) static int gate_read(trigger * t, gamedata *data) { gate_data *gd = (gate_data *)t->data.v; - int bc = read_building_reference(data, &gd->gate, NULL); + int bc = read_building_reference(data, &gd->gate); int rc = read_region_reference(data, &gd->target); if (bc <= 0 && rc <= 0) { From 25b5f797e9627042dc97aa130389944f992d46cb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:18:24 +0100 Subject: [PATCH 5/6] add building_create, too --- src/kernel/building.c | 17 +++++++++++------ src/kernel/building.h | 3 ++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 8cbe5c180..456ad1704 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -366,8 +366,7 @@ int read_building_reference(gamedata * data, building **bp) if (id > 0) { *bp = findbuilding(id); if (*bp == NULL) { - *bp = NULL; - ur_add(RESOLVE_BUILDING | id, (void**)bp, NULL); + *bp = building_create(id); } } else { @@ -376,17 +375,23 @@ int read_building_reference(gamedata * data, building **bp) return id; } +building *building_create(int id) +{ + building *b = (building *)calloc(1, sizeof(building)); + b->no = id; + bhash(b); + return b; +} + building *new_building(const struct building_type * btype, region * r, const struct locale * lang) { building **bptr = &r->buildings; - building *b = (building *)calloc(1, sizeof(building)); + int id = newcontainerid(); + building *b = building_create(id); const char *bname; char buffer[32]; - b->no = newcontainerid(); - bhash(b); - b->type = btype; b->region = r; while (*bptr) diff --git a/src/kernel/building.h b/src/kernel/building.h index 2a0a77cde..a5419325f 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -127,8 +127,9 @@ extern "C" { const char *write_buildingname(const building * b, char *ibuf, size_t size); int buildingcapacity(const struct building *b); + struct building *building_create(int id); struct building *new_building(const struct building_type *typ, - struct region *r, const struct locale *lang); + struct region *r, const struct locale *lang); int build_building(struct unit *u, const struct building_type *typ, int id, int size, struct order *ord); bool building_finished(const struct building *b); From a2fe396b68e9406e0f78bd8a4a3b902637300660 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:20:11 +0100 Subject: [PATCH 6/6] do not delayed-resolve regions --- src/kernel/region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/region.c b/src/kernel/region.c index 192469b8e..f665811d7 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1274,7 +1274,7 @@ int read_region_reference(gamedata * data, region **rp) READ_INT(store, &id); *rp = findregionbyid(id); if (*rp == NULL) { - ur_add(RESOLVE_REGION | id, (void **)rp, NULL); + *rp = region_create(id); } return id; }