From c606a9ac4d75073310ef6634f4c9309f933f0b58 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 22 Sep 2016 20:22:23 +0200 Subject: [PATCH 1/3] extract RC_SPELL handling into a small function, minimize get_race calls. --- src/reports.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/reports.c b/src/reports.c index 681802fd3..ff076a866 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1308,6 +1308,17 @@ static void cb_add_seen(region *r, unit *u, void *cbdata) { } } +static bool unit_cansee(const unit *u) +{ + const race *rc = u_race(u); + static const race *rc_spell; + static int rc_cache; + if (rc_changed(&rc_cache)) { + rc_spell = get_race(RC_SPELL); + } + return (rc!=rc_spell || u->number == RS_FARVISION); +} + /** set region.seen based on visibility by one faction. * * this function may also update ctx->last and ctx->first for potential @@ -1344,7 +1355,7 @@ void prepare_report(report_context *ctx, faction *f) u = building_owner(b); if (u && u->faction==f) { prepare_lighthouse(b, ctx); - if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) { + if (unit_cansee(u)) { add_seen_nb(f, r, seen_unit); } } @@ -1355,7 +1366,7 @@ void prepare_report(report_context *ctx, faction *f) } for (u = r->units; u; u = u->next) { if (u->faction==f) { - if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) { + if (unit_cansee(u)) { add_seen_nb(f, r, seen_unit); } if (fval(r, RF_LIGHTHOUSE)) { From 423e2937456c0956fac09808c6d28a0a88edab13 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Sep 2016 20:36:57 +0200 Subject: [PATCH 2/3] some more config lookup caching --- src/kernel/ally.c | 26 ++++++++++++++------------ src/kernel/config.c | 7 +++++-- src/kernel/faction.c | 22 +++++++++++++++++----- src/kernel/skills.c | 8 ++++++-- src/kernel/unit.c | 17 +++++++++++------ src/magic.c | 6 +++++- src/monsters.c | 7 ++++++- src/study.c | 12 ++++++++++-- src/teleport.c | 8 ++++++-- 9 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 3152ab4b7..2bb980dd0 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -133,19 +133,21 @@ attrib_type at_npcfaction = { */ int HelpMask(void) { - const char *str = config_get("rules.help.mask"); - int rule = 0; - if (str != NULL) { - char *sstr = _strdup(str); - char *tok = strtok(sstr, " "); - while (tok) { - rule |= ally_flag(tok, -1); - tok = strtok(NULL, " "); + static int config, rule = 0; + if (config_changed(&config)) { + const char *str = config_get("rules.help.mask"); + if (str != NULL) { + char *sstr = _strdup(str); + char *tok = strtok(sstr, " "); + while (tok) { + rule |= ally_flag(tok, -1); + tok = strtok(NULL, " "); + } + free(sstr); + } + else { + rule = HELP_ALL; } - free(sstr); - } - else { - rule = HELP_ALL; } return rule; } diff --git a/src/kernel/config.c b/src/kernel/config.c index aaecd2c91..5921535c7 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -731,7 +731,7 @@ int create_directories(void) { double get_param_flt(const struct param *p, const char *key, double def) { - const char *str = get_param(p, key); + const char *str = p ? get_param(p, key) : NULL; return str ? atof(str) : def; } @@ -862,7 +862,10 @@ int cmp_current_owner(const building * b, const building * a) bool rule_stealth_other(void) { - int rule = config_get_int("stealth.faction.other", 1); + static int rule, config; + if (config_changed(&config)) { + rule = config_get_int("stealth.faction.other", 1); + } return rule != 0; } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 823932f88..0ccf62f52 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -796,14 +796,26 @@ attrib_type at_maxmagicians = { int max_magicians(const faction * f) { - int m = config_get_int("rules.maxskills.magic", MAXMAGICIANS); - attrib *a; + static int rule, config, rc_cache; + static const race *rc_elf; + int m; - if ((a = a_find(f->attribs, &at_maxmagicians)) != NULL) { - m = a->data.i; + if (config_changed(&config)) { + rule = config_get_int("rules.maxskills.magic", MAXMAGICIANS); } - if (f->race == get_race(RC_ELF)) + m = rule; + if (f->attribs) { + attrib *a = a_find(f->attribs, &at_maxmagicians); + if (a) { + m = a->data.i; + } + } + if (rc_changed(&rc_cache)) { + rc_elf = get_race(RC_ELF); + } + if (f->race == rc_elf) { ++m; + } return m; } diff --git a/src/kernel/skills.c b/src/kernel/skills.c index 9a6c0f1d7..17e1194c1 100644 --- a/src/kernel/skills.c +++ b/src/kernel/skills.c @@ -184,9 +184,13 @@ void sk_set(skill * sv, int level) sv->level = level; } -static int rule_random_progress(void) +static bool rule_random_progress(void) { - return config_get_int("study.random_progress", 1); + static int rule, config; + if (config_changed(&config)) { + rule = config_get_int("study.random_progress", 1); + } + return rule != 0; } int skill_weeks(int level) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 4623e895e..c5172cafc 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -883,15 +883,16 @@ void leave_building(unit * u) bool can_leave(unit * u) { - int rule_leave; + static int config; + static bool rule_leave; if (!u->building) { return true; } - - rule_leave = config_get_int("rules.move.owner_leave", 0); - - if (rule_leave != 0 && u->building && u == building_owner(u->building)) { + if (config_changed(&config)) { + rule_leave = config_get_int("rules.move.owner_leave", 0) != 0; + } + if (rule_leave && u->building && u == building_owner(u->building)) { return false; } return true; @@ -1721,9 +1722,13 @@ int unit_max_hp(const unit * u) { int h; double p; - int rule_stamina = config_get_int("rules.stamina", STAMINA_AFFECTS_HP); + static int config; + static int rule_stamina; h = u_race(u)->hitpoints; + if (config_changed(&config)) { + rule_stamina = config_get_int("rules.stamina", STAMINA_AFFECTS_HP); + } if (rule_stamina & 1) { p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2; h += (int)(h * p + 0.5); diff --git a/src/magic.c b/src/magic.c index 83899f583..bcf3403aa 100644 --- a/src/magic.c +++ b/src/magic.c @@ -225,7 +225,11 @@ static void free_mage(attrib * a) bool FactionSpells(void) { - return config_get_int("rules.magic.factionlist", 0) != 0; + static int config, rule; + if (config_changed(&config)) { + rule = config_get_int("rules.magic.factionlist", 0); + } + return rule != 0; } void read_spells(struct quicklist **slistp, magic_t mtype, diff --git a/src/monsters.c b/src/monsters.c index 78999e015..ecf768cab 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -84,7 +84,12 @@ static void give_peasants(unit *u, const item_type *itype, int reduce) { } static double random_move_chance(void) { - return config_get_flt("rules.monsters.random_move_chance", MOVECHANCE); + static double rule; + static int config; + if (config_changed(&config)) { + rule = config_get_flt("rules.monsters.random_move_chance", MOVECHANCE); + } + return rule; } static void reduce_weight(unit * u) diff --git a/src/study.c b/src/study.c index eb5cec12d..027f67dde 100644 --- a/src/study.c +++ b/src/study.c @@ -800,7 +800,11 @@ int study_cmd(unit * u, order * ord) } static int produceexp_days(void) { - return config_get_int("study.produceexp", 10); + static int config, rule; + if (config_changed(&config)) { + rule = config_get_int("study.produceexp", 10); + } + return rule; } void produceexp_ex(struct unit *u, skill_t sk, int n, learn_fun learn) @@ -863,7 +867,11 @@ void demon_skillchange(unit *u) if (fval(u, UFL_HUNGER)) { /* hungry demons only go down, never up in skill */ - int rule_hunger = config_get_int("hunger.demon.skill", 0) != 0; + static int config; + static bool rule_hunger; + if (config_changed(&config)) { + rule_hunger = config_get_int("hunger.demon.skill", 0) != 0; + } if (rule_hunger) { upchance = 0; downchance = 15; diff --git a/src/teleport.c b/src/teleport.c index 5b7f71831..c7e775345 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -176,8 +176,12 @@ bool is_astral(const region * r) plane *get_astralplane(void) { plane *astralspace = 0; - int rule_astralplane = config_get_int("modules.astralspace", 1); - + static int config; + static bool rule_astralplane; + + if (config_changed(&config)) { + rule_astralplane = config_get_int("modules.astralspace", 1) != 0; + } if (!rule_astralplane) { return NULL; } From 42c44724f8d1b436d23041be16d00acd9d01cfbb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Sep 2016 17:29:55 +0200 Subject: [PATCH 3/3] testing lazy find_spell calls for equipment configuration --- src/kernel/equipment.c | 42 ++++++++++++++++++++++++++----------- src/kernel/equipment.h | 4 ++-- src/kernel/equipment.test.c | 2 +- src/kernel/xmlreader.c | 20 +++++++----------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/kernel/equipment.c b/src/kernel/equipment.c index 424352347..8266ada9a 100644 --- a/src/kernel/equipment.c +++ b/src/kernel/equipment.c @@ -25,7 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" #include "faction.h" #include "race.h" -#include "spellbook.h" +#include "spell.h" /* util includes */ #include @@ -86,13 +86,20 @@ void equipment_setskill(equipment * eq, skill_t sk, const char *value) } } -void equipment_addspell(equipment * eq, struct spell * sp, int level) +typedef struct lazy_spell { + char *name; + struct spell *sp; + int level; +} lazy_spell; + +void equipment_addspell(equipment * eq, const char * name, int level) { if (eq) { - if (!eq->spellbook) { - eq->spellbook = create_spellbook(0); - } - spellbook_add(eq->spellbook, sp, level); + lazy_spell *ls = malloc(sizeof(lazy_spell)); + ls->sp = NULL; + ls->level = level; + ls->name = _strdup(name); + ql_push(&eq->spells, ls); } } @@ -148,13 +155,18 @@ void equip_unit_mask(struct unit *u, const struct equipment *eq, int mask) } if (mask & EQUIP_SPELLS) { - if (eq->spellbook) { - quicklist * ql = eq->spellbook->spells; + if (eq->spells) { + quicklist * ql = eq->spells; int qi; sc_mage * mage = get_mage(u); for (qi = 0; ql; ql_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *)ql_get(ql, qi); + lazy_spell *sbe = (lazy_spell *)ql_get(ql, qi); + if (!sbe->sp) { + sbe->sp = find_spell(sbe->name); + free(sbe->name); + sbe->name = NULL; + } unit_add_spell(u, mage, sbe->sp, sbe->level); } } @@ -224,6 +236,12 @@ void equip_items(struct item **items, const struct equipment *eq) } } +void free_ls(void *arg) { + lazy_spell *ls = (lazy_spell*)arg; + free(ls->name); + free(ls); +} + void equipment_done(void) { equipment **eqp = &equipment_sets; while (*eqp) { @@ -231,9 +249,9 @@ void equipment_done(void) { equipment *eq = *eqp; *eqp = eq->next; free(eq->name); - if (eq->spellbook) { - spellbook_clear(eq->spellbook); - free(eq->spellbook); + if (eq->spells) { + ql_foreach(eq->spells, free_ls); + ql_free(eq->spells); } while (eq->items) { itemdata *next = eq->items->next; diff --git a/src/kernel/equipment.h b/src/kernel/equipment.h index 11511d99a..5c7b3407b 100644 --- a/src/kernel/equipment.h +++ b/src/kernel/equipment.h @@ -48,7 +48,7 @@ extern "C" { char *name; struct itemdata *items; char *skills[MAXSKILLS]; - struct spellbook *spellbook; + struct quicklist *spells; struct subset *subsets; struct equipment *next; void(*callback) (const struct equipment *, struct unit *); @@ -63,7 +63,7 @@ extern "C" { const struct item_type *itype, const char *value); void equipment_setskill(struct equipment *eq, skill_t sk, const char *value); - void equipment_addspell(struct equipment *eq, struct spell *sp, int level); + void equipment_addspell(struct equipment *eq, const char *name, int level); void equipment_setcallback(struct equipment *eq, void(*callback) (const struct equipment *, struct unit *)); diff --git a/src/kernel/equipment.test.c b/src/kernel/equipment.test.c index 490a44a78..2911af1ea 100644 --- a/src/kernel/equipment.test.c +++ b/src/kernel/equipment.test.c @@ -34,7 +34,7 @@ void test_equipment(CuTest * tc) equipment_setitem(eq, it_horses, "1"); equipment_setskill(eq, SK_MAGIC, "5"); - equipment_addspell(eq, sp, 1); + equipment_addspell(eq, sp->sname, 1); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); equip_unit_mask(u, eq, EQUIP_ALL); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 68f62d11f..66825a9b8 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1191,22 +1191,18 @@ static void add_spells(equipment * eq, xmlNodeSetPtr nsetItems) for (i = 0; i != nsetItems->nodeNr; ++i) { xmlNodePtr node = nsetItems->nodeTab[i]; xmlChar *propValue; - struct spell *sp; + int level; + const char *name; propValue = xmlGetProp(node, BAD_CAST "name"); assert(propValue != NULL); - sp = find_spell((const char *)propValue); - if (!sp) { - log_error("no spell '%s' for equipment-set '%s'\n", (const char *)propValue, eq->name); + name = (const char *)propValue; + level = xml_ivalue(node, "level", 0); + if (level > 0) { + equipment_addspell(eq, name, level); } else { - int level = xml_ivalue(node, "level", 0); - if (level > 0) { - equipment_addspell(eq, sp, level); - } - else { - log_error("spell '%s' for equipment-set '%s' has no level\n", sp->sname, eq->name); - } + log_error("spell '%s' for equipment-set '%s' has no level\n", name, eq->name); } xmlFree(propValue); } @@ -1331,7 +1327,7 @@ static int parse_equipment(xmlDocPtr doc) xmlXPathFreeObject(xpathResult); xpathResult = xmlXPathEvalExpression(BAD_CAST "spell", xpath); - assert(!eq->spellbook); + assert(!eq->spells); add_spells(eq, xpathResult->nodesetval); xmlXPathFreeObject(xpathResult);