Merge pull request #579 from ennorehling/cache-curse-type

add an API for caching the results of ct_find
This commit is contained in:
Enno Rehling 2016-09-19 20:14:16 +02:00 committed by GitHub
commit 98d810dded
5 changed files with 73 additions and 7 deletions

View File

@ -924,8 +924,12 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn)
int esize = 0; int esize = 0;
double wage; double wage;
attrib *a; attrib *a;
const struct curse_type *ctype; static int ct_cache;
static const struct curse_type *drought_ct;
if (ct_changed(&ct_cache)) {
drought_ct = ct_find("drought");
}
if (b != NULL) { if (b != NULL) {
/* TODO: this reveals imaginary castles */ /* TODO: this reveals imaginary castles */
esize = buildingeffsize(b, false); esize = buildingeffsize(b, false);
@ -970,9 +974,8 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn)
} }
/* Bei einer Dürre verdient man nur noch ein Viertel */ /* Bei einer Dürre verdient man nur noch ein Viertel */
ctype = ct_find("drought"); if (drought_ct) {
if (ctype) { curse *c = get_curse(r->attribs, drought_ct);
curse *c = get_curse(r->attribs, ctype);
if (curse_active(c)) if (curse_active(c))
wage /= curse_geteffect(c); wage /= curse_geteffect(c);
} }

View File

@ -291,6 +291,17 @@ attrib_type at_curse = {
#define MAXCTHASH 128 #define MAXCTHASH 128
static quicklist *cursetypes[MAXCTHASH]; static quicklist *cursetypes[MAXCTHASH];
static int ct_changes = 1;
bool ct_changed(int *cache)
{
assert(cache);
if (*cache != ct_changes) {
*cache = ct_changes;
return true;
}
return false;
}
void ct_register(const curse_type * ct) void ct_register(const curse_type * ct)
{ {
@ -298,6 +309,27 @@ void ct_register(const curse_type * ct)
quicklist **ctlp = cursetypes + hash; quicklist **ctlp = cursetypes + hash;
ql_set_insert(ctlp, (void *)ct); ql_set_insert(ctlp, (void *)ct);
++ct_changes;
}
void ct_remove(const char *c)
{
unsigned int hash = tolower(c[0]);
quicklist *ctl = cursetypes[hash];
if (ctl) {
int qi;
for (qi = 0; ctl; ql_advance(&ctl, &qi, 1)) {
curse_type *type = (curse_type *)ql_get(ctl, qi);
if (strcmp(c, type->cname) == 0) {
ql_delete(&ctl, qi);
++ct_changes;
break;
}
}
}
} }
const curse_type *ct_find(const char *c) const curse_type *ct_find(const char *c)
@ -798,5 +830,7 @@ void curses_done(void) {
int i; int i;
for (i = 0; i != MAXCTHASH; ++i) { for (i = 0; i != MAXCTHASH; ++i) {
ql_free(cursetypes[i]); ql_free(cursetypes[i]);
cursetypes[i] = 0;
} }
++ct_changes;
} }

View File

@ -282,7 +282,9 @@ extern "C" {
int find_cursebyname(const char *c); int find_cursebyname(const char *c);
const curse_type *ct_find(const char *c); const curse_type *ct_find(const char *c);
bool ct_changed(int *cache);
void ct_register(const curse_type *); void ct_register(const curse_type *);
void ct_remove(const char *c);
void ct_checknames(void); void ct_checknames(void);
curse *findcurse(int curseid); curse *findcurse(int curseid);

View File

@ -157,10 +157,29 @@ static void test_write_flag(CuTest *tc) {
cleanup_curse(&fix); cleanup_curse(&fix);
} }
static void test_curse_cache(CuTest *tc)
{
int cache = 0;
const curse_type ct_dummy = { "dummy", CURSETYP_NORM, 0, M_SUMEFFECT, NULL };
test_setup();
CuAssertIntEquals(tc, true, ct_changed(&cache));
CuAssertIntEquals(tc, false, ct_changed(&cache));
CuAssertPtrEquals(tc, NULL, (void *)ct_find(ct_dummy.cname));
ct_register(&ct_dummy);
CuAssertIntEquals(tc, true, ct_changed(&cache));
CuAssertPtrEquals(tc, (void *)&ct_dummy, (void *)ct_find(ct_dummy.cname));
ct_remove(ct_dummy.cname);
CuAssertIntEquals(tc, true, ct_changed(&cache));
CuAssertIntEquals(tc, false, ct_changed(&cache));
CuAssertPtrEquals(tc, NULL, (void *)ct_find(ct_dummy.cname));
test_cleanup();
}
CuSuite *get_curse_suite(void) CuSuite *get_curse_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_curse); SUITE_ADD_TEST(suite, test_curse);
SUITE_ADD_TEST(suite, test_curse_cache);
SUITE_ADD_TEST(suite, test_magicstreet); SUITE_ADD_TEST(suite, test_magicstreet);
SUITE_ADD_TEST(suite, test_magicstreet_warning); SUITE_ADD_TEST(suite, test_magicstreet_warning);
SUITE_ADD_TEST(suite, test_good_dreams); SUITE_ADD_TEST(suite, test_good_dreams);

View File

@ -1279,8 +1279,12 @@ static int att_modification(const unit * u, skill_t sk)
if (u->attribs) { if (u->attribs) {
curse *c; curse *c;
const curse_type *skillmod_ct = ct_find("skillmod"); static int cache;
const curse_type *worse_ct = ct_find("worse"); static const curse_type *skillmod_ct, *worse_ct;
if (ct_changed(&cache)) {
skillmod_ct = ct_find("skillmod");
worse_ct = ct_find("worse");
}
c = get_curse(u->attribs, worse_ct); c = get_curse(u->attribs, worse_ct);
if (c != NULL) if (c != NULL)
result += curse_geteffect(c); result += curse_geteffect(c);
@ -1729,7 +1733,11 @@ int unit_max_hp(const unit * u)
/* der healing curse veraendert die maximalen hp */ /* der healing curse veraendert die maximalen hp */
if (u->region && u->region->attribs) { if (u->region && u->region->attribs) {
const curse_type *heal_ct = ct_find("healingzone"); static int cache;
static const curse_type *heal_ct;
if (ct_changed(&cache)) {
heal_ct = ct_find("healingzone");
}
if (heal_ct) { if (heal_ct) {
curse *c = get_curse(u->region->attribs, heal_ct); curse *c = get_curse(u->region->attribs, heal_ct);
if (c) { if (c) {