Merge pull request #578 from ennorehling/cache-buiding-type

add an API for caching the results of bt_find
This commit is contained in:
Enno Rehling 2016-09-19 20:14:27 +02:00 committed by GitHub
commit 7d88dddcc3
4 changed files with 60 additions and 13 deletions

View file

@ -1713,7 +1713,11 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
/* ...oder in der Region muß es eine Burg geben. */ /* ...oder in der Region muß es eine Burg geben. */
building *b = 0; building *b = 0;
if (r->buildings) { if (r->buildings) {
const struct building_type *bt_castle = bt_find("castle"); static int cache;
static const struct building_type *bt_castle;
if (bt_changed(&cache)) {
bt_castle = bt_find("castle");
}
for (b = r->buildings; b; b = b->next) { for (b = r->buildings; b; b = b->next) {
if (b->type == bt_castle && b->size >= 2) { if (b->type == bt_castle && b->size >= 2) {
@ -1799,8 +1803,14 @@ static void expandselling(region * r, request * sellorders, int limit)
unit *hafenowner; unit *hafenowner;
static int counter[MAXLUXURIES]; static int counter[MAXLUXURIES];
static int ncounter = 0; static int ncounter = 0;
const struct building_type *castle_bt; static int bt_cache;
static const struct building_type *castle_bt, *harbour_bt, *caravan_bt;
if (bt_changed(&bt_cache)) {
castle_bt = bt_find("castle");
harbour_bt = bt_find("harbour");
caravan_bt = bt_find("caravan");
}
if (ncounter == 0) { if (ncounter == 0) {
const luxury_type *ltype; const luxury_type *ltype;
for (ltype = luxurytypes; ltype; ltype = ltype->next) { for (ltype = luxurytypes; ltype; ltype = ltype->next) {
@ -1815,7 +1825,6 @@ static void expandselling(region * r, request * sellorders, int limit)
} }
/* Stelle Eigentümer der größten Burg fest. Bekommt Steuern aus jedem /* Stelle Eigentümer der größten Burg fest. Bekommt Steuern aus jedem
* Verkauf. Wenn zwei Burgen gleicher Größe bekommt gar keiner etwas. */ * Verkauf. Wenn zwei Burgen gleicher Größe bekommt gar keiner etwas. */
castle_bt = bt_find("castle");
for (b = rbuildings(r); b; b = b->next) { for (b = rbuildings(r); b; b = b->next) {
if (b->size > maxsize && building_owner(b) != NULL if (b->size > maxsize && building_owner(b) != NULL
&& b->type == castle_bt) { && b->type == castle_bt) {
@ -1829,7 +1838,7 @@ static void expandselling(region * r, request * sellorders, int limit)
} }
} }
hafenowner = owner_buildingtyp(r, bt_find("harbour")); hafenowner = owner_buildingtyp(r, harbour_bt);
if (maxb != (building *)NULL && maxowner != (unit *)NULL) { if (maxb != (building *)NULL && maxowner != (unit *)NULL) {
maxeffsize = buildingeffsize(maxb, false); maxeffsize = buildingeffsize(maxb, false);
@ -1851,7 +1860,7 @@ static void expandselling(region * r, request * sellorders, int limit)
return; return;
if (r->terrain == newterrain(T_DESERT) if (r->terrain == newterrain(T_DESERT)
&& buildingtype_exists(r, bt_find("caravan"), true)) { && buildingtype_exists(r, caravan_bt, true)) {
max_products = rpeasants(r) * 2 / TRADE_FRACTION; max_products = rpeasants(r) * 2 / TRADE_FRACTION;
} }
/* Verkauf: so programmiert, dass er leicht auf mehrere Gueter pro /* Verkauf: so programmiert, dass er leicht auf mehrere Gueter pro
@ -1978,6 +1987,13 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
region *r = u->region; region *r = u->region;
const char *s; const char *s;
keyword_t kwd; keyword_t kwd;
static int bt_cache;
static const struct building_type *castle_bt, *caravan_bt;
if (bt_changed(&bt_cache)) {
castle_bt = bt_find("castle");
caravan_bt = bt_find("caravan");
}
if (u->ship && is_guarded(r, u, GUARD_CREWS)) { if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
cmistake(u, ord, 69, MSG_INCOME); cmistake(u, ord, 69, MSG_INCOME);
@ -1994,7 +2010,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
unlimited = false; unlimited = false;
n = rpeasants(r) / TRADE_FRACTION; n = rpeasants(r) / TRADE_FRACTION;
if (r->terrain == newterrain(T_DESERT) if (r->terrain == newterrain(T_DESERT)
&& buildingtype_exists(r, bt_find("caravan"), true)) && buildingtype_exists(r, caravan_bt, true))
n *= 2; n *= 2;
if (n == 0) { if (n == 0) {
cmistake(u, ord, 303, MSG_COMMERCE); cmistake(u, ord, 303, MSG_COMMERCE);
@ -2027,9 +2043,8 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
/* ...oder in der Region muß es eine Burg geben. */ /* ...oder in der Region muß es eine Burg geben. */
building *b = 0; building *b = 0;
if (r->buildings) { if (r->buildings) {
const struct building_type *bt_castle = bt_find("castle");
for (b = r->buildings; b; b = b->next) { for (b = r->buildings; b; b = b->next) {
if (b->type == bt_castle && b->size >= 2) break; if (b->type == castle_bt && b->size >= 2) break;
} }
} }
if (!b) { if (!b) {
@ -2344,9 +2359,15 @@ static void breedhorses(unit * u)
int n, c, breed = 0; int n, c, breed = 0;
const struct resource_type *rhorse = get_resourcetype(R_HORSE); const struct resource_type *rhorse = get_resourcetype(R_HORSE);
int horses, effsk; int horses, effsk;
static int bt_cache;
static const struct building_type *stables_bt;
if (bt_changed(&bt_cache)) {
stables_bt = bt_find("stables");
}
assert(rhorse && rhorse->itype); assert(rhorse && rhorse->itype);
if (!active_building(u, bt_find("stables"))) { if (!active_building(u, stables_bt)) {
cmistake(u, u->thisorder, 122, MSG_PRODUCE); cmistake(u, u->thisorder, 122, MSG_PRODUCE);
return; return;
} }
@ -3083,6 +3104,13 @@ void produce(struct region *r)
unit *u; unit *u;
bool limited = true; bool limited = true;
request *nextworker = workers; request *nextworker = workers;
static int bt_cache;
static const struct building_type *caravan_bt;
if (bt_changed(&bt_cache)) {
caravan_bt = bt_find("caravan");
}
assert(r); assert(r);
/* das sind alles befehle, die 30 tage brauchen, und die in thisorder /* das sind alles befehle, die 30 tage brauchen, und die in thisorder
@ -3232,7 +3260,7 @@ void produce(struct region *r)
if (sellorders) { if (sellorders) {
int limit = rpeasants(r) / TRADE_FRACTION; int limit = rpeasants(r) / TRADE_FRACTION;
if (r->terrain == newterrain(T_DESERT) if (r->terrain == newterrain(T_DESERT)
&& buildingtype_exists(r, bt_find("caravan"), true)) && buildingtype_exists(r, caravan_bt, true))
limit *= 2; limit *= 2;
expandselling(r, sellorders, limited ? limit : INT_MAX); expandselling(r, sellorders, limited ? limit : INT_MAX);
} }

View file

@ -83,15 +83,28 @@ const building_type *bt_find(const char *name)
return bt_find_i(name); return bt_find_i(name);
} }
static int bt_changes = 1;
bool bt_changed(int *cache)
{
assert(cache);
if (*cache != bt_changes) {
*cache = bt_changes;
return true;
}
return false;
}
void bt_register(building_type * type) void bt_register(building_type * type)
{ {
if (type->init) { if (type->init) {
type->init(type); type->init(type);
} }
ql_push(&buildingtypes, (void *)type); ql_push(&buildingtypes, (void *)type);
++bt_changes;
} }
void free_buildingtype(void *ptr) { static void free_buildingtype(void *ptr) {
building_type *btype = (building_type *)ptr; building_type *btype = (building_type *)ptr;
free_construction(btype->construction); free_construction(btype->construction);
free(btype->maintenance); free(btype->maintenance);
@ -103,6 +116,7 @@ void free_buildingtypes(void) {
ql_foreach(buildingtypes, free_buildingtype); ql_foreach(buildingtypes, free_buildingtype);
ql_free(buildingtypes); ql_free(buildingtypes);
buildingtypes = 0; buildingtypes = 0;
++bt_changes;
} }
building_type *bt_get_or_create(const char *name) building_type *bt_get_or_create(const char *name)

View file

@ -84,6 +84,7 @@ extern "C" {
extern struct attrib_type at_building_action; extern struct attrib_type at_building_action;
building_type *bt_get_or_create(const char *name); building_type *bt_get_or_create(const char *name);
bool bt_changed(int *cache);
const building_type *bt_find(const char *name); const building_type *bt_find(const char *name);
void free_buildingtypes(void); void free_buildingtypes(void);
void register_buildings(void); void register_buildings(void);

View file

@ -17,16 +17,20 @@
static void test_register_building(CuTest * tc) static void test_register_building(CuTest * tc)
{ {
building_type *btype; building_type *btype;
int cache = 0;
test_cleanup(); test_cleanup();
btype = (building_type *)calloc(sizeof(building_type), 1); btype = (building_type *)calloc(sizeof(building_type), 1);
btype->_name = _strdup("herp"); btype->_name = _strdup("herp");
CuAssertIntEquals(tc, true, bt_changed(&cache));
CuAssertIntEquals(tc, false, bt_changed(&cache));
bt_register(btype); bt_register(btype);
CuAssertIntEquals(tc, true, bt_changed(&cache));
CuAssertPtrNotNull(tc, bt_find("herp")); CuAssertPtrNotNull(tc, bt_find("herp"));
// free(btype->_name); free_buildingtypes();
// free(btype); CuAssertIntEquals(tc, true, bt_changed(&cache));
test_cleanup(); test_cleanup();
} }