Merge pull request #291 from ennorehling/feature/issue-289-optimize-donations

modularizing donations
This commit is contained in:
Enno Rehling 2015-09-09 17:17:32 +02:00
commit 33aff91dc3
13 changed files with 143 additions and 58 deletions

View File

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

80
src/donations.c Normal file
View File

@ -0,0 +1,80 @@
#include <kernel/types.h>
#include "donations.h"
#include <kernel/faction.h>
#include <kernel/region.h>
#include <kernel/messages.h>
#include <quicklist.h>
#include <stdlib.h>
#include <string.h>
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)
{
transfer tr, *tf;
quicklist *ql = transfers;
int qi = 0;
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;
}
else {
tf = malloc(sizeof(transfer));
memcpy(tf, &tr, sizeof(transfer));
}
ql_set_insert_ex(&transfers, tf, cmp_transfer);
}
void free_donations(void) {
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)
{
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);
}
}
}

20
src/donations.h Normal file
View File

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

29
src/donations.test.c Normal file
View File

@ -0,0 +1,29 @@
#include "donations.h"
#include <kernel/faction.h>
#include <kernel/region.h>
#include <tests.h>
#include <CuTest.h>
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;
}

View File

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

View File

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

View File

@ -73,6 +73,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/umlaut.h>
#include <util/xml.h>
#include "donations.h"
#ifdef USE_LIBXML2
/* libxml includes */
#include <libxml/tree.h>
@ -1761,6 +1763,7 @@ int markets_module(void)
void free_gamedata(void)
{
int i;
free_donations();
free_units();
free_regions();
free_borders();

View File

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

View File

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

View File

@ -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 <kernel/alliance.h>
@ -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;

View File

@ -1,6 +1,9 @@
#pragma once
#ifndef H_SKILL_H
#define H_SKILL_H
#include <platform.h>
struct locale;
typedef enum {

View File

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

View File

@ -16,6 +16,7 @@
#include "alchemy.h"
#include "economy.h"
#include "monster.h"
#include "donations.h"
#include <assert.h>
@ -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;
}