From 80d696d02ab8eec9557af571ca025e75ce114b02 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Apr 2017 22:15:18 +0200 Subject: [PATCH] remove the funcpointer from struct spell. --- res/e3a/strings.xml | 2 +- src/bindings.h | 2 +- src/helpers.c | 20 ++++++++----------- src/helpers.h | 1 + src/kernel/jsonconf.c | 3 --- src/kernel/spell.c | 32 ++++++++++++++++++++++++++---- src/kernel/spell.h | 4 +++- src/kernel/xmlreader.c | 45 +++--------------------------------------- src/magic.c | 13 +++++++----- src/magic.test.c | 2 +- src/spells.c | 17 ++++++++-------- 11 files changed, 63 insertions(+), 78 deletions(-) diff --git a/res/e3a/strings.xml b/res/e3a/strings.xml index 054cabfaa..eb9f48cf3 100644 --- a/res/e3a/strings.xml +++ b/res/e3a/strings.xml @@ -210,7 +210,7 @@ Dieser Zauber wird die gesamte Ausrüstung der Zieleinheit für einige Zeit vor den Blicken anderer verschleiern. Der Zauber schützt nicht vor Dieben und Spionen. This spell will hide the whole equipment of a target unit from the looks of others. It will not protect against thieves or spies. - + Durch dieses uralte Tanzritual ruft der Zauberkundige die Kräfte des Lebens und der Fruchtbarkeit an. Die darauf folgenden Regenfälle begünstigen das Wachstum und erhöhen die Ernteerträge einiger Bauern der Region bis der Regen wieder nachlässt. This ancient rite calls upon the forces of life and fertility. For the next few weeks, the peasants' harvest will be extraordinary good. diff --git a/src/bindings.h b/src/bindings.h index 2275236cb..5cb64a038 100755 --- a/src/bindings.h +++ b/src/bindings.h @@ -18,7 +18,7 @@ extern "C" { struct _dictionary_; struct selist; - int tolua_toid(struct lua_State * L, int idx, int def); + int tolua_toid(struct lua_State *L, int idx, int def); int tolua_sqlite_open(struct lua_State *L); int tolua_bindings_open(struct lua_State *L, const struct _dictionary_ *d); int tolua_itemlist_next(struct lua_State *L); diff --git a/src/helpers.c b/src/helpers.c index 4e020cefe..700850018 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -23,6 +23,7 @@ without prior permission by the authors of Eressea. #include #include +#include #include #include #include @@ -452,21 +453,16 @@ void register_tolua_helpers(void) callbacks.cast_spell = lua_callspell; - register_function((pf_generic)lua_initfamiliar, - TOLUA_CAST "lua_initfamiliar"); - register_function((pf_generic)lua_getresource, - TOLUA_CAST "lua_getresource"); - register_function((pf_generic)lua_changeresource, - TOLUA_CAST "lua_changeresource"); - register_function((pf_generic)lua_equipmentcallback, - TOLUA_CAST "lua_equip"); + register_function((pf_generic)lua_initfamiliar, "lua_initfamiliar"); + register_function((pf_generic)lua_getresource, "lua_getresource"); + register_function((pf_generic)lua_changeresource, "lua_changeresource"); + register_function((pf_generic)lua_equipmentcallback, "lua_equip"); - register_function((pf_generic)lua_wage, TOLUA_CAST "lua_wage"); - register_function((pf_generic)lua_maintenance, - TOLUA_CAST "lua_maintenance"); + register_function((pf_generic)lua_wage, "lua_wage"); + register_function((pf_generic)lua_maintenance, "lua_maintenance"); item_use_fun = use_item_lua; res_produce_fun = produce_resource_lua; res_limit_fun = limit_resource_lua; - register_item_give(lua_giveitem, TOLUA_CAST "lua_giveitem"); + register_item_give(lua_giveitem, "lua_giveitem"); } diff --git a/src/helpers.h b/src/helpers.h index 5187f7bcf..d0bbcc58b 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -15,6 +15,7 @@ extern "C" { #endif struct lua_State; + void register_tolua_helpers(void); #ifdef __cplusplus diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 6dd3909b5..32ab06e08 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -594,9 +594,6 @@ static void json_spells(cJSON *json) { if (strcmp(item->string, "index") == 0) { continue; } - else if (strcmp(item->string, "cast") == 0) { - sp->cast_fun = (spell_f)get_function(item->valuestring); - } else if (strcmp(item->string, "syntax") == 0) { sp->syntax = strdup(item->valuestring); } diff --git a/src/kernel/spell.c b/src/kernel/spell.c index 900f98ff0..393bbecb9 100644 --- a/src/kernel/spell.c +++ b/src/kernel/spell.c @@ -33,7 +33,30 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -static critbit_tree cb_fumbles; + +static critbit_tree cb_spell_fun; +void add_spellcast(const char *sname, spell_f fun) +{ + size_t len; + char data[64]; + + len = cb_new_kv(sname, strlen(sname), &fun, sizeof(fun), data); + assert(len <= sizeof(data)); + cb_insert(&cb_spell_fun, data, len); +} + +spell_f get_spellcast(const char *sname) +{ + void * match; + spell_f result = NULL; + + if (cb_find_prefix(&cb_spell_fun, sname, strlen(sname) + 1, &match, 1, 0)) { + cb_get_kv(match, &result, sizeof(result)); + } + return result; +} + +static critbit_tree cb_fumble_fun; void add_fumble(const char *sname, fumble_f fun) { size_t len; @@ -41,7 +64,7 @@ void add_fumble(const char *sname, fumble_f fun) len = cb_new_kv(sname, strlen(sname), &fun, sizeof(fun), data); assert(len <= sizeof(data)); - cb_insert(&cb_fumbles, data, len); + cb_insert(&cb_fumble_fun, data, len); } fumble_f get_fumble(const char *sname) @@ -49,7 +72,7 @@ fumble_f get_fumble(const char *sname) void * match; fumble_f result = NULL; - if (cb_find_prefix(&cb_fumbles, sname, strlen(sname) + 1, &match, 1, 0)) { + if (cb_find_prefix(&cb_fumble_fun, sname, strlen(sname) + 1, &match, 1, 0)) { cb_get_kv(match, &result, sizeof(result)); } return result; @@ -71,7 +94,8 @@ static void free_spell_cb(void *cbdata) { } void free_spells(void) { - cb_clear(&cb_fumbles); + cb_clear(&cb_fumble_fun); + cb_clear(&cb_spell_fun); cb_clear(&cb_spells); selist_foreach(spells, free_spell_cb); selist_free(spells); diff --git a/src/kernel/spell.h b/src/kernel/spell.h index da077347a..41feaa17d 100644 --- a/src/kernel/spell.h +++ b/src/kernel/spell.h @@ -41,7 +41,6 @@ extern "C" { int sptyp; int rank; /* Reihenfolge der Zauber */ struct spell_component *components; - spell_f cast_fun; } spell; typedef struct spellref { @@ -52,6 +51,9 @@ extern "C" { void add_fumble(const char *sname, fumble_f fun); fumble_f get_fumble(const char *sname); + void add_spellcast(const char *sname, spell_f fun); + spell_f get_spellcast(const char *sname); + struct spellref *spellref_create(struct spell *sp, const char *name); void spellref_free(struct spellref *spref); struct spell *spellref_get(struct spellref *spref); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index c0595b4f5..7367a2023 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -279,11 +279,8 @@ parse_function(xmlNodePtr node, pf_generic * funPtr, xmlChar ** namePtr) xmlChar *propValue = xmlGetProp(node, BAD_CAST "value"); assert(propValue != NULL); fun = get_function((const char *)propValue); - if (fun != NULL) { - xmlFree(propValue); - - propValue = xmlGetProp(node, BAD_CAST "name"); - } + xmlFree(propValue); + propValue = xmlGetProp(node, BAD_CAST "name"); *namePtr = propValue; *funPtr = fun; return 0; @@ -1311,7 +1308,6 @@ static int parse_spellbooks(xmlDocPtr doc) static int parse_spells(xmlDocPtr doc) { - pf_generic cast = 0; xmlXPathContextPtr xpath = xmlXPathNewContext(doc); xmlXPathObjectPtr spells; @@ -1388,44 +1384,9 @@ static int parse_spells(xmlDocPtr doc) sp->sptyp |= REGIONSPELL; k = xml_ivalue(node, "combat", 0); - if (k >= 0 && k <= 3) + if (k >= 0 && k <= 3) { sp->sptyp |= modes[k]; - - /* reading eressea/spells/spell/function */ - - xpath->node = node; - result = xmlXPathEvalExpression(BAD_CAST "function", xpath); - - if (result->nodesetval->nodeNr == 0) { - cast = get_function(sp->sname); - if (!cast) { - log_info("no spell cast function registered for '%s'\n", sp->sname); - } } - else { - for (k = 0; k != result->nodesetval->nodeNr; ++k) { - xmlNodePtr node = result->nodesetval->nodeTab[k]; - pf_generic fun; - - parse_function(node, &fun, &propValue); - assert(propValue != NULL); - if (strcmp((const char *)propValue, "cast") == 0) { - if (fun) { - cast = fun; - } - else { - log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname); - } - } - else { - log_error("unknown function type '%s' for spell '%s'\n", (const char *)propValue, sp->sname); - } - xmlFree(propValue); - } - } - sp->cast_fun = (spell_f)cast; - xmlXPathFreeObject(result); - /* reading eressea/spells/spell/resource */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "resource", xpath); diff --git a/src/magic.c b/src/magic.c index d7bc63ca2..63c443296 100644 --- a/src/magic.c +++ b/src/magic.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" #include "study.h" +#include "helpers.h" #include "laws.h" #include @@ -3009,12 +3010,9 @@ int cast_spell(struct castorder *co) const char *fname = co->sp->sname; const char *hashpos = strchr(fname, '#'); char fbuf[64]; + spell_f fun; const spell *sp = co->sp; - if (sp->cast_fun) { - return sp->cast_fun(co); - } - if (hashpos != NULL) { ptrdiff_t len = hashpos - fname; assert(len < (ptrdiff_t) sizeof(fbuf)); @@ -3023,7 +3021,12 @@ int cast_spell(struct castorder *co) fname = fbuf; } - return callbacks.cast_spell(co, fname); + fun = get_spellcast(sp->sname); + if (!fun) { + log_warning("no spell function for %s, try callback", sp->sname); + return callbacks.cast_spell(co, fname); + } + return fun(co); } static critbit_tree cb_spellbooks; diff --git a/src/magic.test.c b/src/magic.test.c index 3f279315c..746905029 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -377,8 +377,8 @@ void test_multi_cast(CuTest *tc) { struct locale * lang; test_setup(); + add_spellcast("fireball", cast_fireball); sp = create_spell("fireball", 0); - sp->cast_fun = cast_fireball; CuAssertPtrEquals(tc, sp, find_spell("fireball")); lang = test_create_locale(); diff --git a/src/spells.c b/src/spells.c index 5341a8e11..468441cdd 100644 --- a/src/spells.c +++ b/src/spells.c @@ -6615,12 +6615,10 @@ static spelldata spell_functions[] = { static void register_spelldata(void) { int i; - char zText[32]; - strcpy(zText, "fumble_"); for (i = 0; spell_functions[i].sname; ++i) { spelldata *data = spell_functions + i; if (data->cast) { - register_function((pf_generic)data->cast, data->sname); + add_spellcast(data->sname, data->cast); } if (data->fumble) { add_fumble(data->sname, data->fumble); @@ -6733,11 +6731,14 @@ void register_spells(void) ct_register(&ct_firewall); ct_register(&ct_deathcloud); - register_function((pf_generic)sp_blessedharvest, "cast_blessedharvest"); - register_function((pf_generic)sp_summon_familiar, "cast_familiar"); - register_function((pf_generic)sp_babbler, "cast_babbler"); - register_function((pf_generic)sp_readmind, "cast_readmind"); - register_function((pf_generic)sp_kampfzauber, "combat_spell"); + add_spellcast("blabbermouth", sp_babbler); + add_spellcast("summon_familiar", sp_summon_familiar); + add_spellcast("meteor_rain", sp_kampfzauber); + add_spellcast("fireball", sp_kampfzauber); + add_spellcast("hail", sp_kampfzauber); + add_spellcast("readmind", sp_readmind); + add_spellcast("blessedharvest", sp_blessedharvest); + add_spellcast("raindance", sp_blessedharvest); register_spelldata();