From 9312b44f8ed30c528ed4ecc9d7dbb453450c9bbc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 8 Sep 2015 09:56:56 +0200 Subject: [PATCH] move seen_region logic to a separate seen.[hc] module for testing. currently failing test: 1) Failure (tests.report.test_lighthouse): ./scripts/tests/common.lua:1051: true expected but was false --- src/CMakeLists.txt | 1 + src/battle.c | 1 + src/bind_unit.c | 1 + src/bindings.c | 1 + src/creport.c | 1 + src/jsreport.c | 1 + src/report.c | 1 + src/reports.c | 119 +------------------------------------ src/reports.h | 29 +-------- src/reports.test.c | 1 + src/seen.c | 142 +++++++++++++++++++++++++++++++++++++++++++++ src/seen.h | 59 +++++++++++++++++++ 12 files changed, 213 insertions(+), 144 deletions(-) create mode 100644 src/seen.c create mode 100644 src/seen.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 922417b03..a57ece3b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,6 +86,7 @@ set (ERESSEA_SRC names.c lighthouse.c reports.c + seen.c eressea.c callback.c direction.c diff --git a/src/battle.c b/src/battle.c index 01a654b7f..718f2620c 100644 --- a/src/battle.c +++ b/src/battle.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "chaos.h" #include "move.h" #include "laws.h" +#include "seen.h" #include "skill.h" #include "monster.h" diff --git a/src/bind_unit.c b/src/bind_unit.c index fc5ee0d8f..bd270318a 100755 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -18,6 +18,7 @@ without prior permission by the authors of Eressea. #include "bindings.h" #include "move.h" #include "reports.h" +#include "seen.h" /* attributes includes */ #include diff --git a/src/bindings.c b/src/bindings.c index 0240a5b49..bc3accb69 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -25,6 +25,7 @@ without prior permission by the authors of Eressea. #include "helpers.h" #include "console.h" #include "reports.h" +#include "seen.h" #include diff --git a/src/creport.c b/src/creport.c index 34ff6c843..9c4cbfbb0 100644 --- a/src/creport.c +++ b/src/creport.c @@ -11,6 +11,7 @@ without prior permission by the authors of Eressea. #include #include "buildno.h" #include "creport.h" +#include "seen.h" #include "travelthru.h" /* tweakable features */ diff --git a/src/jsreport.c b/src/jsreport.c index 56e94ab8b..64d6d4e2d 100644 --- a/src/jsreport.c +++ b/src/jsreport.c @@ -1,5 +1,6 @@ #include "reports.h" #include "jsreport.h" +#include "seen.h" #include #include #include diff --git a/src/report.c b/src/report.c index 9d3c8a191..998eab441 100644 --- a/src/report.c +++ b/src/report.c @@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "reports.h" +#include "seen.h" #include "laws.h" #include "travelthru.h" #include "monster.h" diff --git a/src/reports.c b/src/reports.c index b5cccbab3..8e9a4d563 100644 --- a/src/reports.c +++ b/src/reports.c @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "reports.h" #include "laws.h" +#include "seen.h" #include "travelthru.h" #include "lighthouse.h" @@ -1090,121 +1091,6 @@ static void get_addresses(report_context * ctx) ctx->addresses = flist; } -#define MAXSEEHASH 0x1000 -seen_region *reuse; - -seen_region **seen_init(void) -{ - return (seen_region **)calloc(MAXSEEHASH, sizeof(seen_region *)); -} - -void seen_done(seen_region * seehash[]) -{ - int i; - for (i = 0; i != MAXSEEHASH; ++i) { - seen_region *sd = seehash[i]; - if (sd == NULL) - continue; - while (sd->nextHash != NULL) - sd = sd->nextHash; - sd->nextHash = reuse; - reuse = seehash[i]; - seehash[i] = NULL; - } - /* free(seehash); */ -} - -void free_seen(void) -{ - while (reuse) { - seen_region *r = reuse; - reuse = reuse->nextHash; - free(r); - } -} - -void -link_seen(seen_region * seehash[], const region * first, const region * last) -{ - const region *r = first; - seen_region *sr = NULL; - - if (first == last) - return; - - do { - sr = find_seen(seehash, r); - r = r->next; - } while (sr == NULL && r != last); - - while (r != last) { - seen_region *sn = find_seen(seehash, r); - if (sn != NULL) { - sr->next = sn; - sr = sn; - } - r = r->next; - } - if (sr) sr->next = 0; -} - -seen_region *find_seen(struct seen_region *seehash[], const region * r) -{ - unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1); - seen_region *find = seehash[index]; - while (find) { - if (find->r == r) - return find; - find = find->nextHash; - } - return NULL; -} - -static void get_seen_interval(report_context * ctx) -{ - /* this is required to find the neighbour regions of the ones we are in, - * which may well be outside of [firstregion, lastregion) */ - int i; - - assert(ctx->f->seen); - for (i = 0; i != MAXSEEHASH; ++i) { - seen_region *sr = ctx->f->seen[i]; - while (sr != NULL) { - if (ctx->first == NULL || sr->r->index < ctx->first->index) { - ctx->first = sr->r; - } - if (ctx->last != NULL && sr->r->index >= ctx->last->index) { - ctx->last = sr->r->next; - } - sr = sr->nextHash; - } - } - link_seen(ctx->f->seen, ctx->first, ctx->last); -} - -bool -add_seen(struct seen_region *seehash[], struct region *r, unsigned char mode, -bool dis) -{ - seen_region *find = find_seen(seehash, r); - if (find == NULL) { - unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1); - if (!reuse) - reuse = (seen_region *)calloc(1, sizeof(struct seen_region)); - find = reuse; - reuse = reuse->nextHash; - find->nextHash = seehash[index]; - seehash[index] = find; - find->r = r; - } - else if (find->mode >= mode) { - return false; - } - find->mode = mode; - find->disbelieves |= dis; - return true; -} - typedef struct report_type { struct report_type *next; report_fun write; @@ -1653,7 +1539,8 @@ static void prepare_report(struct report_context *ctx, faction *f) view(f->seen, r, f); } } - get_seen_interval(ctx); + get_seen_interval(ctx->f->seen, &ctx->first, &ctx->last); + link_seen(ctx->f->seen, ctx->first, ctx->last); } int write_reports(faction * f, time_t ltime) diff --git a/src/reports.h b/src/reports.h index f0e666ad1..57a15d074 100644 --- a/src/reports.h +++ b/src/reports.h @@ -26,7 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include struct stream; - +struct seen_region; #ifdef __cplusplus extern "C" { #endif @@ -64,35 +64,8 @@ extern "C" { const struct unit *ucansee(const struct faction *f, const struct unit *u, const struct unit *x); - enum { - see_none, - see_neighbour, - see_lighthouse, - see_travel, - see_far, - see_unit, - see_battle - }; int stealth_modifier(int seen_mode); - typedef struct seen_region { - struct seen_region *nextHash; - struct seen_region *next; - struct region *r; - unsigned char mode; - bool disbelieves; - } seen_region; - - struct seen_region *find_seen(struct seen_region *seehash[], - const struct region *r); - bool add_seen(struct seen_region *seehash[], struct region *r, - unsigned char mode, bool dis); - struct seen_region **seen_init(void); - void seen_done(struct seen_region *seehash[]); - void free_seen(void); - void link_seen(seen_region * seehash[], const struct region *first, - const struct region *last); - typedef struct report_context { struct faction *f; struct quicklist *addresses; diff --git a/src/reports.test.c b/src/reports.test.c index c155188dd..892c5ea62 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -4,6 +4,7 @@ #include "report.h" #include "creport.h" #include "move.h" +#include "seen.h" #include "travelthru.h" #include diff --git a/src/seen.c b/src/seen.c new file mode 100644 index 000000000..a0eb30126 --- /dev/null +++ b/src/seen.c @@ -0,0 +1,142 @@ +/* +Copyright (c) 1998-2015, Enno Rehling +Katja Zedel + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +**/ + +#include +#include +#include "seen.h" + +#include + +#include +#include + +#define MAXSEEHASH 0x1000 +seen_region *reuse; + +seen_region **seen_init(void) +{ + return (seen_region **)calloc(MAXSEEHASH, sizeof(seen_region *)); +} + +void seen_done(seen_region * seehash[]) +{ + int i; + for (i = 0; i != MAXSEEHASH; ++i) { + seen_region *sd = seehash[i]; + if (sd == NULL) + continue; + while (sd->nextHash != NULL) + sd = sd->nextHash; + sd->nextHash = reuse; + reuse = seehash[i]; + seehash[i] = NULL; + } + /* free(seehash); */ +} + +void free_seen(void) +{ + while (reuse) { + seen_region *r = reuse; + reuse = reuse->nextHash; + free(r); + } +} + +void +link_seen(seen_region * seehash[], const region * first, const region * last) +{ + const region *r = first; + seen_region *sr = NULL; + + if (first == last) + return; + + do { + sr = find_seen(seehash, r); + r = r->next; + } while (sr == NULL && r != last); + + while (r != last) { + seen_region *sn = find_seen(seehash, r); + if (sn != NULL) { + sr->next = sn; + sr = sn; + } + r = r->next; + } + if (sr) sr->next = 0; +} + +seen_region *find_seen(struct seen_region *seehash[], const region * r) +{ + unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1); + seen_region *find = seehash[index]; + while (find) { + if (find->r == r) { + return find; + } + find = find->nextHash; + } + return NULL; +} + +void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp) +{ + /* this is required to find the neighbour regions of the ones we are in, + * which may well be outside of [firstregion, lastregion) */ + int i; + region *first, *last; + + assert(seen && firstp && lastp); + first = *firstp; + last = *lastp; + for (i = 0; i != MAXSEEHASH; ++i) { + seen_region *sr = seen[i]; + while (sr != NULL) { + if (first == NULL || sr->r->index < first->index) { + first = sr->r; + } + if (last != NULL && sr->r->index >= last->index) { + last = sr->r->next; + } + sr = sr->nextHash; + } + } +} + +bool add_seen(struct seen_region *seehash[], struct region *r, int mode, bool dis) +{ + seen_region *find = find_seen(seehash, r); + if (find == NULL) { + unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1); + if (!reuse) + reuse = (seen_region *)calloc(1, sizeof(struct seen_region)); + find = reuse; + reuse = reuse->nextHash; + find->nextHash = seehash[index]; + seehash[index] = find; + find->r = r; + } + else if (find->mode >= mode) { + return false; + } + find->mode = mode; + find->disbelieves |= dis; + return true; +} diff --git a/src/seen.h b/src/seen.h new file mode 100644 index 000000000..c46a8a7e0 --- /dev/null +++ b/src/seen.h @@ -0,0 +1,59 @@ +#pragma once +/* +Copyright (c) 1998-2015, Enno Rehling +Katja Zedel + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +**/ + +#ifndef H_SEEN_REGION +#define H_SEEN_REGION + +struct region; +struct seen_region; + +#ifdef __cplusplus +extern "C" { +#endif + + enum { + see_none, + see_neighbour, + see_lighthouse, + see_travel, + see_far, + see_unit, + see_battle + }; + + typedef struct seen_region { + struct seen_region *nextHash; + struct seen_region *next; + struct region *r; + unsigned char mode; + bool disbelieves; + } seen_region; + +struct seen_region **seen_init(void); +void seen_done(struct seen_region *seehash[]); +void free_seen(void); +void link_seen(struct seen_region *seehash[], const struct region * first, const struct region * last); +struct seen_region *find_seen(struct seen_region *seehash[], const struct region * r); +void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp); +bool add_seen(struct seen_region *seehash[], struct region *r, int mode, bool dis); +void link_seen(struct seen_region *seehash[], const struct region *first, const struct region *last); +#ifdef __cplusplus +} +#endif +#endif