载入中...
搜索中...
未找到
RuntimeGenerationScript.cpp
浏览该文件的文档.
2#include <charconv>
6
7namespace eve::procgen {
8namespace {} // namespace
9void exposeRuntimeGeneration(ssq::Table& table) {
10 auto job = table.addClass<ProcgenGenerationJob>(
11 "ProcgenGenerationJob", std::function<ProcgenGenerationJob*()>([] { return nullptr; }), true);
12 job.addFunc("getLevel", &ProcgenGenerationJob::getLevel);
13 job.addFunc("getX", &ProcgenGenerationJob::getX);
14 job.addFunc("getZ", &ProcgenGenerationJob::getZ);
15 job.addFunc("getSeed", &ProcgenGenerationJob::getSeed);
16 job.addFunc("getTicket", &ProcgenGenerationJob::getTicket);
17 job.addFunc("getMinX", &ProcgenGenerationJob::getMinX);
18 job.addFunc("getMinZ", &ProcgenGenerationJob::getMinZ);
19 job.addFunc("getMaxX", &ProcgenGenerationJob::getMaxX);
20 job.addFunc("getMaxZ", &ProcgenGenerationJob::getMaxZ);
21 auto cellRequest = table.addClass<ProcgenCellRequest>(
22 "ProcgenCellRequest", std::function<ProcgenCellRequest*()>([]() -> ProcgenCellRequest* { return nullptr; }),
23 true);
24 cellRequest.addFunc("getLevel", &ProcgenCellRequest::getLevel);
25 cellRequest.addFunc("getX", &ProcgenCellRequest::getX);
26 cellRequest.addFunc("getZ", &ProcgenCellRequest::getZ);
27 cellRequest.addFunc("getSeed", &ProcgenCellRequest::getSeed);
28 cellRequest.addFunc("getTicket", &ProcgenCellRequest::getTicket);
29 cellRequest.addFunc("getMinX", &ProcgenCellRequest::getMinX);
30 cellRequest.addFunc("getMinZ", &ProcgenCellRequest::getMinZ);
31 cellRequest.addFunc("getMaxX", &ProcgenCellRequest::getMaxX);
32 cellRequest.addFunc("getMaxZ", &ProcgenCellRequest::getMaxZ);
33
34 auto runtimeGeneration = table.addClass<RuntimeGeneration>(
35 "ProcgenRuntimeGeneration", std::function<RuntimeGeneration*()>([]() -> RuntimeGeneration* { return nullptr; }),
36 true);
37 runtimeGeneration.addFunc("clear", &RuntimeGeneration::clear);
38 runtimeGeneration.addFunc("addLevel", &RuntimeGeneration::addLevel);
39 runtimeGeneration.addFunc("getLevelCount", &RuntimeGeneration::getLevelCount);
40 runtimeGeneration.addFunc("getLevelCellSize", &RuntimeGeneration::getLevelCellSize);
41 runtimeGeneration.addFunc("getLevelGenerationRadius", &RuntimeGeneration::getLevelGenerationRadius);
42 runtimeGeneration.addFunc("getLevelCleanupRadius", &RuntimeGeneration::getLevelCleanupRadius);
43 runtimeGeneration.addFunc("setDirectionWeight", &RuntimeGeneration::setDirectionWeight);
44 runtimeGeneration.addFunc("getDirectionWeight", &RuntimeGeneration::getDirectionWeight);
45 runtimeGeneration.addFunc("setMaxGenerating", &RuntimeGeneration::setMaxGenerating);
46 runtimeGeneration.addFunc("getMaxGenerating", &RuntimeGeneration::getMaxGenerating);
47 runtimeGeneration.addFunc("setMaxActiveCells", &RuntimeGeneration::setMaxActiveCells);
48 runtimeGeneration.addFunc("getMaxActiveCells", &RuntimeGeneration::getMaxActiveCells);
49 runtimeGeneration.addFunc("setMaxPointsPerCell", &RuntimeGeneration::setMaxPointsPerCell);
50 runtimeGeneration.addFunc("getMaxPointsPerCell", &RuntimeGeneration::getMaxPointsPerCell);
51 runtimeGeneration.addFunc("setMaxResidentPoints", &RuntimeGeneration::setMaxResidentPoints);
52 runtimeGeneration.addFunc("getMaxResidentPoints", &RuntimeGeneration::getMaxResidentPoints);
53 runtimeGeneration.addFunc("getResidentPointCount", &RuntimeGeneration::getResidentPointCount);
54 runtimeGeneration.addFunc("getRejectedOutputCount", &RuntimeGeneration::getRejectedOutputCount);
55 runtimeGeneration.addFunc("trimToResidentPoints", &RuntimeGeneration::trimToResidentPoints);
56 runtimeGeneration.addFunc("setMaxGenerationRetries", &RuntimeGeneration::setMaxGenerationRetries);
57 runtimeGeneration.addFunc("getMaxGenerationRetries", &RuntimeGeneration::getMaxGenerationRetries);
58 runtimeGeneration.addFunc("setFrameTimeBudget", &RuntimeGeneration::setFrameTimeBudget);
59 runtimeGeneration.addFunc("getFrameTimeBudget", &RuntimeGeneration::getFrameTimeBudget);
60 runtimeGeneration.addFunc("beginFrame", &RuntimeGeneration::beginFrame);
61 runtimeGeneration.addFunc("setRefreshWorkBudget", &RuntimeGeneration::setRefreshWorkBudget);
62 runtimeGeneration.addFunc("getRefreshWorkBudget", &RuntimeGeneration::getRefreshWorkBudget);
63 runtimeGeneration.addFunc("isRefreshPending", &RuntimeGeneration::isRefreshPending);
64 runtimeGeneration.addFunc("getCommittedRefreshRevision", &RuntimeGeneration::getCommittedRefreshRevision);
65 runtimeGeneration.addFunc("continueGenerationRefresh", [vm = runtimeGeneration.getHandle()](
67 return eve::script::projectResult(
68 vm,
69 value ? value->continueGenerationRefresh()
70 : Result<std::uint64_t>::failure(Diagnostic::error(
71 eve::DiagnosticCode::InvalidArgument, "continueGenerationRefresh requires RuntimeGeneration",
72 "runtimeGeneration", {}, "procgen.runtimeGeneration")),
73 [](std::uint64_t processed) { return eve::Value(std::to_string(processed)); });
74 });
75 runtimeGeneration.addFunc("updateSource", &RuntimeGeneration::updateSource);
76 runtimeGeneration.addFunc("setGenerationSource", &RuntimeGeneration::setGenerationSource);
77 runtimeGeneration.addFunc("removeGenerationSource", &RuntimeGeneration::removeGenerationSource);
78 runtimeGeneration.addFunc("clearGenerationSources", &RuntimeGeneration::clearGenerationSources);
79 runtimeGeneration.addFunc("getGenerationSourceCount", &RuntimeGeneration::getGenerationSourceCount);
80 runtimeGeneration.addFunc("getGenerationSourceId", &RuntimeGeneration::getGenerationSourceId);
81 runtimeGeneration.addFunc("refreshGenerationSources", &RuntimeGeneration::refreshGenerationSources);
82 runtimeGeneration.addFunc("setFrustumCulling", &RuntimeGeneration::setFrustumCulling);
83 runtimeGeneration.addFunc("isFrustumCullingEnabled", &RuntimeGeneration::isFrustumCullingEnabled);
84 runtimeGeneration.addFunc("getFrustumHalfAngle", &RuntimeGeneration::getFrustumHalfAngle);
85 runtimeGeneration.addFunc("getFrustumBehindRadius", &RuntimeGeneration::getFrustumBehindRadius);
86 runtimeGeneration.addFunc("getPendingGenerateCount", &RuntimeGeneration::getPendingGenerateCount);
87 runtimeGeneration.addFunc("getGeneratingCount", &RuntimeGeneration::getGeneratingCount);
88 runtimeGeneration.addFunc("getActiveCellCount", &RuntimeGeneration::getActiveCellCount);
89 runtimeGeneration.addFunc("getPendingCleanupCount", &RuntimeGeneration::getPendingCleanupCount);
90 runtimeGeneration.addFunc("getCancelledGenerationCount", &RuntimeGeneration::getCancelledGenerationCount);
91 runtimeGeneration.addFunc("getFailedCellCount", &RuntimeGeneration::getFailedCellCount);
92 runtimeGeneration.addFunc("retryFailedCells", &RuntimeGeneration::retryFailedCells);
93 runtimeGeneration.addFunc("nextGenerate", &RuntimeGeneration::nextGenerate);
94 runtimeGeneration.addFunc("nextGenerationJob", [vm = runtimeGeneration.getHandle()](RuntimeGeneration* self) {
95 auto object =
96 eve::script::makeOwnedSquirrelInstance<ProcgenGenerationJob>(vm, std::make_unique<ProcgenGenerationJob>());
97 if (!object.ok()) return eve::script::projectStatusResult(vm, object.status());
98 auto result = self->nextGenerationJob();
99 if (!result.ok()) return eve::script::projectStatusResult(vm, result.status());
100 auto value = std::move(result).takeValue();
102 auto owned = std::move(object).takeValue();
103 *owned.to<ProcgenGenerationJob*>() = *value;
105 });
106 runtimeGeneration.addFunc(
107 "completeGenerationJob",
108 [vm = runtimeGeneration.getHandle()](RuntimeGeneration* self, ProcgenGenerationJob* job, PointSet* output) {
110 vm,
111 job && output ? self->completeGenerationJob({*job, *output})
112 : Result<uint64_t>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,
113 "job and output are required", "completion",
114 {}, "procgen.runtimeGeneration")),
115 [](uint64_t revision) { return Value(std::to_string(revision)); });
116 });
117 runtimeGeneration.addFunc(
118 "failGenerationJob", [vm = runtimeGeneration.getHandle()](RuntimeGeneration* self, ProcgenGenerationJob* job) {
120 vm, job ? self->failGenerationJob(*job)
121 : Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "job is required",
122 "job", {}, "procgen.runtimeGeneration")));
123 });
124 runtimeGeneration.addFunc("nextCleanupRequest", [vm = runtimeGeneration.getHandle()](RuntimeGeneration* self) {
125 // Allocate the registered script wrapper before consuming a queue entry.
126 auto object =
127 eve::script::makeOwnedSquirrelInstance<ProcgenCellRequest>(vm, std::make_unique<ProcgenCellRequest>());
128 if (!object.ok()) return eve::script::projectStatusResult(vm, object.status());
129 auto result = self->nextCleanupRequest();
130 if (!result.ok()) return eve::script::projectStatusResult(vm, result.status());
131 auto value = std::move(result).takeValue();
133 auto owned = std::move(object).takeValue();
134 *owned.to<ProcgenCellRequest*>() = *value;
136 });
137 runtimeGeneration.addFunc("completeCleanupRequest", [vm = runtimeGeneration.getHandle()](
138 RuntimeGeneration* self, ProcgenCellRequest* request) {
140 request ? self->completeCleanupRequest(*request)
141 : Result<uint64_t>::failure(Diagnostic::error(
142 DiagnosticCode::InvalidArgument, "cleanup request is required",
143 "request", {}, "procgen.runtimeGeneration")),
144 [](uint64_t count) { return Value(std::to_string(count)); });
145 });
146 runtimeGeneration.addFunc("nextCleanup", &RuntimeGeneration::nextCleanup);
147 runtimeGeneration.addFunc("isRequestCurrent", &RuntimeGeneration::isRequestCurrent);
148 runtimeGeneration.addFunc("completeGeneration", &RuntimeGeneration::completeGeneration);
149 runtimeGeneration.addFunc("failGeneration", &RuntimeGeneration::failGeneration);
150 runtimeGeneration.addFunc("completeCleanup", &RuntimeGeneration::completeCleanup);
151 runtimeGeneration.addFunc("completeCleanupsAtomic", [vm = runtimeGeneration.getHandle()](RuntimeGeneration* value,
152 ssq::Array requestArray) {
153 std::vector<const ProcgenCellRequest*> requests;
154 requests.reserve(requestArray.size());
155 for (size_t index = 0; index < requestArray.size(); ++index)
156 requests.push_back(requestArray.get<ProcgenCellRequest*>(index));
158 vm,
159 value ? value->completeCleanupsAtomic(requests)
160 : Result<std::uint64_t>::failure(Diagnostic::error(
161 eve::DiagnosticCode::InvalidArgument, "completeCleanupsAtomic requires RuntimeGeneration",
162 "runtime", {}, "procgen.runtimeGeneration")),
163 [](std::uint64_t completed) { return eve::Value(std::to_string(completed)); });
164 });
165 runtimeGeneration.addFunc("hasCell", &RuntimeGeneration::hasCell);
166 runtimeGeneration.addFunc("getCellOutput", &RuntimeGeneration::getCellOutput);
167 runtimeGeneration.addFunc("getCellRevision", &RuntimeGeneration::getCellRevision);
168 runtimeGeneration.addFunc(
169 "applyCellUpdate", [vm = runtimeGeneration.getHandle()](RuntimeGeneration* value, int level, int x, int z,
170 const std::string& revisionText, PointSet* output) {
171 std::uint64_t revision = 0;
172 const auto [end, error] =
173 std::from_chars(revisionText.data(), revisionText.data() + revisionText.size(), revision);
174 if (!output || error != std::errc{} || end != revisionText.data() + revisionText.size() || revision == 0)
176 vm,
179 "applyCellUpdate requires an output and a non-zero decimal revision",
180 "revision", {}, "procgen.runtimeGeneration")),
181 [](std::uint64_t committed) { return eve::Value(std::to_string(committed)); });
183 vm, value->applyCellUpdate(level, x, z, revision, *output),
184 [](std::uint64_t committed) { return eve::Value(std::to_string(committed)); });
185 });
186 runtimeGeneration.addFunc(
187 "migrateCellPointIds", [vm = runtimeGeneration.getHandle()](RuntimeGeneration* value, int level, int x, int z,
188 const std::string& revisionText) {
189 std::uint64_t revision = 0;
190 const auto [end, error] =
191 std::from_chars(revisionText.data(), revisionText.data() + revisionText.size(), revision);
192 if (error != std::errc{} || end != revisionText.data() + revisionText.size() || revision == 0)
194 vm,
197 "migrateCellPointIds requires a non-zero decimal revision", "revision", {},
198 "procgen.runtimeGeneration")),
199 [](std::uint64_t committed) { return eve::Value(std::to_string(committed)); });
201 vm, value->migrateCellPointIds(level, x, z, revision),
202 [](std::uint64_t committed) { return eve::Value(std::to_string(committed)); });
203 });
204 runtimeGeneration.addFunc("getCellDelta", &RuntimeGeneration::getCellDelta);
205 runtimeGeneration.addFunc("serializeCell", &RuntimeGeneration::serializeCell);
206 runtimeGeneration.addFunc("deserializeCell", &RuntimeGeneration::deserializeCell);
207 runtimeGeneration.addFunc("debugReport", &RuntimeGeneration::debugReport);
208}
209} // namespace eve::procgen
double value
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::string output
ActiveSource owned
HSQUIRRELVM vm
Definition ECS.cpp:20
const GltfImportRequest & request
wgpu::PopErrorScopeStatus status
int level
std::string error
Definition Package.cpp:60
std::uint64_t revision
std::uint32_t count
The single Squirrel projection for common Result, Status and Value.
Explicit Value/Owned/Borrowed semantics at the Squirrel boundary.
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
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
The canonical owning dynamic value used by data-facing protocols.
Definition Value.h:31
One immutable runtime-generation cell request returned to script.
float getMinZ() const
Returns the min z.
int getLevel() const
Returns the level.
float getMinX() const
Returns the min x.
float getMaxZ() const
Returns the max z.
uint32_t getSeed() const
Returns the seed.
uint64_t getTicket() const
Unique scheduler ticket used to reject stale asynchronous completions.
float getMaxX() const
Returns the max x.
Copyable generation input issued by one RuntimeGeneration scheduler.
float getMaxZ() const
Return the captured upper world-space Z bound.
float getMaxX() const
Return the captured upper world-space X bound.
uint32_t getSeed() const
Return the deterministic seed derived from world seed, level and coordinates.
float getMinX() const
Return the captured lower world-space X bound.
float getMinZ() const
Return the captured lower world-space Z bound.
uint64_t getTicket() const
Return the ticket; valid only together with this job's private scheduler identity.
int getZ() const
Return the cell Z coordinate captured at issue time.
int getX() const
Return the cell X coordinate captured at issue time.
int getLevel() const
Return the hierarchical grid level captured at issue time.
View-driven partition and hierarchical procedural generation scheduler.
void setMaxPointsPerCell(int count)
Set the maximum points allowed in one generated cell; zero disables the limit.
bool completeGeneration(ProcgenCellRequest *request, PointSet *output)
Compatibility-only bool projection of completeGenerationJob; request and output are borrowed.
bool isFrustumCullingEnabled() const
True when frustum culling enabled.
bool deserializeCell(const std::string &definition)
Atomically restore one cell produced by serializeCell for this world seed.
float getFrustumBehindRadius() const
Returns the frustum behind radius.
int getPendingGenerateCount() const
Returns the pending generate count.
int trimToResidentPoints(int target)
Schedule lowest-priority active cells for cleanup until at most target points remain.
bool isRequestCurrent(const ProcgenCellRequest *request) const
Test whether an issued generation or cleanup request still owns its scheduler ticket.
void beginFrame()
Start a new budget window before consuming generation requests.
float getLevelCellSize(int level) const
Returns the level cell size.
int addLevel(float cellSize, float generationRadius, float cleanupMultiplier)
Add a hierarchical grid level.
int getCancelledGenerationCount() const
Return issued generation requests invalidated before completion.
int getActiveCellCount() const
Returns the active cell count.
int getLevelCount() const
Returns the level count.
float getLevelCleanupRadius(int level) const
Returns the level cleanup radius.
bool hasCell(int level, int x, int z) const
void clearGenerationSources()
Clears generation sources.
int getPendingCleanupCount() const
Returns the pending cleanup count.
float getDirectionWeight() const
Returns the direction weight.
void setFrustumCulling(bool enabled, float halfAngleDegrees, float behindRadius)
Enable view-cone scheduling.
int getGeneratingCount() const
Returns the generating count.
std::string serializeCell(int level, int x, int z) const
Serialize one active cell cache entry in a deterministic versioned format.
int getMaxGenerationRetries() const
Return retries allowed after the initial generation attempt.
uint64_t getCommittedRefreshRevision() const
Return the latest source revision atomically published into generation and cleanup queues.
bool isRefreshPending() const
Return whether a staged source snapshot still needs planning work.
uint64_t getCellRevision(int level, int x, int z) const
Returns the cell revision.
void setFrameTimeBudget(float milliseconds)
CPU issue budget in milliseconds for one frame; zero disables the limit.
bool failGeneration(ProcgenCellRequest *request)
Compatibility-only bool projection of failGenerationJob; request is borrowed.
int getRefreshWorkBudget() const
Return the per-call source-refresh candidate budget, or zero when synchronous.
ProcgenCellRequest * nextGenerate()
Compatibility facade returning a heap request; prefer nextGenerationJob().
int getMaxResidentPoints() const
Return the total resident-point limit, or zero when unlimited.
bool removeGenerationSource(const std::string &id)
Removes generation source.
int getGenerationSourceCount() const
Returns the generation source count.
PointSet * getCellOutput(int level, int x, int z) const
Returns the cell output.
float getLevelGenerationRadius(int level) const
Returns the level generation radius.
int getFailedCellCount() const
Return cells stopped after exhausting the generation retry policy.
int retryFailedCells()
Reset and requeue all terminally failed cells still tracked by the scheduler.
int getMaxGenerating() const
Returns the max generating.
float getFrustumHalfAngle() const
Returns the frustum half angle.
PointDelta * getCellDelta(int level, int x, int z) const
Return a caller-owned copy of the latest committed delta, or null when unavailable....
bool setGenerationSource(const std::string &id, float x, float z, float directionX, float directionZ, float radiusScale=1.f)
Add or update a named generation source, then rebuild desired cells.
void updateSource(float x, float z, float directionX, float directionZ)
Recompute desired cells for a generation source.
std::string getGenerationSourceId(int index) const
Returns the generation source id.
bool completeCleanup(ProcgenCellRequest *request)
Compatibility-only bool projection of completeCleanupsAtomic; request is borrowed.
void setMaxGenerating(int count)
Maximum simultaneously issued generation requests.
void setMaxActiveCells(int count)
Maximum active plus in-flight cells; zero disables the resident-cell limit.
float getFrameTimeBudget() const
Returns the frame time budget.
void setMaxGenerationRetries(int count)
Set retries after the initial generation attempt; zero fails immediately.
int getMaxPointsPerCell() const
Return the per-cell point limit, or zero when unlimited.
int getRejectedOutputCount() const
Return generation or restore outputs rejected by point budgets.
std::string debugReport() const
Debug report.
void setDirectionWeight(float weight)
Weight favoring cells in front of the source, clamped to [0,1].
int getResidentPointCount() const
Return points retained by active or not-yet-acknowledged cleanup cells.
ProcgenCellRequest * nextCleanup()
Compatibility-only heap projection of nextCleanupRequest; caller owns the returned request.
void setRefreshWorkBudget(int candidateCells)
Limit source-refresh planning work performed by one call.
void refreshGenerationSources()
Re-evaluate generation/cleanup queues from every registered source.
int getMaxActiveCells() const
Return the resident-cell limit, or zero when unlimited.
void clear()
Remove levels, cells, queues and outputs while retaining the world seed.
void setMaxResidentPoints(int count)
Set the total point limit across active cell outputs; zero disables the limit.
eve::Diagnostic Diagnostic
eve::Result< T > Result
void exposeRuntimeGeneration(ssq::Table &table)
Register owner-thread runtime-generation script interfaces.
ssq::Table projectStatusResult(HSQUIRRELVM vm, const Status &status)
Project a checked native status that carries no payload.
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16
DiagnosticCode
Stable machine-readable diagnostic codes.
Definition Diagnostic.h:47