From d29d38f710b602dc9d9594be2a508dd28e9119a9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 9 Sep 2015 15:45:20 +0200 Subject: [PATCH 1/3] refactor donations into a seaprate code module, add a basic test --- src/CMakeLists.txt | 2 ++ src/donations.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ src/donations.h | 20 +++++++++++++++ src/donations.test.c | 29 +++++++++++++++++++++ src/economy.c | 25 ++---------------- src/economy.h | 1 - src/kernel/config.c | 3 +++ src/kernel/region.c | 6 ----- src/kernel/region.h | 2 +- src/reports.c | 20 +-------------- src/skill.h | 3 +++ src/test_eressea.c | 1 + src/upkeep.c | 3 ++- 13 files changed, 124 insertions(+), 51 deletions(-) create mode 100644 src/donations.c create mode 100644 src/donations.h create mode 100644 src/donations.test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7057bbe7f..e5a05ff8b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,6 +86,7 @@ set (ERESSEA_SRC names.c lighthouse.c reports.c + donations.c seen.c eressea.c callback.c @@ -175,6 +176,7 @@ target_link_libraries(eressea ) set(TESTS_SRC + donations.test.c wormhole.test.c alchemy.test.c test_eressea.c diff --git a/src/donations.c b/src/donations.c new file mode 100644 index 000000000..b272f6f80 --- /dev/null +++ b/src/donations.c @@ -0,0 +1,60 @@ +#include +#include "donations.h" + +#include +#include +#include + +#include + +void add_donation(faction * f1, faction * f2, int amount, region * r) +{ + donation *sp; + + sp = r->donations_; + + while (sp) { + if (sp->f1 == f1 && sp->f2 == f2) { + sp->amount += amount; + return; + } + sp = sp->next; + } + + sp = calloc(1, sizeof(donation)); + sp->f1 = f1; + sp->f2 = f2; + sp->amount = amount; + sp->next = r->donations_; + r->donations_ = sp; +} + +void free_donations(void) { + region *r; + for (r = regions; r; r = r->next) { + while (r->donations_) { + donation *don = r->donations_; + r->donations_ = don->next; + free(don); + } + } +} + +void report_donations(void) +{ + region *r; + for (r = regions; r; r = r->next) { + while (r->donations_) { + donation *sp = r->donations_; + if (sp->amount > 0) { + struct message *msg = msg_message("donation", + "from to amount", sp->f1, sp->f2, sp->amount); + r_addmessage(r, sp->f1, msg); + r_addmessage(r, sp->f2, msg); + msg_release(msg); + } + r->donations_ = sp->next; + free(sp); + } + } +} diff --git a/src/donations.h b/src/donations.h new file mode 100644 index 000000000..e5fce2bb2 --- /dev/null +++ b/src/donations.h @@ -0,0 +1,20 @@ +#pragma once + +#ifndef H_DONATIONS +#define H_DONATIONS + +#ifdef __cplusplus +extern "C" { +#endif + + struct faction; + struct region; + + void add_donation(struct faction * f1, struct faction * f2, int amount, struct region * r); + void free_donations(void); + void report_donations(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/donations.test.c b/src/donations.test.c new file mode 100644 index 000000000..068aba74a --- /dev/null +++ b/src/donations.test.c @@ -0,0 +1,29 @@ +#include "donations.h" + +#include +#include +#include + +#include + +static void test_add_donation(CuTest *tc) { + faction *f1, *f2; + region *r; + + test_cleanup(); + r = test_create_region(0, 0, 0); + f1 = test_create_faction(0); + f2 = test_create_faction(0); + add_donation(f1, f2, 100, r); + report_donations(); + CuAssertPtrNotNull(tc, test_find_messagetype(r->individual_messages->msgs, "donation")); + free_donations(); + test_cleanup(); +} + +CuSuite *get_donations_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_add_donation); + return suite; +} diff --git a/src/economy.c b/src/economy.c index 2219a9cdc..7df3cd310 100644 --- a/src/economy.c +++ b/src/economy.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "alchemy.h" #include "direction.h" +#include "donations.h" #include "give.h" #include "laws.h" #include "randenc.h" @@ -705,28 +706,6 @@ static int forget_cmd(unit * u, order * ord) return 0; } -void add_spende(faction * f1, faction * f2, int amount, region * r) -{ - donation *sp; - - sp = r->donations; - - while (sp) { - if (sp->f1 == f1 && sp->f2 == f2) { - sp->amount += amount; - return; - } - sp = sp->next; - } - - sp = calloc(1, sizeof(donation)); - sp->f1 = f1; - sp->f2 = f2; - sp->amount = amount; - sp->next = r->donations; - r->donations = sp; -} - static bool maintain(building * b, bool first) /* first==false -> take money from wherever you can */ { @@ -886,7 +865,7 @@ static bool maintain(building * b, bool first) cost -= give; fset(ua->faction, FFL_SELECT); if (m->rtype == rsilver) - add_spende(ua->faction, u->faction, give, r); + add_donation(ua->faction, u->faction, give, r); if (cost <= 0) break; } diff --git a/src/economy.h b/src/economy.h index 2ad2fe566..dce389556 100644 --- a/src/economy.h +++ b/src/economy.h @@ -54,7 +54,6 @@ extern "C" { enum { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC, IC_LOOT }; void maintain_buildings(struct region *r, bool crash); - void add_spende(struct faction *f1, struct faction *f2, int betrag, struct region *r); int make_cmd(struct unit *u, struct order *ord); void split_allocations(struct region *r); int recruit_archetypes(void); diff --git a/src/kernel/config.c b/src/kernel/config.c index fe4d96934..9a350245d 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -73,6 +73,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include "donations.h" + #ifdef USE_LIBXML2 /* libxml includes */ #include @@ -1761,6 +1763,7 @@ int markets_module(void) void free_gamedata(void) { int i; + free_donations(); free_units(); free_regions(); free_borders(); diff --git a/src/kernel/region.c b/src/kernel/region.c index 999b8dc33..8b82edbea 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -839,12 +839,6 @@ void free_region(region * r) free(res); } - while (r->donations) { - donation *don = r->donations; - r->donations = don->next; - free(don); - } - while (r->units) { unit *u = r->units; r->units = u->next; diff --git a/src/kernel/region.h b/src/kernel/region.h index c29732b78..3bf4b4748 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -133,7 +133,7 @@ extern "C" { struct message_list *msgs; } *individual_messages; struct attrib *attribs; - struct donation *donations; + struct donation *donations_; const struct terrain_type *terrain; struct rawmaterial *resources; #ifdef FAST_CONNECT diff --git a/src/reports.c b/src/reports.c index 2168268bb..e2a5c6d55 100644 --- a/src/reports.c +++ b/src/reports.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "seen.h" #include "travelthru.h" #include "lighthouse.h" +#include "donations.h" /* kernel includes */ #include @@ -1602,25 +1603,6 @@ int write_reports(faction * f, time_t ltime) return 0; } -static void report_donations(void) -{ - region *r; - for (r = regions; r; r = r->next) { - while (r->donations) { - donation *sp = r->donations; - if (sp->amount > 0) { - struct message *msg = msg_message("donation", - "from to amount", sp->f1, sp->f2, sp->amount); - r_addmessage(r, sp->f1, msg); - r_addmessage(r, sp->f2, msg); - msg_release(msg); - } - r->donations = sp->next; - free(sp); - } - } -} - static void write_script(FILE * F, const faction * f) { report_type *rtype; diff --git a/src/skill.h b/src/skill.h index ad4450e74..8b0c0c155 100644 --- a/src/skill.h +++ b/src/skill.h @@ -1,6 +1,9 @@ +#pragma once + #ifndef H_SKILL_H #define H_SKILL_H +#include struct locale; typedef enum { diff --git a/src/test_eressea.c b/src/test_eressea.c index f531d8042..bd72323b7 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -81,6 +81,7 @@ int RunAllTests(void) RUN_TESTS(suite, messages); /* gamecode */ RUN_TESTS(suite, battle); + RUN_TESTS(suite, donations); RUN_TESTS(suite, travelthru); RUN_TESTS(suite, economy); RUN_TESTS(suite, give); diff --git a/src/upkeep.c b/src/upkeep.c index d1c34f476..c23746b07 100644 --- a/src/upkeep.c +++ b/src/upkeep.c @@ -16,6 +16,7 @@ #include "alchemy.h" #include "economy.h" #include "monster.h" +#include "donations.h" #include @@ -55,7 +56,7 @@ static void help_feed(unit * donor, unit * u, int *need_p) change_money(donor, -give); change_money(u, give); need -= give; - add_spende(donor->faction, u->faction, give, donor->region); + add_donation(donor->faction, u->faction, give, donor->region); } *need_p = need; } From 337aca9b3c0dab039dea702193f8e5401df85196 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 9 Sep 2015 16:47:09 +0200 Subject: [PATCH 2/3] remove region.donations, replace with a global list. --- src/donations.c | 93 +++++++++++++++++++++++++++------------------ src/kernel/region.h | 8 ---- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/donations.c b/src/donations.c index b272f6f80..c9b4a6c6a 100644 --- a/src/donations.c +++ b/src/donations.c @@ -4,57 +4,76 @@ #include #include #include +#include #include +typedef struct transfer { + struct region *r; + struct faction *f1, *f2; + int amount; +} transfer; + +static quicklist *transfers = 0; + +int cmp_transfer(const void *v1, const void *v2) { + const transfer *t1 = (const transfer *)v1; + const transfer *t2 = (const transfer *)v2; + if (t1->r == t2->r) { + if (t1->f1 == t2->f1) { + if (t1->f2 == t2->f2) { + return 0; + } + return t1->f2->no - t2->f2->no; + } + return t1->f1->no - t2->f1->no; + } + return t1->r->uid - t2->r->uid; +} + void add_donation(faction * f1, faction * f2, int amount, region * r) { - donation *sp; + transfer tr, *tf; + quicklist *ql = transfers; + int qi = 0; - sp = r->donations_; - - while (sp) { - if (sp->f1 == f1 && sp->f2 == f2) { - sp->amount += amount; - return; - } - sp = sp->next; + tr.r = r; + tr.f1 = f1; + tr.f2 = f2; + tr.amount = amount; + if (ql_set_find_ex(&ql, &qi, &tr, cmp_transfer)) { + tf = (transfer *)ql_get(ql, qi); + tf->amount += amount; } - - sp = calloc(1, sizeof(donation)); - sp->f1 = f1; - sp->f2 = f2; - sp->amount = amount; - sp->next = r->donations_; - r->donations_ = sp; + else { + tf = malloc(sizeof(transfer)); + memcpy(tf, &tr, sizeof(transfer)); + } + ql_set_insert_ex(&transfers, tf, cmp_transfer); } void free_donations(void) { - region *r; - for (r = regions; r; r = r->next) { - while (r->donations_) { - donation *don = r->donations_; - r->donations_ = don->next; - free(don); - } - } + ql_foreach(transfers, free); + ql_free(transfers); + transfers = 0; +} + +static void report_transfer(faction *f1, faction *f2, region *r, int amount) { + struct message *msg = msg_message("donation", + "from to amount", f1, f2, amount); + r_addmessage(r, f1, msg); + r_addmessage(r, f2, msg); + msg_release(msg); } void report_donations(void) { - region *r; - for (r = regions; r; r = r->next) { - while (r->donations_) { - donation *sp = r->donations_; - if (sp->amount > 0) { - struct message *msg = msg_message("donation", - "from to amount", sp->f1, sp->f2, sp->amount); - r_addmessage(r, sp->f1, msg); - r_addmessage(r, sp->f2, msg); - msg_release(msg); - } - r->donations_ = sp->next; - free(sp); + ql_iter qli = qli_init(&transfers);; + + while (qli_more(qli)) { + transfer *tf = (transfer *)qli_next(&qli); + if (tf->amount > 0) { + report_transfer(tf->f1, tf->f2, tf->r, tf->amount); } } } diff --git a/src/kernel/region.h b/src/kernel/region.h index 3bf4b4748..93453364a 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -62,7 +62,6 @@ extern "C" { struct message; struct message_list; struct rawmaterial; - struct donation; struct item; #define MORALE_TAX_FACTOR 0.005 /* 0.5% tax per point of morale */ @@ -104,12 +103,6 @@ extern "C" { struct region_owner *ownership; } land_region; - typedef struct donation { - struct donation *next; - struct faction *f1, *f2; - int amount; - } donation; - typedef struct region { struct region *next; struct land_region *land; @@ -133,7 +126,6 @@ extern "C" { struct message_list *msgs; } *individual_messages; struct attrib *attribs; - struct donation *donations_; const struct terrain_type *terrain; struct rawmaterial *resources; #ifdef FAST_CONNECT From f2b2dc2063fb507c62ef1bb3fed4fec69619e27f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 9 Sep 2015 16:48:24 +0200 Subject: [PATCH 3/3] fix linux build, missing include --- src/donations.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/donations.c b/src/donations.c index c9b4a6c6a..09d572177 100644 --- a/src/donations.c +++ b/src/donations.c @@ -7,6 +7,7 @@ #include #include +#include typedef struct transfer { struct region *r;