API reference / @jsprismarine/chunkgen / ChunkHolder
Class: ChunkHolder<TChunk>
Defined in: ChunkHolder.ts:80
One chunk's place in the ladder: the promise each status resolved to, and who still needs it.
This is Java's GenerationChunkHolder. Two mechanisms carry the whole design.
One promise per status, created by the first caller and awaited by every later one, is what makes a (chunk, status) body run exactly once however many requests overlap. Java needs a compare-and-exchange on startedWork because several pool threads reach applyStep at once; only the thread that owns the holder map touches a holder here, and a map insert cannot be interleaved, so the promise slot does the same job. startedWork is kept anyway, because it is what catches a layer loop that skips a rung.
A reference count, rather than a cache eviction policy, decides when the holder goes away. Every generation task that needs this chunk inside its radius acquires one and releases it when it finishes, and ChunkHolderMap drops the holder at zero. An LRU would evict a chunk a running feature pass is still writing into.
Type Parameters
TChunk
TChunk extends StagedChunk
Constructors
Constructor
new ChunkHolder<
TChunk>(chunkX,chunkZ,newChunk):ChunkHolder<TChunk>
Defined in: ChunkHolder.ts:96
Parameters
chunkX
number
Chunk x coordinate.
chunkZ
number
Chunk z coordinate.
newChunk
(chunkX, chunkZ) => TChunk
Allocates the chunk the empty status starts from. It is called once, on the first step, so a holder that is acquired and never stepped costs nothing. A server that reads chunks from disk replaces this with the load.
Returns
ChunkHolder<TChunk>
Properties
chunkX
readonlychunkX:number
Defined in: ChunkHolder.ts:97
Chunk x coordinate.
chunkZ
readonlychunkZ:number
Defined in: ChunkHolder.ts:98
Chunk z coordinate.
Accessors
referenceCount
Get Signature
get referenceCount():
number
Defined in: ChunkHolder.ts:113
How many generation tasks still need this chunk.
Returns
number
startedStatus
Get Signature
get startedStatus():
"empty"|"structure_starts"|"structure_references"|"biomes"|"terrain"|"features"|"initialize_light"|"light"|"spawn"|"full"|undefined
Defined in: ChunkHolder.ts:108
The highest status whose body has been started, which is at or above status.
Returns
"empty" | "structure_starts" | "structure_references" | "biomes" | "terrain" | "features" | "initialize_light" | "light" | "spawn" | "full" | undefined
status
Get Signature
get status():
"empty"|"structure_starts"|"structure_references"|"biomes"|"terrain"|"features"|"initialize_light"|"light"|"spawn"|"full"|undefined
Defined in: ChunkHolder.ts:103
The highest status whose body has finished, or undefined before empty has run.
Returns
"empty" | "structure_starts" | "structure_references" | "biomes" | "terrain" | "features" | "initialize_light" | "light" | "spawn" | "full" | undefined
Methods
acquire()
acquire():
this
Defined in: ChunkHolder.ts:123
Records that one more task needs this chunk. Pairs with release.
Returns
this
applyStep()
applyStep(
step,body):Promise<TChunk>
Defined in: ChunkHolder.ts:179
Runs a step on this chunk, or joins the run that is already under way.
Java's GenerationChunkHolder.applyStep. The first caller for a status creates the promise and body runs once; every later caller gets that same promise back and body is not called again. The run waits for the parent status's promise first, so two statuses of one chunk are never in flight together.
Parameters
step
The rung to climb, which also carries the window the body may read.
body
ChunkStepBody<TChunk>
What to run, supplied by the caller because the status bodies live outside this package.
Returns
Promise<TChunk>
The chunk at step.targetStatus.
Throws
ChunkStepOutOfOrderError when the holder has not started the parent status.
chunkAt()
chunkAt(
status):TChunk
Defined in: ChunkHolder.ts:158
The chunk, having checked that it has reached the status the reader needs.
The chunk returned is the live one, so it may be at a status above status when another task has already driven it further. That is Java's behavior too: WorldGenRegion.getChunk checks the guarantee and then hands over the live ChunkAccess. It is also why features records its neighbor writes as a patch rather than applying them, which is slice 7.
Parameters
status
"empty" | "structure_starts" | "structure_references" | "biomes" | "terrain" | "features" | "initialize_light" | "light" | "spawn" | "full"
Returns
TChunk
Throws
ChunkNotReadyError when the chunk has not reached that status.
futureFor()
futureFor(
status):Promise<TChunk> |undefined
Defined in: ChunkHolder.ts:144
The promise a status resolved or will resolve to, or undefined when it has not been asked for.
Parameters
status
"empty" | "structure_starts" | "structure_references" | "biomes" | "terrain" | "features" | "initialize_light" | "light" | "spawn" | "full"
Returns
Promise<TChunk> | undefined
hasReached()
hasReached(
status):boolean
Defined in: ChunkHolder.ts:118
Whether the chunk's body for status has finished.
Parameters
status
"empty" | "structure_starts" | "structure_references" | "biomes" | "terrain" | "features" | "initialize_light" | "light" | "spawn" | "full"
Returns
boolean
release()
release():
number
Defined in: ChunkHolder.ts:135
Records that one task no longer needs this chunk.
Returns
number
The remaining count. At zero the holder is finished with and its map drops it.
Throws
RangeError when the holder is already unreferenced, which means a task released twice and some other task's holder is about to be dropped out from under it.