载入中...
搜索中...
未找到
LineOfSightRouter.cpp
浏览该文件的文档.
1
7
8#include "common/Capability.h"
9#include "common/Diagnostic.h"
10
11#include <optional>
12#include <utility>
13
14namespace eve::sensing {
15namespace {
16
17template <typename T>
18Result<T> failure(DiagnosticCode code, std::string message, std::string path) {
20}
21
23std::string locationPath(const char* name) { return std::string("lineOfSight.") + name; }
24
26LineOfSightRouter& routerHolder() {
27 static LineOfSightRouter router;
28 return router;
29}
30
31} // namespace
32
34 LineOfSightRouter& router = routerHolder();
35 ILineOfSightQuery* registered = cap::query<ILineOfSightQuery>();
36 if (registered == &router) return Result<LineOfSightRouter*>::success(&router);
37 if (registered != nullptr)
38 // Respect an existing registration instead of replacing it, so a project that owns its
39 // own implementation is never silently overridden by a backend claiming a space.
40 return failure<LineOfSightRouter*>(DiagnosticCode::Conflict,
41 "another line-of-sight provider is already registered",
42 "lineOfSight.provider");
43 cap::provide<ILineOfSightQuery>(&router);
45}
46
47std::optional<CoordinateSpace> LineOfSightRouter::spaceOf(const TargetLocation& location) noexcept {
48 return std::visit(
49 [](const auto& point) -> std::optional<CoordinateSpace> { return point.space(); }, location);
50}
51
53 if (provider == nullptr)
54 return failure<void>(DiagnosticCode::InvalidArgument,
55 "line-of-sight backend must not be null", "lineOfSight.provider");
56 const auto index = static_cast<std::size_t>(space);
57 if (index >= providers_.size())
58 return failure<void>(DiagnosticCode::InvalidArgument,
59 "unknown line-of-sight coordinate space", "lineOfSight.space");
60 if (providers_[index] != nullptr)
61 // Replace would make the effective backend depend on registration order, which is the
62 // problem this router exists to remove.
63 return failure<void>(DiagnosticCode::Conflict,
64 "line-of-sight coordinate space already has a backend", "lineOfSight.space");
65 providers_[index] = provider;
67}
68
70 const auto index = static_cast<std::size_t>(space);
71 if (index >= providers_.size() || providers_[index] != provider)
73 providers_[index] = nullptr;
75}
76
78 const auto index = static_cast<std::size_t>(space);
79 return index < providers_.size() && providers_[index] != nullptr;
80}
81
82std::vector<CoordinateSpace> LineOfSightRouter::spaces() const {
83 std::vector<CoordinateSpace> claimed;
84 for (std::size_t index = 0; index < providers_.size(); ++index) {
85 if (providers_[index] != nullptr) claimed.push_back(static_cast<CoordinateSpace>(index));
86 }
87 return claimed;
88}
89
91 const TargetLocation& to) const {
92 const auto fromSpace = spaceOf(from);
93 const auto toSpace = spaceOf(to);
94 if (!fromSpace || !toSpace)
95 return failure<LineOfSightResult>(DiagnosticCode::InvalidArgument,
96 "line-of-sight endpoints must be valid points",
97 locationPath("from"));
98 if (*fromSpace != *toSpace)
99 // The interface forbids converting between spaces, so a mixed query is a caller error
100 // rather than something to approximate.
101 return failure<LineOfSightResult>(DiagnosticCode::InvalidArgument,
102 "line-of-sight endpoints must share a coordinate space",
103 locationPath("to"));
104 const auto index = static_cast<std::size_t>(*fromSpace);
105 if (index >= providers_.size() || providers_[index] == nullptr)
106 return failure<LineOfSightResult>(DiagnosticCode::Unsupported,
107 "no line-of-sight backend for coordinate space " +
108 std::string(coordinateSpaceName(*fromSpace)),
109 locationPath("from"));
110 return providers_[index]->query(from, to);
111}
112
113} // namespace eve::sensing
std::string from
Stable, structured diagnostics shared by engine modules.
std::string message
DiagnosticCode code
HexCoordinates to
Cell the unit walks towards on this segment.
Definition HexUnits.cpp:64
One registered line-of-sight provider that dispatches to backends by coordinate space.
std::string name
std::string path
Definition PlayHost.cpp:110
uint32_t index
glm::vec3 point
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
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
Consumer-owned line-of-sight capability.
Definition Targeting.h:431
Routes each line-of-sight query to the backend that claimed its coordinate space.
std::vector< CoordinateSpace > spaces() const
Claimed spaces in enum order, so a caller can report coverage deterministically.
Result< void > addProvider(CoordinateSpace space, const ILineOfSightQuery *provider)
Claim one coordinate space for a backend.
bool hasProvider(CoordinateSpace space) const noexcept
Whether some backend currently answers for space.
Result< LineOfSightResult > query(const TargetLocation &from, const TargetLocation &to) const override
Answer one segment query by routing it to the backend for its coordinate space.
Result< void > removeProvider(CoordinateSpace space, const ILineOfSightQuery *provider)
Release a claimed space when provider is the one that claimed it.
std::variant< WorldPoint, GridPoint > TargetLocation
Either a world point or a grid point, with the tag retained.
Definition Targeting.h:198
Result< LineOfSightRouter * > ensureLineOfSightRouter()
The process-wide router, registered as the ILineOfSightQuery capability.
CoordinateSpace
Coordinate spaces are not interchangeable, even when dimensions match.
Definition Targeting.h:37
std::string_view coordinateSpaceName(CoordinateSpace space) noexcept
Returns the stable protocol name for a coordinate space.
DiagnosticCode
Stable machine-readable diagnostic codes.
Definition Diagnostic.h:47