133 int addLevel(
float cellSize,
float generationRadius,
float cleanupMultiplier);
135 int getLevelCount()
const;
137 float getLevelCellSize(
int level)
const;
139 float getLevelGenerationRadius(
int level)
const;
141 float getLevelCleanupRadius(
int level)
const;
144 void setDirectionWeight(
float weight);
146 float getDirectionWeight()
const;
148 void setMaxGenerating(
int count);
150 int getMaxGenerating()
const;
152 void setMaxActiveCells(
int count);
154 int getMaxActiveCells()
const;
156 void setMaxPointsPerCell(
int count);
158 int getMaxPointsPerCell()
const;
160 void setMaxResidentPoints(
int count);
162 int getMaxResidentPoints()
const;
164 int getResidentPointCount()
const;
166 int getRejectedOutputCount()
const;
171 int trimToResidentPoints(
int target);
173 void setMaxGenerationRetries(
int count);
175 int getMaxGenerationRetries()
const;
179 float getFrameTimeBudget()
const;
192 void setRefreshWorkBudget(
int candidateCells);
194 int getRefreshWorkBudget()
const;
196 bool isRefreshPending()
const;
198 uint64_t getCommittedRefreshRevision()
const;
213 void updateSource(
float x,
float z,
float directionX,
float directionZ);
215 bool setGenerationSource(
const std::string&
id,
float x,
float z,
float directionX,
216 float directionZ,
float radiusScale = 1.f);
218 bool removeGenerationSource(
const std::string&
id);
220 void clearGenerationSources();
222 int getGenerationSourceCount()
const;
224 std::string getGenerationSourceId(
int index)
const;
226 void refreshGenerationSources();
233 void setFrustumCulling(
bool enabled,
float halfAngleDegrees,
float behindRadius);
235 bool isFrustumCullingEnabled()
const;
237 float getFrustumHalfAngle()
const;
239 float getFrustumBehindRadius()
const;
242 int getPendingGenerateCount()
const;
244 int getGeneratingCount()
const;
246 int getActiveCellCount()
const;
248 int getPendingCleanupCount()
const;
250 int getCancelledGenerationCount()
const;
252 int getFailedCellCount()
const;
254 int retryFailedCells();
293 bool isOwnerThread() const noexcept;
326 bool hasCell(
int level,
int x,
int z) const;
330 uint64_t getCellRevision(
int level,
int x,
int z) const;
337 [[nodiscard]]
Result<uint64_t> applyCellUpdate(
int level,
int x,
int z, uint64_t expectedRevision,
343 [[nodiscard]]
Result<uint64_t> migrateCellPointIds(
int level,
int x,
int z, uint64_t expectedRevision);
351 std::
string serializeCell(
int level,
int x,
int z) const;
355 std::
string debugReport() const;
361 float cellSize = 1.f;
362 float generationRadius = 1.f;
363 float cleanupRadius = 1.f;
365 enum class State {
Pending, Generating, Active, Cleanup,
Failed };
371 bool operator==(
const CellKey& other)
const {
372 return level == other.level &&
x == other.x &&
z == other.z;
377 size_t operator()(
const CellKey&
key)
const;
385 bool trimmed =
false;
388 bool hasDelta =
false;
393 float directionX = 0.f;
394 float directionZ = 0.f;
395 float radiusScale = 1.f;
399 std::vector<Level> levels;
400 std::vector<Source> sources;
401 std::unordered_map<CellKey, float, CellKeyHash> desiredPriorities;
402 float directionWeight = 0.f;
403 float frustumHalfAngle = 180.f;
404 float coneCosine = -1.f;
405 float frustumBehindRadius = 0.f;
406 bool frustumCulling =
false;
407 size_t sourceIndex = 0;
408 size_t levelIndex = 0;
415 bool rangeReady =
false;
418 ProcgenCellRequest makeRequest(
const CellKey&
key)
const;
419 ProcgenGenerationJob makeGenerationJob(
const CellKey&
key)
const;
420 std::optional<ProcgenGenerationJob> issueGenerationJob();
421 [[nodiscard]] Result<std::reference_wrapper<Cell>> validateGenerationJob(
const ProcgenGenerationJob& job);
422 void transitionCellState(Cell&
cell, State nextState);
423 void requestGenerationRefresh();
424 void startRefreshPlan();
425 uint64_t advanceRefreshPlan(uint64_t candidateBudget);
426 void commitRefreshPlan(
const RefreshPlan& plan);
427 [[nodiscard]] Result<void> validateCleanups(
const std::vector<const ProcgenCellRequest*>& requests)
const;
428 void eraseValidatedCleanups(
const std::vector<const ProcgenCellRequest*>& requests);
429 uint32_t cellSeed(
const CellKey&
key)
const;
432 uint32_t worldSeed_ = 1;
433 std::thread::id ownerThread_;
434 const uint64_t schedulerId_;
435 float directionWeight_ = 0.25f;
436 int maxGenerating_ = 4;
437 int maxActiveCells_ = 0;
438 int maxPointsPerCell_ = 0;
439 int maxResidentPoints_ = 0;
440 int rejectedOutputCount_ = 0;
441 int cancelledGenerationCount_ = 0;
442 int maxGenerationRetries_ = 3;
443 float frameTimeBudgetMs_ = 0.f;
444 uint64_t frameStartedNs_ = 0;
445 int refreshWorkBudget_ = 0;
446 uint64_t sourceRevision_ = 0;
447 uint64_t committedRefreshRevision_ = 0;
448 std::optional<RefreshPlan> refreshPlan_;
449 bool frustumCulling_ =
false;
450 float frustumHalfAngle_ = 60.f;
451 float frustumBehindRadius_ = 0.f;
452 std::vector<Level> levels_;
453 std::unordered_map<std::string, Source> sources_;
454 std::vector<std::string> sourceOrder_;
455 std::unordered_map<CellKey, Cell, CellKeyHash> cells_;
456 std::deque<CellKey> generateQueue_;
457 std::deque<CellKey> cleanupQueue_;
458 int generatingCount_ = 0;
459 int activeCellCount_ = 0;
460 uint64_t nextTicket_ = 0;