载入中...
搜索中...
未找到
Sensing.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
6#include "common/Module.h"
7#include "common/Result.h"
11
12#include <cstdint>
13#include <limits>
14#include <map>
15#include <memory>
16#include <optional>
17#include <set>
18#include <span>
19#include <string>
20#include <string_view>
21#include <unordered_map>
22#include <variant>
23#include <vector>
24
25namespace eve::sensing {
26
28struct Subject {
29 std::string id;
30 float x = 0, y = 0;
31 std::string faction;
32 std::set<std::string> tags;
33 std::set<std::string> visibleTo;
34 std::set<std::string> zones;
35};
36
38struct Candidate {
39 std::string id;
40 float x = 0, y = 0, distance = 0;
41};
42
44enum class CountPolicy : std::uint8_t {
49};
50
52enum class SortKey : std::uint8_t {
53 None,
55};
56
59 float x = 0.f;
60 float y = 0.f;
61 float radius = 0.f;
62};
63
65struct QueryBox {
66 float minX = 0.f;
67 float minY = 0.f;
68 float maxX = 0.f;
69 float maxY = 0.f;
70};
71
78struct QueryCone {
79 float x = 0.f;
80 float y = 0.f;
81 float dirX = 1.f;
82 float dirY = 0.f;
83 float halfAngle = 0.f;
84 float range = 0.f;
85};
86
88using QueryShape = std::variant<std::monostate, QueryCircle, QueryBox, QueryCone>;
89
98struct QuerySpec {
100 float minRange = 0.f;
101 float maxRange = std::numeric_limits<float>::infinity();
102 std::vector<std::string> requiredTags;
103 std::vector<std::string> excludedTags;
104 std::vector<std::string> includeFactions;
105 std::vector<std::string> excludeFactions;
106 std::optional<std::string> visibleTo;
107 std::uint32_t minCount = 0;
108 std::uint32_t maxCount = std::numeric_limits<std::uint32_t>::max();
111
113 [[nodiscard]] eve::Result<void> validate() const;
114};
115
118 float x = 0.f;
119 float y = 0.f;
120 std::optional<std::string> subjectId;
121};
122
125 std::string id;
126 float x = 0.f;
127 float y = 0.f;
128 float distance = 0.f;
129 float score = 0.f;
130 std::string scoreReason;
131};
132
135public:
139 explicit CandidateQueryResult(std::vector<RankedCandidate> ranked) : ranked_(std::move(ranked)) {}
140
142 [[nodiscard]] std::span<const RankedCandidate> ranked() const noexcept { return ranked_; }
144 [[nodiscard]] std::size_t size() const noexcept { return ranked_.size(); }
145
146private:
147 std::vector<RankedCandidate> ranked_;
148};
149
152public:
154 [[nodiscard]] eve::Result<void> upsert(std::string_view id, float x, float y, std::string_view faction,
155 std::string_view tagsCsv, std::string_view visibleToCsv);
157 [[nodiscard]] eve::Result<void> remove(std::string_view id);
165 [[nodiscard]] eve::Result<void> setZones(std::string_view id, std::string_view zonesCsv);
166
175 [[nodiscard]] eve::Result<void> setSpatialIndexEnabled(bool enabled, float cellSize = 64.f);
177 [[nodiscard]] bool spatialIndexEnabled() const noexcept;
178
185 [[nodiscard]] eve::Result<CandidateQueryResult> query(const QueryOrigin& origin, const QuerySpec& spec);
186
188 [[nodiscard]] eve::Result<int> circle(float x, float y, float radius, std::string_view requireTagsCsv,
189 std::string_view excludeTagsCsv, std::string_view includeFactionsCsv,
190 std::string_view excludeFactionsCsv, std::string_view visibleTo, int limit);
192 [[nodiscard]] eve::Result<int> box(float minX, float minY, float maxX, float maxY, std::string_view requireTagsCsv,
193 std::string_view excludeTagsCsv, std::string_view includeFactionsCsv,
194 std::string_view excludeFactionsCsv, std::string_view visibleTo, int limit);
205 [[nodiscard]] eve::Result<int> executePreset(std::string_view presetId, float originX, float originY, float dirX,
206 float dirY);
215 [[nodiscard]] eve::OptionalRef<const Candidate> resultAt(int index) const;
221 [[nodiscard]] std::string debugLastQueryJson() const;
223 std::string snapshotJson() const;
225 [[nodiscard]] eve::Result<void> restoreJson(const std::string& json);
226
228 [[nodiscard]] const std::map<std::string, Subject>& subjects() const noexcept { return subjects_; }
229
230 SensingWorld() = default;
232 ~SensingWorld() = default;
233 SensingWorld(const SensingWorld&) = delete;
236 SensingWorld(SensingWorld&&) noexcept = default;
238 SensingWorld& operator=(SensingWorld&&) noexcept = default;
239
240private:
241 [[nodiscard]] bool accepts(const Subject& subject, const QuerySpec& spec) const;
242 void publishResults(std::vector<RankedCandidate> ranked);
243 void clearSpatialIndex();
244 void rebuildSpatialIndex();
245 void indexSubject(const Subject& subject);
246 void unindexSubject(const std::string& id);
248 [[nodiscard]] bool trySpatialBroadphase(const QueryOrigin& origin, const QuerySpec& spec,
249 std::vector<const Subject*>& out) const;
250
251 std::map<std::string, Subject> subjects_;
252 std::vector<Candidate> results_;
253
254 std::unique_ptr<eve::spatial::SpatialHash2D> spatialIndex_;
255 std::unordered_map<std::string, int> subjectSpatialIds_;
256 std::unordered_map<int, std::string> spatialIdSubjects_;
257 int nextSpatialId_ = 1;
258
259 struct LastQueryDebug {
260 bool usedSpatial = false;
261 std::uint32_t scanned = 0;
262 std::uint32_t accepted = 0;
263 float originX = 0.f;
264 float originY = 0.f;
265 std::string shapeKind = "none";
266 std::vector<RankedCandidate> ranked;
267 };
268 LastQueryDebug lastQuery_;
269};
270
275
278public:
281 Sensing();
283 ~Sensing() override;
292 [[nodiscard]] static eve::Result<SensingWorldHandleRef> newWorld();
294 [[nodiscard]] static eve::script::Borrowed<SensingWorld> resolve(SensingWorldHandleRef reference) noexcept;
298 [[nodiscard]] static bool isStale(SensingWorldHandleRef reference) noexcept;
299
302 [[nodiscard]] int worldCount() const override;
305 [[nodiscard]] std::vector<eve::SensingWorldQuery> lastQueries() const override;
306
307private:
309};
310
318 std::string subjectId;
319 float x = 0.f;
320 float y = 0.f;
321 float distance = 0.f;
322 float score = 0.f;
323 std::string scoreReason;
324};
325
331[[nodiscard]] inline std::vector<PerceptionFact> perceptionFactsFrom(const CandidateQueryResult& result) {
332 std::vector<PerceptionFact> facts;
333 facts.reserve(result.size());
334 for (const auto& candidate : result.ranked()) {
335 PerceptionFact fact;
336 fact.subjectId = candidate.id;
337 fact.x = candidate.x;
338 fact.y = candidate.y;
339 fact.distance = candidate.distance;
340 fact.score = candidate.score;
341 fact.scoreReason = candidate.scoreReason;
342 facts.push_back(std::move(fact));
343 }
344 return facts;
345}
346
347} // namespace eve::sensing
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
int subject
Definition AnimSmr.cpp:163
eve::action::ActionSpatialBinding spatial
AuthorityStoreHandleRef reference
Definition Authority.cpp:24
Vocabulary aliases for nullable and checked borrowed references.
#define EVENGINE_API_PLATFORM
Definition Export.h:107
const std::string * accepts
float radius
std::function< eve::Result< void >()> release
Definition Procgen.cpp:86
Move-only, checked operation results for the common layer.
V3 origin
Definition RoadBake.cpp:138
Explicit Value/Owned/Borrowed semantics at the Squirrel boundary.
int limit
Definition TreeMesh.cpp:164
uint32_t index
Runtime sensing read surface (provided by the sensing module).
EVENGINE_API_FOUNDATION public API.
Definition Module.h:46
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Non-owning C++ observation with no implicit lifetime extension.
Slot/generation registry whose objects are exclusively unique-owned.
Owning ranked result; does not assign a primary target.
Definition Sensing.h:134
std::size_t size() const noexcept
Returns the size of .
Definition Sensing.h:144
CandidateQueryResult(std::vector< RankedCandidate > ranked)
Constructs a CandidateQueryResult.
Definition Sensing.h:139
std::span< const RankedCandidate > ranked() const noexcept
Ranked.
Definition Sensing.h:142
CandidateQueryResult()=default
Constructs a CandidateQueryResult.
Gameplay-facing 2D candidate query service; it never values or selects targets.
Definition Sensing.h:151
~SensingWorld()=default
Sensing world.
const std::map< std::string, Subject > & subjects() const noexcept
Returns a borrowed view of stored subjects for adapters; valid until mutation.
Definition Sensing.h:228
SensingWorld(const SensingWorld &)=delete
SensingWorld(SensingWorld &&) noexcept=default
Sensing world.
SensingWorld & operator=(const SensingWorld &)=delete
Script factory for independent sensing worlds.
Definition Sensing.h:277
SortKey
Ordering applied to ranked query results.
Definition Sensing.h:52
std::vector< PerceptionFact > perceptionFactsFrom(const CandidateQueryResult &result)
Projects ranked query results into adapter-neutral perception facts.
Definition Sensing.h:331
CountPolicy
How candidate-count overflow relative to maxCount is handled.
Definition Sensing.h:44
@ TruncateToMax
Keep the best maxCount candidates after sorting (legacy circle/box limit).
@ FailIfOutOfRange
Fail the query when the filtered set is outside [minCount, maxCount].
std::variant< std::monostate, QueryCircle, QueryBox, QueryCone > QueryShape
Optional broad-phase shape; monostate means range-only around the origin.
Definition Sensing.h:88
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16
std::optional< std::reference_wrapper< T > > OptionalRef
Optional borrowed reference; it does not extend T's lifetime.
Definition BorrowedRef.h:24
bool enabled
A deterministic candidate returned by a spatial query.
Definition Sensing.h:38
Neutral perception fact projected from a ranked sensing candidate.
Definition Sensing.h:317
Inclusive axis-aligned box shape for QuerySpec (World2D).
Definition Sensing.h:65
Circle shape for QuerySpec (World2D).
Definition Sensing.h:58
2D cone/sector shape for QuerySpec (World2D).
Definition Sensing.h:78
World2D origin used for range tests and distance sorting.
Definition Sensing.h:117
std::optional< std::string > subjectId
Definition Sensing.h:120
Configurable candidate query against SensingWorld.
Definition Sensing.h:98
std::vector< std::string > excludedTags
Definition Sensing.h:103
CountPolicy countPolicy
Definition Sensing.h:109
std::vector< std::string > excludeFactions
Definition Sensing.h:105
std::uint32_t minCount
Definition Sensing.h:107
eve::Result< void > validate() const
Validates ranges, counts, tags and shape invariants.
Definition Sensing.cpp:161
std::vector< std::string > requiredTags
Definition Sensing.h:102
std::uint32_t maxCount
Definition Sensing.h:108
std::optional< std::string > visibleTo
Definition Sensing.h:106
std::vector< std::string > includeFactions
Definition Sensing.h:104
One ranked candidate produced by SensingWorld::query.
Definition Sensing.h:124
Handle domain for module-owned sensing worlds.
Definition Sensing.h:272
Mirrored gameplay facts used by candidate queries.
Definition Sensing.h:28
std::string id
Definition Sensing.h:29
std::set< std::string > tags
Definition Sensing.h:32
std::string faction
Definition Sensing.h:31
std::set< std::string > zones
Definition Sensing.h:34
std::set< std::string > visibleTo
Definition Sensing.h:33