convert multiple seenspell attributes to single seenspells list. faster? maybe.

This commit is contained in:
Enno Rehling 2018-02-10 16:50:05 +01:00
parent c3fce574fb
commit fe29f2433a
3 changed files with 90 additions and 24 deletions

View file

@ -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);

View file

@ -34,6 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <storage.h>
#include <stdlib.h>
#include <string.h>
/* ------------------------------------------------------------- */
/* 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);
}

View file

@ -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