@codexo/exojs-tilemap 0.15.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -26
- package/dist/esm/ChunkSource.d.ts +33 -0
- package/dist/esm/ChunkSource.d.ts.map +1 -0
- package/dist/esm/ChunkStreamer.d.ts +98 -0
- package/dist/esm/ChunkStreamer.d.ts.map +1 -0
- package/dist/esm/ChunkStreamer.js +201 -0
- package/dist/esm/ChunkStreamer.js.map +1 -0
- package/dist/esm/ImageLayer.d.ts +11 -3
- package/dist/esm/ImageLayer.d.ts.map +1 -0
- package/dist/esm/ImageLayer.js +71 -64
- package/dist/esm/ImageLayer.js.map +1 -1
- package/dist/esm/ImageLayerNode.d.ts +89 -0
- package/dist/esm/ImageLayerNode.d.ts.map +1 -0
- package/dist/esm/ImageLayerNode.js +205 -0
- package/dist/esm/ImageLayerNode.js.map +1 -0
- package/dist/esm/MapObject.d.ts +70 -0
- package/dist/esm/MapObject.d.ts.map +1 -0
- package/dist/esm/MapObject.js +34 -0
- package/dist/esm/MapObject.js.map +1 -0
- package/dist/esm/MapObjectSpawner.d.ts +133 -0
- package/dist/esm/MapObjectSpawner.d.ts.map +1 -0
- package/dist/esm/MapObjectSpawner.js +147 -0
- package/dist/esm/MapObjectSpawner.js.map +1 -0
- package/dist/esm/MapSpawnSession.d.ts +53 -0
- package/dist/esm/MapSpawnSession.d.ts.map +1 -0
- package/dist/esm/MapSpawnSession.js +88 -0
- package/dist/esm/MapSpawnSession.js.map +1 -0
- package/dist/esm/MapWorld.d.ts +134 -0
- package/dist/esm/MapWorld.d.ts.map +1 -0
- package/dist/esm/MapWorld.js +150 -0
- package/dist/esm/MapWorld.js.map +1 -0
- package/dist/esm/MapWorldRuntime.d.ts +182 -0
- package/dist/esm/MapWorldRuntime.d.ts.map +1 -0
- package/dist/esm/MapWorldRuntime.js +261 -0
- package/dist/esm/MapWorldRuntime.js.map +1 -0
- package/dist/esm/ObjectLayer.d.ts +93 -7
- package/dist/esm/ObjectLayer.d.ts.map +1 -0
- package/dist/esm/ObjectLayer.js +184 -167
- package/dist/esm/ObjectLayer.js.map +1 -1
- package/dist/esm/SampledChunkSource.d.ts +43 -0
- package/dist/esm/SampledChunkSource.d.ts.map +1 -0
- package/dist/esm/SampledChunkSource.js +48 -0
- package/dist/esm/SampledChunkSource.js.map +1 -0
- package/dist/esm/TileAnimator.d.ts +12 -2
- package/dist/esm/TileAnimator.d.ts.map +1 -0
- package/dist/esm/TileAnimator.js +154 -165
- package/dist/esm/TileAnimator.js.map +1 -1
- package/dist/esm/TileChunk.d.ts +30 -5
- package/dist/esm/TileChunk.d.ts.map +1 -0
- package/dist/esm/TileChunk.js +190 -188
- package/dist/esm/TileChunk.js.map +1 -1
- package/dist/esm/TileChunkNode.d.ts +18 -3
- package/dist/esm/TileChunkNode.d.ts.map +1 -0
- package/dist/esm/TileChunkNode.js +104 -85
- package/dist/esm/TileChunkNode.js.map +1 -1
- package/dist/esm/TileLayer.d.ts +104 -24
- package/dist/esm/TileLayer.d.ts.map +1 -0
- package/dist/esm/TileLayer.js +511 -469
- package/dist/esm/TileLayer.js.map +1 -1
- package/dist/esm/TileLayerNode.d.ts +52 -11
- package/dist/esm/TileLayerNode.d.ts.map +1 -0
- package/dist/esm/TileLayerNode.js +224 -166
- package/dist/esm/TileLayerNode.js.map +1 -1
- package/dist/esm/TileMap.d.ts +96 -31
- package/dist/esm/TileMap.d.ts.map +1 -0
- package/dist/esm/TileMap.js +401 -357
- package/dist/esm/TileMap.js.map +1 -1
- package/dist/esm/TileMapBand.d.ts +42 -29
- package/dist/esm/TileMapBand.d.ts.map +1 -0
- package/dist/esm/TileMapBand.js +151 -158
- package/dist/esm/TileMapBand.js.map +1 -1
- package/dist/esm/TileMapNode.d.ts +34 -18
- package/dist/esm/TileMapNode.d.ts.map +1 -0
- package/dist/esm/TileMapNode.js +122 -109
- package/dist/esm/TileMapNode.js.map +1 -1
- package/dist/esm/TileMapView.d.ts +108 -47
- package/dist/esm/TileMapView.d.ts.map +1 -0
- package/dist/esm/TileMapView.js +385 -338
- package/dist/esm/TileMapView.js.map +1 -1
- package/dist/esm/TileSet.d.ts +15 -6
- package/dist/esm/TileSet.d.ts.map +1 -0
- package/dist/esm/TileSet.js +161 -181
- package/dist/esm/TileSet.js.map +1 -1
- package/dist/esm/WangSet.d.ts +5 -4
- package/dist/esm/WangSet.d.ts.map +1 -0
- package/dist/esm/WangSet.js +70 -78
- package/dist/esm/WangSet.js.map +1 -1
- package/dist/esm/WorkerSampledChunkSource.d.ts +95 -0
- package/dist/esm/WorkerSampledChunkSource.d.ts.map +1 -0
- package/dist/esm/WorkerSampledChunkSource.js +117 -0
- package/dist/esm/WorkerSampledChunkSource.js.map +1 -0
- package/dist/esm/autoTile.d.ts +10 -5
- package/dist/esm/autoTile.d.ts.map +1 -0
- package/dist/esm/autoTile.js +164 -205
- package/dist/esm/autoTile.js.map +1 -1
- package/dist/esm/chunkGeometry.d.ts +8 -7
- package/dist/esm/chunkGeometry.d.ts.map +1 -0
- package/dist/esm/chunkGeometry.js +83 -94
- package/dist/esm/chunkGeometry.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +26 -15
- package/dist/esm/nodeBounds.d.ts +20 -0
- package/dist/esm/nodeBounds.d.ts.map +1 -0
- package/dist/esm/nodeBounds.js +40 -0
- package/dist/esm/nodeBounds.js.map +1 -0
- package/dist/esm/pixelSnap.d.ts +4 -3
- package/dist/esm/pixelSnap.d.ts.map +1 -0
- package/dist/esm/pixelSnap.js +18 -16
- package/dist/esm/pixelSnap.js.map +1 -1
- package/dist/esm/public.d.ts +23 -3
- package/dist/esm/public.d.ts.map +1 -0
- package/dist/esm/tileCollision.d.ts +190 -0
- package/dist/esm/tileCollision.d.ts.map +1 -0
- package/dist/esm/tileCollision.js +367 -0
- package/dist/esm/tileCollision.js.map +1 -0
- package/dist/esm/tileWord.d.ts +12 -0
- package/dist/esm/tileWord.d.ts.map +1 -0
- package/dist/esm/tileWord.js +16 -0
- package/dist/esm/tileWord.js.map +1 -0
- package/dist/esm/tilemapExtension.d.ts +4 -3
- package/dist/esm/tilemapExtension.d.ts.map +1 -0
- package/dist/esm/tilemapExtension.js +47 -47
- package/dist/esm/tilemapExtension.js.map +1 -1
- package/dist/esm/tilemapSerializers.d.ts +5 -4
- package/dist/esm/tilemapSerializers.d.ts.map +1 -0
- package/dist/esm/tilemapSerializers.js +48 -41
- package/dist/esm/tilemapSerializers.js.map +1 -1
- package/dist/esm/types.d.ts +34 -18
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +111 -120
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +50 -2
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts.map +1 -0
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +366 -332
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -1
- package/dist/esm/webgl2/shaders/tile-chunk.frag.js +6 -0
- package/dist/esm/webgl2/shaders/tile-chunk.frag.js.map +1 -0
- package/dist/esm/webgl2/shaders/tile-chunk.vert.js +6 -0
- package/dist/esm/webgl2/shaders/tile-chunk.vert.js.map +1 -0
- package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +70 -4
- package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts.map +1 -0
- package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +496 -383
- package/dist/esm/webgpu/WebGpuTileChunkRenderer.js.map +1 -1
- package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js +6 -0
- package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js.map +1 -0
- package/package.json +8 -15
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/register.d.ts +0 -1
- package/dist/esm/register.js +0 -25
- package/dist/esm/register.js.map +0 -1
package/dist/esm/TileChunk.js
CHANGED
|
@@ -1,192 +1,194 @@
|
|
|
1
|
-
import { validateInteger } from
|
|
1
|
+
import { validateInteger } from "./types.js";
|
|
2
2
|
|
|
3
|
+
//#region src/TileChunk.ts
|
|
3
4
|
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
5
|
+
* A compact, fixed-size chunk of tile data within a layer.
|
|
6
|
+
*
|
|
7
|
+
* Storage is a single {@link Uint32Array} of length `width * height`,
|
|
8
|
+
* laid out row-major. Each cell is a packed tile word (0 = empty).
|
|
9
|
+
* Chunk coordinates are signed to support future infinite maps.
|
|
10
|
+
*
|
|
11
|
+
* The backing array is **private** - external code cannot mutate storage
|
|
12
|
+
* directly. All mutation must flow through {@link TileLayer} public APIs,
|
|
13
|
+
* which call the package-internal `_setRawAt` method.
|
|
14
|
+
*
|
|
15
|
+
* The chunk tracks a revision counter that increments on every mutation
|
|
16
|
+
* so the future renderer can detect which chunks need GPU rebuilds.
|
|
17
|
+
*
|
|
18
|
+
* @advanced
|
|
19
|
+
*/
|
|
20
|
+
var TileChunk = class {
|
|
21
|
+
/** Signed chunk X coordinate. */
|
|
22
|
+
cx;
|
|
23
|
+
/** Signed chunk Y coordinate. */
|
|
24
|
+
cy;
|
|
25
|
+
/** Width of this chunk in tiles. */
|
|
26
|
+
width;
|
|
27
|
+
/** Height of this chunk in tiles. */
|
|
28
|
+
height;
|
|
29
|
+
/** Packed tile storage (row-major). Private - never exposed directly. */
|
|
30
|
+
_tiles;
|
|
31
|
+
/** Whether every cell in this chunk is empty (0). Lazy-computed. */
|
|
32
|
+
_empty = null;
|
|
33
|
+
/** Monotonic revision counter - incremented on every mutation. */
|
|
34
|
+
_revision = 0;
|
|
35
|
+
/**
|
|
36
|
+
* Render-node-owned callbacks notified whenever `_revision` advances.
|
|
37
|
+
* `TileChunkNode.pages` caches geometry against `revision`, but that cache
|
|
38
|
+
* is only consulted from `render()` - a call the engine skips entirely for
|
|
39
|
+
* a content-clean subtree under a `RetainedContainer`. Without
|
|
40
|
+
* this push, an in-place tile edit after capture would replay stale cached
|
|
41
|
+
* geometry forever. Package-internal; not part of {@link ReadonlyTileChunk}.
|
|
42
|
+
*/
|
|
43
|
+
_dirtyListeners = null;
|
|
44
|
+
/**
|
|
45
|
+
* @param cx Signed chunk X coordinate (must be finite safe integer).
|
|
46
|
+
* @param cy Signed chunk Y coordinate (must be finite safe integer).
|
|
47
|
+
* @param width Chunk width in tiles (positive safe integer).
|
|
48
|
+
* @param height Chunk height in tiles (positive safe integer).
|
|
49
|
+
* @param source Optional source data to copy (must match length).
|
|
50
|
+
*/
|
|
51
|
+
constructor(cx, cy, width, height, source) {
|
|
52
|
+
if (!Number.isFinite(cx) || !Number.isInteger(cx) || !Number.isSafeInteger(cx)) throw new Error(`TileChunk cx must be a finite safe integer (got ${cx}).`);
|
|
53
|
+
if (!Number.isFinite(cy) || !Number.isInteger(cy) || !Number.isSafeInteger(cy)) throw new Error(`TileChunk cy must be a finite safe integer (got ${cy}).`);
|
|
54
|
+
if (width <= 0 || height <= 0) throw new Error(`TileChunk dimensions must be positive (got ${width}x${height}).`);
|
|
55
|
+
if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height)) throw new Error(`TileChunk dimensions must be safe integers (got ${width}x${height}).`);
|
|
56
|
+
const size = width * height;
|
|
57
|
+
if (!Number.isSafeInteger(size)) throw new Error(`TileChunk size overflow: ${width} * ${height} is not safe.`);
|
|
58
|
+
if (size > 4294967295) throw new Error(`TileChunk size ${size} exceeds TypedArray maximum length.`);
|
|
59
|
+
this.cx = cx;
|
|
60
|
+
this.cy = cy;
|
|
61
|
+
this.width = width;
|
|
62
|
+
this.height = height;
|
|
63
|
+
if (source) {
|
|
64
|
+
if (source.length !== size) throw new Error(`TileChunk source length ${source.length} != ${size}.`);
|
|
65
|
+
this._tiles = new Uint32Array(source);
|
|
66
|
+
} else this._tiles = new Uint32Array(size);
|
|
67
|
+
}
|
|
68
|
+
/** Row-major index for cell (lx, ly) within this chunk. */
|
|
69
|
+
_index(lx, ly) {
|
|
70
|
+
return ly * this.width + lx;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate local-in-chunk coordinates before access.
|
|
74
|
+
* @throws If lx or ly is not a finite integer or out of [0, dimension).
|
|
75
|
+
*/
|
|
76
|
+
_validateLocalCoord(lx, ly) {
|
|
77
|
+
validateInteger(lx, "lx");
|
|
78
|
+
validateInteger(ly, "ly");
|
|
79
|
+
if (lx < 0 || lx >= this.width) throw new Error(`lx ${lx} out of chunk bounds [0, ${this.width - 1}].`);
|
|
80
|
+
if (ly < 0 || ly >= this.height) throw new Error(`ly ${ly} out of chunk bounds [0, ${this.height - 1}].`);
|
|
81
|
+
}
|
|
82
|
+
/** @inheritdoc */
|
|
83
|
+
getRawAt(lx, ly) {
|
|
84
|
+
this._validateLocalCoord(lx, ly);
|
|
85
|
+
return this._tiles[this._index(lx, ly)];
|
|
86
|
+
}
|
|
87
|
+
/** @inheritdoc */
|
|
88
|
+
get empty() {
|
|
89
|
+
if (this._empty === null) this._empty = this._tiles.every((v) => v === 0);
|
|
90
|
+
return this._empty;
|
|
91
|
+
}
|
|
92
|
+
/** @inheritdoc */
|
|
93
|
+
get revision() {
|
|
94
|
+
return this._revision;
|
|
95
|
+
}
|
|
96
|
+
/** @inheritdoc */
|
|
97
|
+
cloneTiles() {
|
|
98
|
+
return new Uint32Array(this._tiles);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Package-internal access to the underlying tile storage.
|
|
102
|
+
* Returns the actual mutable `Uint32Array` - DO NOT USE publicly.
|
|
103
|
+
*
|
|
104
|
+
* Provided for the future tilemap renderer (same package) so it can
|
|
105
|
+
* read chunk data efficiently without a full `cloneTiles()` copy per frame.
|
|
106
|
+
*
|
|
107
|
+
* External consumers and other packages MUST NOT call this.
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
_getRawStorage() {
|
|
111
|
+
return this._tiles;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Validate a packed tile value before storing.
|
|
115
|
+
* Accepts any finite integer - `Uint32Array` stores via unsigned 32-bit
|
|
116
|
+
* truncation (`ToUint32`). Negative values produced by JavaScript's
|
|
117
|
+
* signed bitwise ops (e.g. when the transform bits set bit 31) are valid.
|
|
118
|
+
* @throws If the value is NaN, Infinity, or non-integer.
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
_validatePacked(packed) {
|
|
122
|
+
if (typeof packed !== "number" || !Number.isFinite(packed) || !Number.isInteger(packed)) throw new Error(`Packed tile must be a finite integer (got ${packed}).`);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Write a packed tile word at local-in-chunk coordinates.
|
|
126
|
+
* Returns true if the stored value actually changed.
|
|
127
|
+
*
|
|
128
|
+
* Package-internal: only {@link TileLayer} may call this.
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
_setRawAt(lx, ly, packed) {
|
|
132
|
+
this._validateLocalCoord(lx, ly);
|
|
133
|
+
this._validatePacked(packed);
|
|
134
|
+
const i = this._index(lx, ly);
|
|
135
|
+
if (this._tiles[i] === packed) return false;
|
|
136
|
+
this._tiles[i] = packed;
|
|
137
|
+
this._revision++;
|
|
138
|
+
this._empty = null;
|
|
139
|
+
this._notifyDirty();
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Mark the chunk as needing a GPU rebuild.
|
|
144
|
+
* Invalidates the empty cache and increments revision.
|
|
145
|
+
*
|
|
146
|
+
* Package-internal: for future renderer use only.
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
_markDirty() {
|
|
150
|
+
this._empty = null;
|
|
151
|
+
this._revision++;
|
|
152
|
+
this._notifyDirty();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Clear every cell in this chunk. Does not re-allocate storage.
|
|
156
|
+
* Increments revision if any cell was non-zero.
|
|
157
|
+
*
|
|
158
|
+
* Package-internal: only {@link TileLayer} may call this.
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
_clear() {
|
|
162
|
+
if (!this._tiles.some((v) => v !== 0)) return;
|
|
163
|
+
this._tiles.fill(0);
|
|
164
|
+
this._revision++;
|
|
165
|
+
this._empty = true;
|
|
166
|
+
this._notifyDirty();
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Register a callback invoked synchronously whenever this chunk's revision
|
|
170
|
+
* advances. Multiple listeners are supported (a chunk may back more than one
|
|
171
|
+
* `TileChunkNode` - e.g. two `TileLayerNode`s over the same `TileLayer`).
|
|
172
|
+
* Package-internal: called by `TileChunkNode` to push mutations onto the
|
|
173
|
+
* scene-node content-revision chain (see the `_dirtyListeners` field).
|
|
174
|
+
* @internal
|
|
175
|
+
*/
|
|
176
|
+
_addDirtyListener(listener) {
|
|
177
|
+
(this._dirtyListeners ??= /* @__PURE__ */ new Set()).add(listener);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Unregister a listener added via {@link _addDirtyListener} (node destroy).
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
_removeDirtyListener(listener) {
|
|
184
|
+
this._dirtyListeners?.delete(listener);
|
|
185
|
+
}
|
|
186
|
+
_notifyDirty() {
|
|
187
|
+
if (this._dirtyListeners === null) return;
|
|
188
|
+
for (const listener of this._dirtyListeners) listener();
|
|
189
|
+
}
|
|
190
|
+
};
|
|
190
191
|
|
|
192
|
+
//#endregion
|
|
191
193
|
export { TileChunk };
|
|
192
|
-
//# sourceMappingURL=TileChunk.js.map
|
|
194
|
+
//# sourceMappingURL=TileChunk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TileChunk.js","sources":["../../../src/TileChunk.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TileChunk.js","names":[],"sources":["../../src/TileChunk.ts"],"sourcesContent":["import type { PackedTile } from './types';\nimport { validateInteger } from './types';\n\n/**\n * Public readonly view of a tile chunk.\n *\n * Provides read-only inspection access for iteration, queries, and the\n * future renderer. The underlying storage is never exposed directly.\n *\n * @advanced\n */\nexport interface ReadonlyTileChunk {\n /** Signed chunk X coordinate. */\n readonly cx: number;\n /** Signed chunk Y coordinate. */\n readonly cy: number;\n /** Width of this chunk in tiles. */\n readonly width: number;\n /** Height of this chunk in tiles. */\n readonly height: number;\n /** Whether every cell is empty (all-zero). */\n readonly empty: boolean;\n /**\n * Monotonic revision counter. Increments on every cell mutation\n * within this chunk. No-ops (writing same value) do NOT increment.\n */\n readonly revision: number;\n\n /**\n * Read the raw packed tile word at local-in-chunk coordinates.\n * Returns 0 for empty.\n * @throws If coordinates are invalid.\n */\n getRawAt(lx: number, ly: number): PackedTile;\n\n /**\n * Create a defensive copy of the tile data. The caller owns the copy;\n * mutation of the returned array cannot affect the chunk.\n */\n cloneTiles(): Uint32Array;\n}\n\n/**\n * A compact, fixed-size chunk of tile data within a layer.\n *\n * Storage is a single {@link Uint32Array} of length `width * height`,\n * laid out row-major. Each cell is a packed tile word (0 = empty).\n * Chunk coordinates are signed to support future infinite maps.\n *\n * The backing array is **private** - external code cannot mutate storage\n * directly. All mutation must flow through {@link TileLayer} public APIs,\n * which call the package-internal `_setRawAt` method.\n *\n * The chunk tracks a revision counter that increments on every mutation\n * so the future renderer can detect which chunks need GPU rebuilds.\n *\n * @advanced\n */\nexport class TileChunk implements ReadonlyTileChunk {\n /** Signed chunk X coordinate. */\n public readonly cx: number;\n /** Signed chunk Y coordinate. */\n public readonly cy: number;\n\n /** Width of this chunk in tiles. */\n public readonly width: number;\n /** Height of this chunk in tiles. */\n public readonly height: number;\n\n /** Packed tile storage (row-major). Private - never exposed directly. */\n private readonly _tiles: Uint32Array;\n\n /** Whether every cell in this chunk is empty (0). Lazy-computed. */\n private _empty: boolean | null = null;\n\n /** Monotonic revision counter - incremented on every mutation. */\n private _revision = 0;\n\n /**\n * Render-node-owned callbacks notified whenever `_revision` advances.\n * `TileChunkNode.pages` caches geometry against `revision`, but that cache\n * is only consulted from `render()` - a call the engine skips entirely for\n * a content-clean subtree under a `RetainedContainer`. Without\n * this push, an in-place tile edit after capture would replay stale cached\n * geometry forever. Package-internal; not part of {@link ReadonlyTileChunk}.\n */\n private _dirtyListeners: Set<() => void> | null = null;\n\n /**\n * @param cx Signed chunk X coordinate (must be finite safe integer).\n * @param cy Signed chunk Y coordinate (must be finite safe integer).\n * @param width Chunk width in tiles (positive safe integer).\n * @param height Chunk height in tiles (positive safe integer).\n * @param source Optional source data to copy (must match length).\n */\n public constructor(cx: number, cy: number, width: number, height: number, source?: Uint32Array) {\n // Validate chunk coordinates as finite safe integers (negative OK).\n if (!Number.isFinite(cx) || !Number.isInteger(cx) || !Number.isSafeInteger(cx)) {\n throw new Error(`TileChunk cx must be a finite safe integer (got ${cx}).`);\n }\n if (!Number.isFinite(cy) || !Number.isInteger(cy) || !Number.isSafeInteger(cy)) {\n throw new Error(`TileChunk cy must be a finite safe integer (got ${cy}).`);\n }\n\n if (width <= 0 || height <= 0) {\n throw new Error(`TileChunk dimensions must be positive (got ${width}x${height}).`);\n }\n if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height)) {\n throw new Error(`TileChunk dimensions must be safe integers (got ${width}x${height}).`);\n }\n\n const size = width * height;\n if (!Number.isSafeInteger(size)) {\n throw new Error(`TileChunk size overflow: ${width} * ${height} is not safe.`);\n }\n\n // Guard against TypedArray length limits.\n if (size > 0xffffffff) {\n throw new Error(`TileChunk size ${size} exceeds TypedArray maximum length.`);\n }\n\n this.cx = cx;\n this.cy = cy;\n this.width = width;\n this.height = height;\n\n if (source) {\n if (source.length !== size) {\n throw new Error(`TileChunk source length ${source.length} != ${size}.`);\n }\n // Defensive copy - caller mutation of source array will not affect storage.\n this._tiles = new Uint32Array(source);\n } else {\n this._tiles = new Uint32Array(size);\n }\n }\n\n /** Row-major index for cell (lx, ly) within this chunk. */\n private _index(lx: number, ly: number): number {\n return ly * this.width + lx;\n }\n\n /**\n * Validate local-in-chunk coordinates before access.\n * @throws If lx or ly is not a finite integer or out of [0, dimension).\n */\n private _validateLocalCoord(lx: number, ly: number): void {\n validateInteger(lx, 'lx');\n validateInteger(ly, 'ly');\n if (lx < 0 || lx >= this.width) {\n throw new Error(`lx ${lx} out of chunk bounds [0, ${this.width - 1}].`);\n }\n if (ly < 0 || ly >= this.height) {\n throw new Error(`ly ${ly} out of chunk bounds [0, ${this.height - 1}].`);\n }\n }\n\n // ── Readonly public API (ReadonlyTileChunk) ──────────────────────────\n\n /** @inheritdoc */\n public getRawAt(lx: number, ly: number): PackedTile {\n this._validateLocalCoord(lx, ly);\n return this._tiles[this._index(lx, ly)]!;\n }\n\n /** @inheritdoc */\n public get empty(): boolean {\n if (this._empty === null) {\n this._empty = this._tiles.every(v => v === 0);\n }\n return this._empty;\n }\n\n /** @inheritdoc */\n public get revision(): number {\n return this._revision;\n }\n\n /** @inheritdoc */\n public cloneTiles(): Uint32Array {\n return new Uint32Array(this._tiles);\n }\n\n // ── Internal mutation (package-private, NOT public API) ──────────────\n\n /**\n * Package-internal access to the underlying tile storage.\n * Returns the actual mutable `Uint32Array` - DO NOT USE publicly.\n *\n * Provided for the future tilemap renderer (same package) so it can\n * read chunk data efficiently without a full `cloneTiles()` copy per frame.\n *\n * External consumers and other packages MUST NOT call this.\n * @internal\n */\n public _getRawStorage(): Uint32Array {\n return this._tiles;\n }\n\n /**\n * Validate a packed tile value before storing.\n * Accepts any finite integer - `Uint32Array` stores via unsigned 32-bit\n * truncation (`ToUint32`). Negative values produced by JavaScript's\n * signed bitwise ops (e.g. when the transform bits set bit 31) are valid.\n * @throws If the value is NaN, Infinity, or non-integer.\n * @internal\n */\n private _validatePacked(packed: PackedTile): void {\n if (typeof packed !== 'number' || !Number.isFinite(packed) || !Number.isInteger(packed)) {\n throw new Error(`Packed tile must be a finite integer (got ${packed}).`);\n }\n }\n\n /**\n * Write a packed tile word at local-in-chunk coordinates.\n * Returns true if the stored value actually changed.\n *\n * Package-internal: only {@link TileLayer} may call this.\n * @internal\n */\n public _setRawAt(lx: number, ly: number, packed: PackedTile): boolean {\n this._validateLocalCoord(lx, ly);\n this._validatePacked(packed);\n const i = this._index(lx, ly);\n const prev = this._tiles[i];\n if (prev === packed) return false;\n this._tiles[i] = packed;\n this._revision++;\n this._empty = null; // invalidate cache\n this._notifyDirty();\n return true;\n }\n\n /**\n * Mark the chunk as needing a GPU rebuild.\n * Invalidates the empty cache and increments revision.\n *\n * Package-internal: for future renderer use only.\n * @internal\n */\n public _markDirty(): void {\n this._empty = null;\n this._revision++;\n this._notifyDirty();\n }\n\n /**\n * Clear every cell in this chunk. Does not re-allocate storage.\n * Increments revision if any cell was non-zero.\n *\n * Package-internal: only {@link TileLayer} may call this.\n * @internal\n */\n public _clear(): void {\n const hadContent = this._tiles.some(v => v !== 0);\n if (!hadContent) return;\n this._tiles.fill(0);\n this._revision++;\n this._empty = true;\n this._notifyDirty();\n }\n\n /**\n * Register a callback invoked synchronously whenever this chunk's revision\n * advances. Multiple listeners are supported (a chunk may back more than one\n * `TileChunkNode` - e.g. two `TileLayerNode`s over the same `TileLayer`).\n * Package-internal: called by `TileChunkNode` to push mutations onto the\n * scene-node content-revision chain (see the `_dirtyListeners` field).\n * @internal\n */\n public _addDirtyListener(listener: () => void): void {\n (this._dirtyListeners ??= new Set()).add(listener);\n }\n\n /**\n * Unregister a listener added via {@link _addDirtyListener} (node destroy).\n * @internal\n */\n public _removeDirtyListener(listener: () => void): void {\n this._dirtyListeners?.delete(listener);\n }\n\n private _notifyDirty(): void {\n if (this._dirtyListeners === null) return;\n for (const listener of this._dirtyListeners) {\n listener();\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0DA,IAAa,YAAb,MAAoD;;CAElD,AAAgB;;CAEhB,AAAgB;;CAGhB,AAAgB;;CAEhB,AAAgB;;CAGhB,AAAiB;;CAGjB,AAAQ,SAAyB;;CAGjC,AAAQ,YAAY;;;;;;;;;CAUpB,AAAQ,kBAA0C;;;;;;;;CASlD,AAAO,YAAY,IAAY,IAAY,OAAe,QAAgB,QAAsB;EAE9F,IAAI,CAAC,OAAO,SAAS,EAAE,KAAK,CAAC,OAAO,UAAU,EAAE,KAAK,CAAC,OAAO,cAAc,EAAE,GAC3E,MAAM,IAAI,MAAM,mDAAmD,GAAG,GAAG;EAE3E,IAAI,CAAC,OAAO,SAAS,EAAE,KAAK,CAAC,OAAO,UAAU,EAAE,KAAK,CAAC,OAAO,cAAc,EAAE,GAC3E,MAAM,IAAI,MAAM,mDAAmD,GAAG,GAAG;EAG3E,IAAI,SAAS,KAAK,UAAU,GAC1B,MAAM,IAAI,MAAM,8CAA8C,MAAM,GAAG,OAAO,GAAG;EAEnF,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,CAAC,OAAO,cAAc,MAAM,GAC9D,MAAM,IAAI,MAAM,mDAAmD,MAAM,GAAG,OAAO,GAAG;EAGxF,MAAM,OAAO,QAAQ;EACrB,IAAI,CAAC,OAAO,cAAc,IAAI,GAC5B,MAAM,IAAI,MAAM,4BAA4B,MAAM,KAAK,OAAO,cAAc;EAI9E,IAAI,OAAO,YACT,MAAM,IAAI,MAAM,kBAAkB,KAAK,oCAAoC;EAG7E,KAAK,KAAK;EACV,KAAK,KAAK;EACV,KAAK,QAAQ;EACb,KAAK,SAAS;EAEd,IAAI,QAAQ;GACV,IAAI,OAAO,WAAW,MACpB,MAAM,IAAI,MAAM,2BAA2B,OAAO,OAAO,MAAM,KAAK,EAAE;GAGxE,KAAK,SAAS,IAAI,YAAY,MAAM;EACtC,OACE,KAAK,SAAS,IAAI,YAAY,IAAI;CAEtC;;CAGA,AAAQ,OAAO,IAAY,IAAoB;EAC7C,OAAO,KAAK,KAAK,QAAQ;CAC3B;;;;;CAMA,AAAQ,oBAAoB,IAAY,IAAkB;EACxD,gBAAgB,IAAI,IAAI;EACxB,gBAAgB,IAAI,IAAI;EACxB,IAAI,KAAK,KAAK,MAAM,KAAK,OACvB,MAAM,IAAI,MAAM,MAAM,GAAG,2BAA2B,KAAK,QAAQ,EAAE,GAAG;EAExE,IAAI,KAAK,KAAK,MAAM,KAAK,QACvB,MAAM,IAAI,MAAM,MAAM,GAAG,2BAA2B,KAAK,SAAS,EAAE,GAAG;CAE3E;;CAKA,AAAO,SAAS,IAAY,IAAwB;EAClD,KAAK,oBAAoB,IAAI,EAAE;EAC/B,OAAO,KAAK,OAAO,KAAK,OAAO,IAAI,EAAE;CACvC;;CAGA,IAAW,QAAiB;EAC1B,IAAI,KAAK,WAAW,MAClB,KAAK,SAAS,KAAK,OAAO,OAAM,MAAK,MAAM,CAAC;EAE9C,OAAO,KAAK;CACd;;CAGA,IAAW,WAAmB;EAC5B,OAAO,KAAK;CACd;;CAGA,AAAO,aAA0B;EAC/B,OAAO,IAAI,YAAY,KAAK,MAAM;CACpC;;;;;;;;;;;CAcA,AAAO,iBAA8B;EACnC,OAAO,KAAK;CACd;;;;;;;;;CAUA,AAAQ,gBAAgB,QAA0B;EAChD,IAAI,OAAO,WAAW,YAAY,CAAC,OAAO,SAAS,MAAM,KAAK,CAAC,OAAO,UAAU,MAAM,GACpF,MAAM,IAAI,MAAM,6CAA6C,OAAO,GAAG;CAE3E;;;;;;;;CASA,AAAO,UAAU,IAAY,IAAY,QAA6B;EACpE,KAAK,oBAAoB,IAAI,EAAE;EAC/B,KAAK,gBAAgB,MAAM;EAC3B,MAAM,IAAI,KAAK,OAAO,IAAI,EAAE;EAE5B,IADa,KAAK,OAAO,OACZ,QAAQ,OAAO;EAC5B,KAAK,OAAO,KAAK;EACjB,KAAK;EACL,KAAK,SAAS;EACd,KAAK,aAAa;EAClB,OAAO;CACT;;;;;;;;CASA,AAAO,aAAmB;EACxB,KAAK,SAAS;EACd,KAAK;EACL,KAAK,aAAa;CACpB;;;;;;;;CASA,AAAO,SAAe;EAEpB,IAAI,CADe,KAAK,OAAO,MAAK,MAAK,MAAM,CACjC,GAAG;EACjB,KAAK,OAAO,KAAK,CAAC;EAClB,KAAK;EACL,KAAK,SAAS;EACd,KAAK,aAAa;CACpB;;;;;;;;;CAUA,AAAO,kBAAkB,UAA4B;EACnD,CAAC,KAAK,oCAAoB,IAAI,IAAI,EAAC,CAAE,IAAI,QAAQ;CACnD;;;;;CAMA,AAAO,qBAAqB,UAA4B;EACtD,KAAK,iBAAiB,OAAO,QAAQ;CACvC;CAEA,AAAQ,eAAqB;EAC3B,IAAI,KAAK,oBAAoB,MAAM;EACnC,KAAK,MAAM,YAAY,KAAK,iBAC1B,SAAS;CAEb;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReadonlyRectangle } from '@codexo/exojs';
|
|
2
2
|
import { Drawable } from '@codexo/exojs/renderer-sdk';
|
|
3
3
|
import type { ChunkPage } from './chunkGeometry';
|
|
4
4
|
import type { ReadonlyTileChunk } from './TileChunk';
|
|
@@ -15,7 +15,7 @@ import type { TileSet } from './TileSet';
|
|
|
15
15
|
* chunks are culled by their accurate {@link getLocalBounds} before `render`
|
|
16
16
|
* is ever called, so a camera pan rebuilds nothing.
|
|
17
17
|
*
|
|
18
|
-
* The node references
|
|
18
|
+
* The node references - but never owns - the runtime chunk, tilesets, and
|
|
19
19
|
* tileset textures. Destroying it releases only its cached CPU geometry; the
|
|
20
20
|
* `TileMap`/`TileLayer` data and Loader-owned textures are untouched.
|
|
21
21
|
*
|
|
@@ -31,6 +31,15 @@ export declare class TileChunkNode extends Drawable {
|
|
|
31
31
|
private readonly _pixelHeight;
|
|
32
32
|
private _pages;
|
|
33
33
|
private _builtRevision;
|
|
34
|
+
/**
|
|
35
|
+
* Bound once so `TileChunk._addDirtyListener`/`_removeDirtyListener` add and
|
|
36
|
+
* remove the SAME function reference. Pushes the chunk's revision bump onto
|
|
37
|
+
* this node's own content revision (see `TileChunk._dirtyListeners`) so a
|
|
38
|
+
* `RetainedContainer` ancestor - which skips walking a content-clean
|
|
39
|
+
* subtree entirely - observes the mutation and re-collects instead of
|
|
40
|
+
* replaying stale cached geometry.
|
|
41
|
+
*/
|
|
42
|
+
private readonly _onChunkDirty;
|
|
34
43
|
/**
|
|
35
44
|
* @param chunk The readonly chunk this node renders.
|
|
36
45
|
* @param tilesets The owning layer's tileset array.
|
|
@@ -54,6 +63,12 @@ export declare class TileChunkNode extends Drawable {
|
|
|
54
63
|
get pages(): readonly ChunkPage[];
|
|
55
64
|
/** `true` when the chunk has no drawable tiles (no geometry, no draw calls). */
|
|
56
65
|
get isEmpty(): boolean;
|
|
57
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Recomputed lazily on read, so it writes `_localBounds` directly rather than
|
|
68
|
+
* going through `_setLocalBounds`: an invalidating write inside a getter
|
|
69
|
+
* would re-dirty the node on every read.
|
|
70
|
+
*/
|
|
71
|
+
getLocalBounds(): ReadonlyRectangle;
|
|
58
72
|
destroy(): void;
|
|
59
73
|
}
|
|
74
|
+
//# sourceMappingURL=TileChunkNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TileChunkNode.d.ts","sourceRoot":"","sources":["../../src/TileChunkNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,cAAc,CAAM;IAE5B;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF;;;;;;;;;;OAUG;gBAED,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM;IAoB1B,sDAAsD;IACtD,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED;;;;OAIG;IACH,IAAW,KAAK,IAAI,SAAS,SAAS,EAAE,CAOvC;IAED,gFAAgF;IAChF,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;;;OAIG;IACa,cAAc,IAAI,iBAAiB;IAInC,OAAO,IAAI,IAAI;CAUhC"}
|