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
This commit is contained in:
Enno Rehling 2015-09-08 09:56:56 +02:00
parent d64948f0fc
commit 9312b44f8e
12 changed files with 213 additions and 144 deletions

View File

@ -86,6 +86,7 @@ set (ERESSEA_SRC
names.c
lighthouse.c
reports.c
seen.c
eressea.c
callback.c
direction.c

View File

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

View File

@ -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 <attributes/racename.h>

View File

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

View File

@ -11,6 +11,7 @@ without prior permission by the authors of Eressea.
#include <kernel/config.h>
#include "buildno.h"
#include "creport.h"
#include "seen.h"
#include "travelthru.h"
/* tweakable features */

View File

@ -1,5 +1,6 @@
#include "reports.h"
#include "jsreport.h"
#include "seen.h"
#include <kernel/faction.h>
#include <kernel/region.h>
#include <kernel/terrain.h>

View File

@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "reports.h"
#include "seen.h"
#include "laws.h"
#include "travelthru.h"
#include "monster.h"

View File

@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#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)

View File

@ -26,7 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/types.h>
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;

View File

@ -4,6 +4,7 @@
#include "report.h"
#include "creport.h"
#include "move.h"
#include "seen.h"
#include "travelthru.h"
#include <kernel/building.h>

142
src/seen.c Normal file
View File

@ -0,0 +1,142 @@
/*
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
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 <platform.h>
#include <kernel/config.h>
#include "seen.h"
#include <kernel/region.h>
#include <assert.h>
#include <stdlib.h>
#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;
}

59
src/seen.h Normal file
View File

@ -0,0 +1,59 @@
#pragma once
/*
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
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