载入中...
搜索中...
未找到
HexVisibility.cpp
浏览该文件的文档.
1
7
8#include "common/Diagnostic.h"
9
10#include <algorithm>
11#include <string>
12#include <utility>
13#include <vector>
14
15namespace eve::hexmap {
16namespace {
17
18[[nodiscard]]
23[[nodiscard]] Result<void> validateView(const HexMap& map, const HexVisibility& visibility, HexCoordinates from) {
24 if (!map.contains(from)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "view origin is outside the hex map", "hexmap"));
25 if (visibility.cellCount() != map.cellCount())
26 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "visibility counters must be reset to map.cellCount() before a view update", "hexmap"));
27 return Result<void>::success();
28}
29
30} // namespace
31
32// --- state ------------------------------------------------------------------
33
34void HexVisibility::reset(std::int32_t cellCount) {
35 counts_.assign(cellCount > 0 ? static_cast<std::size_t>(cellCount) : 0u, 0);
36 touched_.clear();
37}
38
39bool HexVisibility::isVisible(std::int32_t cellIndex) const noexcept {
40 if (cellIndex < 0 || cellIndex >= cellCount()) return false;
41 return counts_[static_cast<std::size_t>(cellIndex)] > 0;
42}
43
44std::int32_t HexVisibility::visibility(std::int32_t cellIndex) const noexcept {
45 if (cellIndex < 0 || cellIndex >= cellCount()) return 0;
46 return counts_[static_cast<std::size_t>(cellIndex)];
47}
48
49std::int32_t HexVisibility::visibleCellCount() const noexcept { return static_cast<std::int32_t>(touched_.size()); }
50
51// --- viewers ----------------------------------------------------------------
52
54 std::int32_t range) {
55 Result<void> valid = validateView(map, *this, from);
56 if (!valid.ok()) return valid;
57
58 std::vector<std::int32_t> cells;
59 Result<void> collected = collectVisibleCells(map, scratch, from, range, cells);
60 if (!collected.ok()) return collected;
61
62 for (const std::int32_t index : cells) {
63 // `collectVisibleCells` only reports indices of this map, so the counter is in range.
64 if (++counts_[static_cast<std::size_t>(index)] != 1) continue;
65 // First viewer of this cell: latch it explored and remember the counter so
66 // `clear` can zero the map without a full scan.
67 touched_.push_back(index);
68 map.setExplored(map.coordinatesAt(index), true)
69 .ignore("the cell index comes from this map, so the explored latch cannot be rejected");
70 // The fog overlay of this cell changed shade, so its chunk must be rebuilt.
72 }
73 return Result<void>::success();
74}
75
77 std::int32_t range) {
78 Result<void> valid = validateView(map, *this, from);
79 if (!valid.ok()) return valid;
80
81 std::vector<std::int32_t> cells;
82 Result<void> collected = collectVisibleCells(map, scratch, from, range, cells);
83 if (!collected.ok()) return collected;
84
85 for (const std::int32_t index : cells) {
86 std::int32_t& counter = counts_[static_cast<std::size_t>(index)];
87 if (counter == 0) continue;
88 if (--counter != 0) continue;
89 // The cell lost its last viewer. `touched_` order is unspecified, so a
90 // swap-and-pop removal is fine.
91 const auto entry = std::find(touched_.begin(), touched_.end(), index);
92 if (entry != touched_.end()) {
93 *entry = touched_.back();
94 touched_.pop_back();
95 }
96 // The cell became invisible again: its fog overlay shade changed.
98 }
99 return Result<void>::success();
100}
101
102void HexVisibility::clear(HexMap& map) noexcept {
103 // Every cell that loses its last viewer changes the fog overlay's shade, so each
104 // touched cell's chunk has to be rebuilt. `increase`/`decrease` already do this;
105 // leaving it out here meant dropping the viewers left stale fog geometry on screen
106 // until an unrelated edit happened to dirty the same chunk.
107 for (const std::int32_t index : touched_) {
108 counts_[static_cast<std::size_t>(index)] = 0;
109 map.markChunkDirtyAndNeighbors(map.chunkIndexOf(map.coordinatesAt(index)));
110 }
111 // The map's explored flags are a one-way latch and stay untouched.
112 touched_.clear();
113}
114
115} // namespace eve::hexmap
std::string from
Stable, structured diagnostics shared by engine modules.
float u
Definition Grass.cpp:233
Reference-counted cell visibility and explored state.
Range range
bool valid
std::array< PixelCell, kPixelChunkSize *kPixelChunkSize > cells
uint32_t index
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
bool ok() const noexcept
Whether this result represents a non-failure outcome.
Definition Result.h:255
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
An editable, chunked, pointy-top hex map.
Definition HexMap.h:72
HexCoordinates coordinatesAt(std::int32_t index) const noexcept
Coordinates of a linear cell index; out-of-range indices return (0, 0).
Definition HexMap.cpp:69
std::int32_t chunkIndexOf(HexCoordinates coordinates) const noexcept
Chunk index owning coordinates, or -1 when outside the grid.
Definition HexMap.cpp:102
Result< void > setExplored(HexCoordinates c, bool explored)
Sets the explored (fog-of-war) latch of a cell.
Definition HexMap.cpp:482
void markChunkDirtyAndNeighbors(std::int32_t chunkIndex) noexcept
Marks one chunk and its direct chunk neighbours dirty.
Definition HexMap.cpp:136
Reusable search scratch: one record per cell plus a priority bucket queue.
Definition HexSearch.h:68
std::int32_t visibility(std::int32_t cellIndex) const noexcept
Number of viewers currently covering the cell.
void reset(std::int32_t cellCount)
Sizes the counter array for cellCount cells and zeroes it.
Result< void > increase(HexMap &map, HexSearchContext &scratch, HexCoordinates from, std::int32_t range)
Adds one viewer at from.
std::int32_t visibleCellCount() const noexcept
Number of cells with at least one viewer.
std::int32_t cellCount() const noexcept
Number of tracked cells.
void clear(HexMap &map) noexcept
Drops every viewer, leaving the map's explored flags untouched.
Result< void > decrease(HexMap &map, HexSearchContext &scratch, HexCoordinates from, std::int32_t range)
Removes one viewer at from.
bool isVisible(std::int32_t cellIndex) const noexcept
Whether any viewer currently sees the cell.
Result< void > collectVisibleCells(const HexMap &map, HexSearchContext &scratch, HexCoordinates from, std::int32_t range, std::vector< std::int32_t > &out)
Collects every cell visible from from within range.
Axial coordinates of one hex cell.