From fe29f2433ae4cdb2c2bf2e57b56c2dcfcd9c22ce Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 10 Feb 2018 16:50:05 +0100 Subject: [PATCH] convert multiple seenspell attributes to single seenspells list. faster? maybe. --- src/attributes/attributes.c | 2 +- src/attributes/seenspell.c | 109 ++++++++++++++++++++++++++++-------- src/attributes/seenspell.h | 3 +- 3 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index e6887a777..cfa99fcfd 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -179,8 +179,8 @@ void register_attributes(void) at_register(&at_mage); at_register(&at_countdown); at_register(&at_curse); - at_register(&at_seenspell); + at_register(&at_seenspells); /* neue REGION-Attribute */ at_register(&at_moveblock); diff --git a/src/attributes/seenspell.c b/src/attributes/seenspell.c index e7fd2e38a..3d813ee45 100644 --- a/src/attributes/seenspell.c +++ b/src/attributes/seenspell.c @@ -34,6 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include /* ------------------------------------------------------------- */ /* Ausgabe der Spruchbeschreibungen @@ -43,6 +44,43 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * Spruch zu seiner List-of-known-spells hinzugefĆ¼gt werden. */ +static int read_seenspells(variant *var, void *owner, struct gamedata *data) +{ + selist *ql; + storage *store = data->store; + spell *sp = 0; + char token[32]; + + UNUSED_ARG(owner); + READ_TOK(store, token, sizeof(token)); + while (token[0]) { + sp = find_spell(token); + if (!sp) { + log_info("read_seenspells: could not find spell '%s'\n", token); + return AT_READ_FAIL; + } + selist_push(&ql, sp); + READ_TOK(store, token, sizeof(token)); + } + var->v = ql; + return AT_READ_OK; +} + +static bool cb_write_spell(const void *data, void *more) { + const spell *sp = (const spell *)data; + storage *store = (storage *)more; + WRITE_TOK(store, sp->sname); + return true; + +} +static void +write_seenspells(const variant *var, const void *owner, struct storage *store) +{ + UNUSED_ARG(owner); + selist_foreach_ex((selist *)var->v, cb_write_spell, store); + WRITE_TOK(store, ""); +} + static int read_seenspell(variant *var, void *owner, struct gamedata *data) { storage *store = data->store; @@ -60,7 +98,7 @@ static int read_seenspell(variant *var, void *owner, struct gamedata *data) return AT_READ_FAIL; } var->v = sp; - return AT_READ_OK; + return AT_READ_DEPR; } static void @@ -71,18 +109,53 @@ write_seenspell(const variant *var, const void *owner, struct storage *store) WRITE_TOK(store, sp->sname); } +static int cmp_spell(const void *a, const void *b) { + const spell *spa = (const spell *)a; + const spell *spb = (const spell *)b; + return strcmp(spa->sname, spb->sname); +} + +static bool set_seen(attrib **alist, struct spell *sp) { + attrib *a = a_find(*alist, &at_seenspells); + selist *sl; + if (!a) { + a = a_add(alist, a_new(&at_seenspells)); + } + sl = (selist *)a->data.v; + return selist_set_insert(&sl, sp, cmp_spell); +} + +static void upgrade_seenspell(attrib **alist, attrib *abegin) { + attrib *a, *ak; + + ak = a_find(*alist, &at_seenspells); + if (ak) alist = &ak; + for (a = abegin; a && a->type == abegin->type; a = a->next) { + set_seen(alist, (struct spell *)a->data.v); + } +} + +static void free_seenspells(variant *var) { + selist *sl = (selist *)var->v; + selist_free(sl); +} + +attrib_type at_seenspells = { + "seenspells", NULL, free_seenspells, NULL, write_seenspells, read_seenspells +}; + attrib_type at_seenspell = { - "seenspell", NULL, NULL, NULL, write_seenspell, read_seenspell + "seenspell", NULL, NULL, NULL, NULL, read_seenspell, upgrade_seenspell }; static bool already_seen(const faction * f, const spell * sp) { attrib *a; - for (a = a_find(f->attribs, &at_seenspell); a && a->type == &at_seenspell; - a = a->next) { - if (a->data.v == sp) - return true; + a = a_find(f->attribs, &at_seenspells); + if (a) { + selist *sl = (selist *)a->data.v; + return selist_set_find(&sl, NULL, sp, cmp_spell); } return false; } @@ -94,25 +167,17 @@ attrib_type at_reportspell = { void show_spell(faction *f, const spellbook_entry *sbe) { if (!already_seen(f, sbe->sp)) { - attrib * a = a_new(&at_reportspell); - a->data.v = (void *)sbe; - a_add(&f->attribs, a); - a_add(&f->attribs, a_new(&at_seenspell))->data.v = sbe->sp; + /* mark the spell as seen by this faction: */ + if (set_seen(&f->attribs, sbe->sp)) { + /* add the spell to the report: */ + attrib * a = a_new(&at_reportspell); + a->data.v = (void *)sbe; + a_add(&f->attribs, a); + } } } void reset_seen_spells(faction *f, const struct spell *sp) { - if (sp) { - attrib *a = a_find(f->attribs, &at_seenspell); - while (a && a->type == &at_seenspell && a->data.v != sp) { - a = a->next; - } - if (a) { - a_remove(&f->attribs, a); - } - } - else { - a_removeall(&f->attribs, &at_seenspell); - } + a_removeall(&f->attribs, &at_seenspells); } diff --git a/src/attributes/seenspell.h b/src/attributes/seenspell.h index aada5ad0a..cdfb36e48 100644 --- a/src/attributes/seenspell.h +++ b/src/attributes/seenspell.h @@ -10,6 +10,7 @@ void show_spell(struct faction * f, const struct spellbook_entry *sbe); void reset_seen_spells(struct faction * f, const struct spell *sp); extern struct attrib_type at_reportspell; -extern struct attrib_type at_seenspell; +extern struct attrib_type at_seenspells; +extern struct attrib_type at_seenspell; /* upgraded */ #endif