@codexo/exojs-tilemap 0.15.3 → 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.
Files changed (151) hide show
  1. package/README.md +33 -26
  2. package/dist/esm/ChunkSource.d.ts +33 -0
  3. package/dist/esm/ChunkSource.d.ts.map +1 -0
  4. package/dist/esm/ChunkStreamer.d.ts +98 -0
  5. package/dist/esm/ChunkStreamer.d.ts.map +1 -0
  6. package/dist/esm/ChunkStreamer.js +201 -0
  7. package/dist/esm/ChunkStreamer.js.map +1 -0
  8. package/dist/esm/ImageLayer.d.ts +11 -3
  9. package/dist/esm/ImageLayer.d.ts.map +1 -0
  10. package/dist/esm/ImageLayer.js +71 -64
  11. package/dist/esm/ImageLayer.js.map +1 -1
  12. package/dist/esm/ImageLayerNode.d.ts +89 -0
  13. package/dist/esm/ImageLayerNode.d.ts.map +1 -0
  14. package/dist/esm/ImageLayerNode.js +205 -0
  15. package/dist/esm/ImageLayerNode.js.map +1 -0
  16. package/dist/esm/MapObject.d.ts +70 -0
  17. package/dist/esm/MapObject.d.ts.map +1 -0
  18. package/dist/esm/MapObject.js +34 -0
  19. package/dist/esm/MapObject.js.map +1 -0
  20. package/dist/esm/MapObjectSpawner.d.ts +133 -0
  21. package/dist/esm/MapObjectSpawner.d.ts.map +1 -0
  22. package/dist/esm/MapObjectSpawner.js +147 -0
  23. package/dist/esm/MapObjectSpawner.js.map +1 -0
  24. package/dist/esm/MapSpawnSession.d.ts +53 -0
  25. package/dist/esm/MapSpawnSession.d.ts.map +1 -0
  26. package/dist/esm/MapSpawnSession.js +88 -0
  27. package/dist/esm/MapSpawnSession.js.map +1 -0
  28. package/dist/esm/MapWorld.d.ts +134 -0
  29. package/dist/esm/MapWorld.d.ts.map +1 -0
  30. package/dist/esm/MapWorld.js +150 -0
  31. package/dist/esm/MapWorld.js.map +1 -0
  32. package/dist/esm/MapWorldRuntime.d.ts +182 -0
  33. package/dist/esm/MapWorldRuntime.d.ts.map +1 -0
  34. package/dist/esm/MapWorldRuntime.js +261 -0
  35. package/dist/esm/MapWorldRuntime.js.map +1 -0
  36. package/dist/esm/ObjectLayer.d.ts +93 -7
  37. package/dist/esm/ObjectLayer.d.ts.map +1 -0
  38. package/dist/esm/ObjectLayer.js +184 -167
  39. package/dist/esm/ObjectLayer.js.map +1 -1
  40. package/dist/esm/SampledChunkSource.d.ts +43 -0
  41. package/dist/esm/SampledChunkSource.d.ts.map +1 -0
  42. package/dist/esm/SampledChunkSource.js +48 -0
  43. package/dist/esm/SampledChunkSource.js.map +1 -0
  44. package/dist/esm/TileAnimator.d.ts +12 -2
  45. package/dist/esm/TileAnimator.d.ts.map +1 -0
  46. package/dist/esm/TileAnimator.js +154 -165
  47. package/dist/esm/TileAnimator.js.map +1 -1
  48. package/dist/esm/TileChunk.d.ts +30 -5
  49. package/dist/esm/TileChunk.d.ts.map +1 -0
  50. package/dist/esm/TileChunk.js +190 -188
  51. package/dist/esm/TileChunk.js.map +1 -1
  52. package/dist/esm/TileChunkNode.d.ts +18 -3
  53. package/dist/esm/TileChunkNode.d.ts.map +1 -0
  54. package/dist/esm/TileChunkNode.js +104 -85
  55. package/dist/esm/TileChunkNode.js.map +1 -1
  56. package/dist/esm/TileLayer.d.ts +104 -24
  57. package/dist/esm/TileLayer.d.ts.map +1 -0
  58. package/dist/esm/TileLayer.js +511 -469
  59. package/dist/esm/TileLayer.js.map +1 -1
  60. package/dist/esm/TileLayerNode.d.ts +52 -11
  61. package/dist/esm/TileLayerNode.d.ts.map +1 -0
  62. package/dist/esm/TileLayerNode.js +224 -166
  63. package/dist/esm/TileLayerNode.js.map +1 -1
  64. package/dist/esm/TileMap.d.ts +96 -31
  65. package/dist/esm/TileMap.d.ts.map +1 -0
  66. package/dist/esm/TileMap.js +401 -357
  67. package/dist/esm/TileMap.js.map +1 -1
  68. package/dist/esm/TileMapBand.d.ts +42 -29
  69. package/dist/esm/TileMapBand.d.ts.map +1 -0
  70. package/dist/esm/TileMapBand.js +151 -158
  71. package/dist/esm/TileMapBand.js.map +1 -1
  72. package/dist/esm/TileMapNode.d.ts +34 -18
  73. package/dist/esm/TileMapNode.d.ts.map +1 -0
  74. package/dist/esm/TileMapNode.js +122 -109
  75. package/dist/esm/TileMapNode.js.map +1 -1
  76. package/dist/esm/TileMapView.d.ts +108 -47
  77. package/dist/esm/TileMapView.d.ts.map +1 -0
  78. package/dist/esm/TileMapView.js +385 -338
  79. package/dist/esm/TileMapView.js.map +1 -1
  80. package/dist/esm/TileSet.d.ts +15 -6
  81. package/dist/esm/TileSet.d.ts.map +1 -0
  82. package/dist/esm/TileSet.js +161 -181
  83. package/dist/esm/TileSet.js.map +1 -1
  84. package/dist/esm/WangSet.d.ts +5 -4
  85. package/dist/esm/WangSet.d.ts.map +1 -0
  86. package/dist/esm/WangSet.js +70 -78
  87. package/dist/esm/WangSet.js.map +1 -1
  88. package/dist/esm/WorkerSampledChunkSource.d.ts +95 -0
  89. package/dist/esm/WorkerSampledChunkSource.d.ts.map +1 -0
  90. package/dist/esm/WorkerSampledChunkSource.js +117 -0
  91. package/dist/esm/WorkerSampledChunkSource.js.map +1 -0
  92. package/dist/esm/autoTile.d.ts +10 -5
  93. package/dist/esm/autoTile.d.ts.map +1 -0
  94. package/dist/esm/autoTile.js +164 -205
  95. package/dist/esm/autoTile.js.map +1 -1
  96. package/dist/esm/chunkGeometry.d.ts +8 -7
  97. package/dist/esm/chunkGeometry.d.ts.map +1 -0
  98. package/dist/esm/chunkGeometry.js +83 -94
  99. package/dist/esm/chunkGeometry.js.map +1 -1
  100. package/dist/esm/index.d.ts +1 -0
  101. package/dist/esm/index.d.ts.map +1 -0
  102. package/dist/esm/index.js +26 -15
  103. package/dist/esm/nodeBounds.d.ts +20 -0
  104. package/dist/esm/nodeBounds.d.ts.map +1 -0
  105. package/dist/esm/nodeBounds.js +40 -0
  106. package/dist/esm/nodeBounds.js.map +1 -0
  107. package/dist/esm/pixelSnap.d.ts +4 -3
  108. package/dist/esm/pixelSnap.d.ts.map +1 -0
  109. package/dist/esm/pixelSnap.js +18 -16
  110. package/dist/esm/pixelSnap.js.map +1 -1
  111. package/dist/esm/public.d.ts +23 -3
  112. package/dist/esm/public.d.ts.map +1 -0
  113. package/dist/esm/tileCollision.d.ts +190 -0
  114. package/dist/esm/tileCollision.d.ts.map +1 -0
  115. package/dist/esm/tileCollision.js +367 -0
  116. package/dist/esm/tileCollision.js.map +1 -0
  117. package/dist/esm/tileWord.d.ts +12 -0
  118. package/dist/esm/tileWord.d.ts.map +1 -0
  119. package/dist/esm/tileWord.js +16 -0
  120. package/dist/esm/tileWord.js.map +1 -0
  121. package/dist/esm/tilemapExtension.d.ts +4 -3
  122. package/dist/esm/tilemapExtension.d.ts.map +1 -0
  123. package/dist/esm/tilemapExtension.js +47 -47
  124. package/dist/esm/tilemapExtension.js.map +1 -1
  125. package/dist/esm/tilemapSerializers.d.ts +5 -4
  126. package/dist/esm/tilemapSerializers.d.ts.map +1 -0
  127. package/dist/esm/tilemapSerializers.js +48 -41
  128. package/dist/esm/tilemapSerializers.js.map +1 -1
  129. package/dist/esm/types.d.ts +34 -18
  130. package/dist/esm/types.d.ts.map +1 -0
  131. package/dist/esm/types.js +111 -120
  132. package/dist/esm/types.js.map +1 -1
  133. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +50 -2
  134. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts.map +1 -0
  135. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +366 -332
  136. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -1
  137. package/dist/esm/webgl2/shaders/tile-chunk.frag.js +6 -0
  138. package/dist/esm/webgl2/shaders/tile-chunk.frag.js.map +1 -0
  139. package/dist/esm/webgl2/shaders/tile-chunk.vert.js +6 -0
  140. package/dist/esm/webgl2/shaders/tile-chunk.vert.js.map +1 -0
  141. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +70 -4
  142. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts.map +1 -0
  143. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +496 -383
  144. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js.map +1 -1
  145. package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js +6 -0
  146. package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js.map +1 -0
  147. package/package.json +8 -15
  148. package/dist/esm/index.js.map +0 -1
  149. package/dist/esm/register.d.ts +0 -1
  150. package/dist/esm/register.js +0 -25
  151. package/dist/esm/register.js.map +0 -1
@@ -1,6 +1,7 @@
1
- import type { Rectangle } from '@codexo/exojs';
1
+ import type { ReadonlyRectangle } from '@codexo/exojs';
2
2
  import { Container } from '@codexo/exojs';
3
- import type { PixelSnapMode } from '@codexo/exojs/renderer-sdk';
3
+ import { PixelSnapMode } from '@codexo/exojs/renderer-sdk';
4
+ import { ImageLayerNode } from './ImageLayerNode';
4
5
  import { TileLayerNode } from './TileLayerNode';
5
6
  import type { TileMap } from './TileMap';
6
7
  /**
@@ -16,17 +17,19 @@ export interface TileMapNodeOptions {
16
17
  }
17
18
  /**
18
19
  * A convenience scene node that renders a whole {@link TileMap} as a
19
- * {@link Container} of one {@link TileLayerNode} per tile layer, in map layer
20
- * order (back-to-front by document order).
20
+ * {@link Container} of one node per renderable layer - a {@link TileLayerNode}
21
+ * per tile layer and an {@link ImageLayerNode} per image layer, interleaved
22
+ * back-to-front by the map's combined document order
23
+ * ({@link import('./TileMap').TileMap.renderableLayers}).
21
24
  *
22
- * `TileMapNode` owns **only** its layer nodes never application actors. Use
25
+ * `TileMapNode` owns **only** its layer nodes - never application actors. Use
23
26
  * it for the simple, non-interleaved case (no actors between layers); for
24
- * actor interleaving, place individual `TileLayerNode`s into your own scene
25
- * graph instead.
27
+ * actor interleaving, place individual `TileLayerNode`s / `ImageLayerNode`s
28
+ * into your own scene graph instead (see `TileMapView`).
26
29
  *
27
- * The node references but never owns the {@link TileMap}: destroying the
30
+ * The node references - but never owns - the {@link TileMap}: destroying the
28
31
  * node frees its layer/chunk nodes and their cached GPU geometry, while the
29
- * `TileMap` data and Loader-owned tileset textures survive (free them via
32
+ * `TileMap` data and Loader-owned textures survive (free them via
30
33
  * `TileMap.destroy()` / `Loader.destroy()` respectively).
31
34
  *
32
35
  * Layers added to or removed from the map after construction are reflected only
@@ -47,25 +50,38 @@ export declare class TileMapNode extends Container {
47
50
  * chunk node, current and rebuilt). Snaps tile chunk origins to the active
48
51
  * render target's device-pixel grid for crisp tiles; with integer tile pitch
49
52
  * the grid stays exact and adjacent chunks/layers cannot drift apart. Purely
50
- * visual tile data, layer offsets, chunk revisions, and culling are
53
+ * visual - tile data, layer offsets, chunk revisions, and culling are
51
54
  * unchanged. Setting the current value is a no-op; an invalid value throws and
52
55
  * leaves the prior mode unchanged.
53
56
  *
54
- * @default 'none'
57
+ * @default PixelSnapMode.None
55
58
  * @stable
56
59
  */
57
60
  get pixelSnapMode(): PixelSnapMode;
58
61
  set pixelSnapMode(mode: PixelSnapMode);
59
- /** The layer render nodes, in map layer order. */
60
- get layerNodes(): readonly TileLayerNode[];
61
- /** Find the layer node rendering the named layer, or `undefined`. */
62
- getLayerNode(name: string): TileLayerNode | undefined;
63
62
  /**
64
- * Rebuild the layer-node children from the map's current layers. Call after
65
- * layers are structurally added to or removed from the map.
63
+ * The layer render nodes - tile and image alike - in the map's combined
64
+ * document order.
65
+ */
66
+ get layerNodes(): ReadonlyArray<TileLayerNode | ImageLayerNode>;
67
+ /**
68
+ * Find the layer node rendering the named layer (tile or image; first match
69
+ * in document order), or `undefined`.
70
+ */
71
+ getLayerNode(name: string): TileLayerNode | ImageLayerNode | undefined;
72
+ /**
73
+ * Rebuild the layer-node children from the map's current renderable layers.
74
+ * Call after tile or image layers are structurally added to or removed from
75
+ * the map.
66
76
  */
67
77
  refreshLayers(): this;
68
- getLocalBounds(): Rectangle;
78
+ /**
79
+ * Recomputed lazily on read, so it writes `_localBounds` directly rather than
80
+ * going through `_setLocalBounds`: an invalidating write inside a getter
81
+ * would re-dirty the node on every read.
82
+ */
83
+ getLocalBounds(): ReadonlyRectangle;
69
84
  destroy(): void;
70
85
  private _buildLayerNodes;
71
86
  }
87
+ //# sourceMappingURL=TileMapNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TileMapNode.d.ts","sourceRoot":"","sources":["../../src/TileMapNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6C;IACzE,OAAO,CAAC,cAAc,CAAqC;gBAExC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAa7D,yCAAyC;IACzC,IAAW,GAAG,IAAI,OAAO,CAExB;IAED;;;;;;;;;;;OAWG;IACH,IAAW,aAAa,IAAI,aAAa,CAExC;IAED,IAAW,aAAa,CAAC,IAAI,EAAE,aAAa,EAW3C;IAED;;;OAGG;IACH,IAAW,UAAU,IAAI,aAAa,CAAC,aAAa,GAAG,cAAc,CAAC,CAErE;IAED;;;OAGG;IACI,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,GAAG,SAAS;IAI7E;;;;OAIG;IACI,aAAa,IAAI,IAAI;IAe5B;;;;OAIG;IACa,cAAc,IAAI,iBAAiB;IAgBnC,OAAO,IAAI,IAAI;IAY/B,OAAO,CAAC,gBAAgB;CAYzB"}
@@ -1,113 +1,126 @@
1
- import { Container } from '@codexo/exojs';
2
- import { assertPixelSnapMode } from './pixelSnap.js';
3
- import { TileLayerNode } from './TileLayerNode.js';
1
+ import { ImageLayer } from "./ImageLayer.js";
2
+ import { assertPixelSnapMode } from "./pixelSnap.js";
3
+ import { ImageLayerNode } from "./ImageLayerNode.js";
4
+ import { aggregateChildLocalBounds } from "./nodeBounds.js";
5
+ import { TileLayerNode } from "./TileLayerNode.js";
6
+ import { PixelSnapMode } from "@codexo/exojs/renderer-sdk";
7
+ import { Container } from "@codexo/exojs";
4
8
 
9
+ //#region src/TileMapNode.ts
5
10
  /**
6
- * A convenience scene node that renders a whole {@link TileMap} as a
7
- * {@link Container} of one {@link TileLayerNode} per tile layer, in map layer
8
- * order (back-to-front by document order).
9
- *
10
- * `TileMapNode` owns **only** its layer nodes — never application actors. Use
11
- * it for the simple, non-interleaved case (no actors between layers); for
12
- * actor interleaving, place individual `TileLayerNode`s into your own scene
13
- * graph instead.
14
- *
15
- * The node references but never owns — the {@link TileMap}: destroying the
16
- * node frees its layer/chunk nodes and their cached GPU geometry, while the
17
- * `TileMap` data and Loader-owned tileset textures survive (free them via
18
- * `TileMap.destroy()` / `Loader.destroy()` respectively).
19
- *
20
- * Layers added to or removed from the map after construction are reflected only
21
- * after {@link TileMapNode.refreshLayers}.
22
- *
23
- * @advanced
24
- */
25
- class TileMapNode extends Container {
26
- _map;
27
- _cullChunks;
28
- _layerNodes = [];
29
- _pixelSnapMode = 'none';
30
- constructor(map, options) {
31
- super();
32
- this._map = map;
33
- this._cullChunks = options?.cullable ?? true;
34
- this._buildLayerNodes();
35
- }
36
- /** The runtime map this node renders. */
37
- get map() {
38
- return this._map;
39
- }
40
- /**
41
- * Render-only pixel-snap mode applied to every layer (and forwarded to every
42
- * chunk node, current and rebuilt). Snaps tile chunk origins to the active
43
- * render target's device-pixel grid for crisp tiles; with integer tile pitch
44
- * the grid stays exact and adjacent chunks/layers cannot drift apart. Purely
45
- * visual tile data, layer offsets, chunk revisions, and culling are
46
- * unchanged. Setting the current value is a no-op; an invalid value throws and
47
- * leaves the prior mode unchanged.
48
- *
49
- * @default 'none'
50
- * @stable
51
- */
52
- get pixelSnapMode() {
53
- return this._pixelSnapMode;
54
- }
55
- set pixelSnapMode(mode) {
56
- if (mode === this._pixelSnapMode) {
57
- return;
58
- }
59
- assertPixelSnapMode(mode);
60
- this._pixelSnapMode = mode;
61
- for (const node of this._layerNodes) {
62
- node.pixelSnapMode = mode;
63
- }
64
- }
65
- /** The layer render nodes, in map layer order. */
66
- get layerNodes() {
67
- return this._layerNodes;
68
- }
69
- /** Find the layer node rendering the named layer, or `undefined`. */
70
- getLayerNode(name) {
71
- return this._layerNodes.find(node => node.layer.name === name);
72
- }
73
- /**
74
- * Rebuild the layer-node children from the map's current layers. Call after
75
- * layers are structurally added to or removed from the map.
76
- */
77
- refreshLayers() {
78
- const previous = [...this._layerNodes];
79
- this.removeChildren();
80
- this._layerNodes.length = 0;
81
- for (const node of previous) {
82
- node.destroy();
83
- }
84
- this._buildLayerNodes();
85
- return this;
86
- }
87
- getLocalBounds() {
88
- const bounds = super.getLocalBounds();
89
- bounds.set(0, 0, this._map.pixelWidth, this._map.pixelHeight);
90
- return bounds;
91
- }
92
- destroy() {
93
- const layerNodes = [...this._layerNodes];
94
- this._layerNodes.length = 0;
95
- super.destroy();
96
- for (const node of layerNodes) {
97
- node.destroy();
98
- }
99
- }
100
- _buildLayerNodes() {
101
- for (const layer of this._map.layers) {
102
- const node = new TileLayerNode(layer, { cullable: this._cullChunks });
103
- if (this._pixelSnapMode !== 'none') {
104
- node.pixelSnapMode = this._pixelSnapMode;
105
- }
106
- this._layerNodes.push(node);
107
- this.addChild(node);
108
- }
109
- }
110
- }
11
+ * A convenience scene node that renders a whole {@link TileMap} as a
12
+ * {@link Container} of one node per renderable layer - a {@link TileLayerNode}
13
+ * per tile layer and an {@link ImageLayerNode} per image layer, interleaved
14
+ * back-to-front by the map's combined document order
15
+ * ({@link import('./TileMap').TileMap.renderableLayers}).
16
+ *
17
+ * `TileMapNode` owns **only** its layer nodes - never application actors. Use
18
+ * it for the simple, non-interleaved case (no actors between layers); for
19
+ * actor interleaving, place individual `TileLayerNode`s / `ImageLayerNode`s
20
+ * into your own scene graph instead (see `TileMapView`).
21
+ *
22
+ * The node references - but never owns - the {@link TileMap}: destroying the
23
+ * node frees its layer/chunk nodes and their cached GPU geometry, while the
24
+ * `TileMap` data and Loader-owned textures survive (free them via
25
+ * `TileMap.destroy()` / `Loader.destroy()` respectively).
26
+ *
27
+ * Layers added to or removed from the map after construction are reflected only
28
+ * after {@link TileMapNode.refreshLayers}.
29
+ *
30
+ * @advanced
31
+ */
32
+ var TileMapNode = class extends Container {
33
+ _map;
34
+ _cullChunks;
35
+ _layerNodes = [];
36
+ _pixelSnapMode = PixelSnapMode.None;
37
+ constructor(map, options) {
38
+ super();
39
+ this._map = map;
40
+ this._cullChunks = options?.cullable ?? true;
41
+ this._buildLayerNodes();
42
+ if (!this._map.bounded) this.cullable = false;
43
+ }
44
+ /** The runtime map this node renders. */
45
+ get map() {
46
+ return this._map;
47
+ }
48
+ /**
49
+ * Render-only pixel-snap mode applied to every layer (and forwarded to every
50
+ * chunk node, current and rebuilt). Snaps tile chunk origins to the active
51
+ * render target's device-pixel grid for crisp tiles; with integer tile pitch
52
+ * the grid stays exact and adjacent chunks/layers cannot drift apart. Purely
53
+ * visual - tile data, layer offsets, chunk revisions, and culling are
54
+ * unchanged. Setting the current value is a no-op; an invalid value throws and
55
+ * leaves the prior mode unchanged.
56
+ *
57
+ * @default PixelSnapMode.None
58
+ * @stable
59
+ */
60
+ get pixelSnapMode() {
61
+ return this._pixelSnapMode;
62
+ }
63
+ set pixelSnapMode(mode) {
64
+ if (mode === this._pixelSnapMode) return;
65
+ assertPixelSnapMode(mode);
66
+ this._pixelSnapMode = mode;
67
+ for (const node of this._layerNodes) node.pixelSnapMode = mode;
68
+ }
69
+ /**
70
+ * The layer render nodes - tile and image alike - in the map's combined
71
+ * document order.
72
+ */
73
+ get layerNodes() {
74
+ return this._layerNodes;
75
+ }
76
+ /**
77
+ * Find the layer node rendering the named layer (tile or image; first match
78
+ * in document order), or `undefined`.
79
+ */
80
+ getLayerNode(name) {
81
+ return this._layerNodes.find((node) => node.layer.name === name);
82
+ }
83
+ /**
84
+ * Rebuild the layer-node children from the map's current renderable layers.
85
+ * Call after tile or image layers are structurally added to or removed from
86
+ * the map.
87
+ */
88
+ refreshLayers() {
89
+ const previous = [...this._layerNodes];
90
+ this.removeChildren();
91
+ this._layerNodes.length = 0;
92
+ for (const node of previous) node.destroy();
93
+ this._buildLayerNodes();
94
+ return this;
95
+ }
96
+ /**
97
+ * Recomputed lazily on read, so it writes `_localBounds` directly rather than
98
+ * going through `_setLocalBounds`: an invalidating write inside a getter
99
+ * would re-dirty the node on every read.
100
+ */
101
+ getLocalBounds() {
102
+ const bounds = this._localBounds;
103
+ const { pixelHeight, pixelWidth } = this._map;
104
+ if (pixelWidth !== void 0 && pixelHeight !== void 0) bounds.set(0, 0, pixelWidth, pixelHeight);
105
+ else if (this._layerNodes.length > 0) aggregateChildLocalBounds(this._layerNodes, bounds);
106
+ return bounds;
107
+ }
108
+ destroy() {
109
+ const layerNodes = [...this._layerNodes];
110
+ this._layerNodes.length = 0;
111
+ super.destroy();
112
+ for (const node of layerNodes) node.destroy();
113
+ }
114
+ _buildLayerNodes() {
115
+ for (const layer of this._map.renderableLayers) {
116
+ const node = layer instanceof ImageLayer ? new ImageLayerNode(layer) : new TileLayerNode(layer, { cullable: this._cullChunks });
117
+ if (this._pixelSnapMode !== PixelSnapMode.None) node.pixelSnapMode = this._pixelSnapMode;
118
+ this._layerNodes.push(node);
119
+ this.addChild(node);
120
+ }
121
+ }
122
+ };
111
123
 
124
+ //#endregion
112
125
  export { TileMapNode };
113
- //# sourceMappingURL=TileMapNode.js.map
126
+ //# sourceMappingURL=TileMapNode.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TileMapNode.js","sources":["../../../src/TileMapNode.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAoBA;;;;;;;;;;;;;;;;;;;AAmBG;AACG,MAAO,WAAY,SAAQ,SAAS,CAAA;AACvB,IAAA,IAAI;AACJ,IAAA,WAAW;IACX,WAAW,GAAoB,EAAE;IAC1C,cAAc,GAAkB,MAAM;IAE9C,WAAA,CAAmB,GAAY,EAAE,OAA4B,EAAA;AAC3D,QAAA,KAAK,EAAE;AAEP,QAAA,IAAI,CAAC,IAAI,GAAG,GAAG;QACf,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,QAAQ,IAAI,IAAI;QAE5C,IAAI,CAAC,gBAAgB,EAAE;IACzB;;AAGA,IAAA,IAAW,GAAG,GAAA;QACZ,OAAO,IAAI,CAAC,IAAI;IAClB;AAEA;;;;;;;;;;;AAWG;AACH,IAAA,IAAW,aAAa,GAAA;QACtB,OAAO,IAAI,CAAC,cAAc;IAC5B;IAEA,IAAW,aAAa,CAAC,IAAmB,EAAA;AAC1C,QAAA,IAAI,IAAI,KAAK,IAAI,CAAC,cAAc,EAAE;YAChC;QACF;QAEA,mBAAmB,CAAC,IAAI,CAAC;AACzB,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;AAE1B,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE;AACnC,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI;QAC3B;IACF;;AAGA,IAAA,IAAW,UAAU,GAAA;QACnB,OAAO,IAAI,CAAC,WAAW;IACzB;;AAGO,IAAA,YAAY,CAAC,IAAY,EAAA;AAC9B,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;IAChE;AAEA;;;AAGG;IACI,aAAa,GAAA;QAClB,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;QAEtC,IAAI,CAAC,cAAc,EAAE;AACrB,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;AAE3B,QAAA,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE;YAC3B,IAAI,CAAC,OAAO,EAAE;QAChB;QAEA,IAAI,CAAC,gBAAgB,EAAE;AAEvB,QAAA,OAAO,IAAI;IACb;IAEgB,cAAc,GAAA;AAC5B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,EAAE;AAErC,QAAA,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;AAE7D,QAAA,OAAO,MAAM;IACf;IAEgB,OAAO,GAAA;QACrB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;AAExC,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAE3B,KAAK,CAAC,OAAO,EAAE;AAEf,QAAA,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;YAC7B,IAAI,CAAC,OAAO,EAAE;QAChB;IACF;IAEQ,gBAAgB,GAAA;QACtB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AACpC,YAAA,MAAM,IAAI,GAAG,IAAI,aAAa,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;AAErE,YAAA,IAAI,IAAI,CAAC,cAAc,KAAK,MAAM,EAAE;AAClC,gBAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,cAAc;YAC1C;AAEA,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;AAC3B,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACrB;IACF;AACD;;;;"}
1
+ {"version":3,"file":"TileMapNode.js","names":[],"sources":["../../src/TileMapNode.ts"],"sourcesContent":["import type { ReadonlyRectangle } from '@codexo/exojs';\nimport { Container } from '@codexo/exojs';\nimport { PixelSnapMode } from '@codexo/exojs/renderer-sdk';\n\nimport { ImageLayer } from './ImageLayer';\nimport { ImageLayerNode } from './ImageLayerNode';\nimport { aggregateChildLocalBounds } from './nodeBounds';\nimport { assertPixelSnapMode } from './pixelSnap';\nimport { TileLayerNode } from './TileLayerNode';\nimport type { TileMap } from './TileMap';\n\n/**\n * Options for a {@link TileMapNode}.\n * @advanced\n */\nexport interface TileMapNodeOptions {\n /**\n * Whether the map's chunk nodes participate in per-chunk view culling.\n * Forwarded to every {@link TileLayerNode}. Defaults to `true`.\n */\n readonly cullable?: boolean;\n}\n\n/**\n * A convenience scene node that renders a whole {@link TileMap} as a\n * {@link Container} of one node per renderable layer - a {@link TileLayerNode}\n * per tile layer and an {@link ImageLayerNode} per image layer, interleaved\n * back-to-front by the map's combined document order\n * ({@link import('./TileMap').TileMap.renderableLayers}).\n *\n * `TileMapNode` owns **only** its layer nodes - never application actors. Use\n * it for the simple, non-interleaved case (no actors between layers); for\n * actor interleaving, place individual `TileLayerNode`s / `ImageLayerNode`s\n * into your own scene graph instead (see `TileMapView`).\n *\n * The node references - but never owns - the {@link TileMap}: destroying the\n * node frees its layer/chunk nodes and their cached GPU geometry, while the\n * `TileMap` data and Loader-owned textures survive (free them via\n * `TileMap.destroy()` / `Loader.destroy()` respectively).\n *\n * Layers added to or removed from the map after construction are reflected only\n * after {@link TileMapNode.refreshLayers}.\n *\n * @advanced\n */\nexport class TileMapNode extends Container {\n private readonly _map: TileMap;\n private readonly _cullChunks: boolean;\n private readonly _layerNodes: Array<TileLayerNode | ImageLayerNode> = [];\n private _pixelSnapMode: PixelSnapMode = PixelSnapMode.None;\n\n public constructor(map: TileMap, options?: TileMapNodeOptions) {\n super();\n\n this._map = map;\n this._cullChunks = options?.cullable ?? true;\n\n this._buildLayerNodes();\n\n if (!this._map.bounded) {\n this.cullable = false;\n }\n }\n\n /** The runtime map this node renders. */\n public get map(): TileMap {\n return this._map;\n }\n\n /**\n * Render-only pixel-snap mode applied to every layer (and forwarded to every\n * chunk node, current and rebuilt). Snaps tile chunk origins to the active\n * render target's device-pixel grid for crisp tiles; with integer tile pitch\n * the grid stays exact and adjacent chunks/layers cannot drift apart. Purely\n * visual - tile data, layer offsets, chunk revisions, and culling are\n * unchanged. Setting the current value is a no-op; an invalid value throws and\n * leaves the prior mode unchanged.\n *\n * @default PixelSnapMode.None\n * @stable\n */\n public get pixelSnapMode(): PixelSnapMode {\n return this._pixelSnapMode;\n }\n\n public set pixelSnapMode(mode: PixelSnapMode) {\n if (mode === this._pixelSnapMode) {\n return;\n }\n\n assertPixelSnapMode(mode);\n this._pixelSnapMode = mode;\n\n for (const node of this._layerNodes) {\n node.pixelSnapMode = mode;\n }\n }\n\n /**\n * The layer render nodes - tile and image alike - in the map's combined\n * document order.\n */\n public get layerNodes(): ReadonlyArray<TileLayerNode | ImageLayerNode> {\n return this._layerNodes;\n }\n\n /**\n * Find the layer node rendering the named layer (tile or image; first match\n * in document order), or `undefined`.\n */\n public getLayerNode(name: string): TileLayerNode | ImageLayerNode | undefined {\n return this._layerNodes.find(node => node.layer.name === name);\n }\n\n /**\n * Rebuild the layer-node children from the map's current renderable layers.\n * Call after tile or image layers are structurally added to or removed from\n * the map.\n */\n public refreshLayers(): this {\n const previous = [...this._layerNodes];\n\n this.removeChildren();\n this._layerNodes.length = 0;\n\n for (const node of previous) {\n node.destroy();\n }\n\n this._buildLayerNodes();\n\n return this;\n }\n\n /**\n * Recomputed lazily on read, so it writes `_localBounds` directly rather than\n * going through `_setLocalBounds`: an invalidating write inside a getter\n * would re-dirty the node on every read.\n */\n public override getLocalBounds(): ReadonlyRectangle {\n const bounds = this._localBounds;\n\n // Reading the pixel extents directly (rather than gating on `bounded`)\n // is what narrows them to numbers - `bounded` is a plain boolean getter.\n const { pixelHeight, pixelWidth } = this._map;\n\n if (pixelWidth !== undefined && pixelHeight !== undefined) {\n bounds.set(0, 0, pixelWidth, pixelHeight);\n } else if (this._layerNodes.length > 0) {\n aggregateChildLocalBounds(this._layerNodes, bounds);\n }\n\n return bounds;\n }\n\n public override destroy(): void {\n const layerNodes = [...this._layerNodes];\n\n this._layerNodes.length = 0;\n\n super.destroy();\n\n for (const node of layerNodes) {\n node.destroy();\n }\n }\n\n private _buildLayerNodes(): void {\n for (const layer of this._map.renderableLayers) {\n const node = layer instanceof ImageLayer ? new ImageLayerNode(layer) : new TileLayerNode(layer, { cullable: this._cullChunks });\n\n if (this._pixelSnapMode !== PixelSnapMode.None) {\n node.pixelSnapMode = this._pixelSnapMode;\n }\n\n this._layerNodes.push(node);\n this.addChild(node);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAa,cAAb,cAAiC,UAAU;CACzC,AAAiB;CACjB,AAAiB;CACjB,AAAiB,cAAqD,CAAC;CACvE,AAAQ,iBAAgC,cAAc;CAEtD,AAAO,YAAY,KAAc,SAA8B;EAC7D,MAAM;EAEN,KAAK,OAAO;EACZ,KAAK,cAAc,SAAS,YAAY;EAExC,KAAK,iBAAiB;EAEtB,IAAI,CAAC,KAAK,KAAK,SACb,KAAK,WAAW;CAEpB;;CAGA,IAAW,MAAe;EACxB,OAAO,KAAK;CACd;;;;;;;;;;;;;CAcA,IAAW,gBAA+B;EACxC,OAAO,KAAK;CACd;CAEA,IAAW,cAAc,MAAqB;EAC5C,IAAI,SAAS,KAAK,gBAChB;EAGF,oBAAoB,IAAI;EACxB,KAAK,iBAAiB;EAEtB,KAAK,MAAM,QAAQ,KAAK,aACtB,KAAK,gBAAgB;CAEzB;;;;;CAMA,IAAW,aAA4D;EACrE,OAAO,KAAK;CACd;;;;;CAMA,AAAO,aAAa,MAA0D;EAC5E,OAAO,KAAK,YAAY,MAAK,SAAQ,KAAK,MAAM,SAAS,IAAI;CAC/D;;;;;;CAOA,AAAO,gBAAsB;EAC3B,MAAM,WAAW,CAAC,GAAG,KAAK,WAAW;EAErC,KAAK,eAAe;EACpB,KAAK,YAAY,SAAS;EAE1B,KAAK,MAAM,QAAQ,UACjB,KAAK,QAAQ;EAGf,KAAK,iBAAiB;EAEtB,OAAO;CACT;;;;;;CAOA,AAAgB,iBAAoC;EAClD,MAAM,SAAS,KAAK;EAIpB,MAAM,EAAE,aAAa,eAAe,KAAK;EAEzC,IAAI,eAAe,UAAa,gBAAgB,QAC9C,OAAO,IAAI,GAAG,GAAG,YAAY,WAAW;OACnC,IAAI,KAAK,YAAY,SAAS,GACnC,0BAA0B,KAAK,aAAa,MAAM;EAGpD,OAAO;CACT;CAEA,AAAgB,UAAgB;EAC9B,MAAM,aAAa,CAAC,GAAG,KAAK,WAAW;EAEvC,KAAK,YAAY,SAAS;EAE1B,MAAM,QAAQ;EAEd,KAAK,MAAM,QAAQ,YACjB,KAAK,QAAQ;CAEjB;CAEA,AAAQ,mBAAyB;EAC/B,KAAK,MAAM,SAAS,KAAK,KAAK,kBAAkB;GAC9C,MAAM,OAAO,iBAAiB,aAAa,IAAI,eAAe,KAAK,IAAI,IAAI,cAAc,OAAO,EAAE,UAAU,KAAK,YAAY,CAAC;GAE9H,IAAI,KAAK,mBAAmB,cAAc,MACxC,KAAK,gBAAgB,KAAK;GAG5B,KAAK,YAAY,KAAK,IAAI;GAC1B,KAAK,SAAS,IAAI;EACpB;CACF;AACF"}
@@ -1,20 +1,26 @@
1
- import type { PixelSnapMode } from '@codexo/exojs/renderer-sdk';
1
+ import { PixelSnapMode } from '@codexo/exojs/renderer-sdk';
2
+ import { ImageLayerNode } from './ImageLayerNode';
2
3
  import { TileLayerNode } from './TileLayerNode';
3
4
  import type { TileMap } from './TileMap';
4
5
  import { TileMapBand } from './TileMapBand';
5
6
  /**
6
7
  * A layer selector inside a {@link TileMapBandDefinition}: either a stable
7
- * layer **id** (`number`) or a **unique** layer **name** (`string`). Names that
8
- * are shared by more than one layer are rejected as ambiguous reference such
9
- * layers by id.
8
+ * layer **id** (`number`) or a **unique** layer **name** (`string`). Selectors
9
+ * resolve across the map's tile **and** image layers. Names that are shared by
10
+ * more than one layer (of either kind) are rejected as ambiguous - reference
11
+ * such layers by id. An id shared by a tile layer and an image layer (possible
12
+ * only in fallback-ordered maps, which never validated cross-kind uniqueness)
13
+ * is equally ambiguous - reference such layers by a unique name.
10
14
  * @advanced
11
15
  */
12
16
  export type TileLayerSelector = number | string;
13
17
  /**
14
- * The layers composing one band, by id or unique name, in any order. Rendering
15
- * order always follows map document order regardless of the order listed here —
16
- * a definition *selects* layers, it never reorders them. The band's name is the
17
- * key it is registered under in {@link TileMapViewOptions.bands}.
18
+ * The layers composing one band, by id or unique name, in any order. Tile and
19
+ * image layers may be freely mixed. Rendering order always follows the map's
20
+ * combined document order ({@link import('./TileMap').TileMap.renderableLayers})
21
+ * regardless of the order listed here - a definition *selects* layers, it never
22
+ * reorders them. The band's name is the key it is registered under in
23
+ * {@link TileMapViewOptions.bands}.
18
24
  * @advanced
19
25
  */
20
26
  export type TileMapBandDefinition = readonly TileLayerSelector[];
@@ -25,15 +31,16 @@ export type TileMapBandDefinition = readonly TileLayerSelector[];
25
31
  export interface TileMapViewOptions {
26
32
  /**
27
33
  * Named bands, keyed by band name (keys are unique, so duplicate band names
28
- * cannot occur). Each value lists the layers that compose the band. Layers
29
- * not listed in any band remain reachable through
30
- * {@link TileMapView.getLayerNodeById} and friends and are owned directly by
31
- * the view (no implicit fallback band). The definition is copied and frozen;
32
- * mutating the caller's object afterwards does not change band assignments.
34
+ * cannot occur). Each value lists the layers that compose the band - tile
35
+ * and image layers alike. Layers not listed in any band remain reachable
36
+ * through {@link TileMapView.getLayerNodeById} and friends and are owned
37
+ * directly by the view (no implicit fallback band). The definition is copied
38
+ * and frozen; mutating the caller's object afterwards does not change band
39
+ * assignments.
33
40
  *
34
41
  * @throws (at construction) on an unknown layer id, an unknown or ambiguous
35
- * layer name, a layer listed twice within one band, or a layer assigned to
36
- * more than one band.
42
+ * layer name, a cross-kind ambiguous layer id, a layer listed twice within
43
+ * one band, or a layer assigned to more than one band.
37
44
  */
38
45
  readonly bands?: Readonly<Record<string, TileMapBandDefinition>>;
39
46
  /**
@@ -49,7 +56,7 @@ export interface TileMapViewOptions {
49
56
  * A view produces exactly one canonical {@link TileLayerNode} per map layer
50
57
  * (stable identity, map document order) and, optionally, named {@link TileMapBand}s
51
58
  * grouping subsets of those nodes. The application parents the bands / layer
52
- * nodes wherever it wants typically as siblings of its own actor containers:
59
+ * nodes wherever it wants - typically as siblings of its own actor containers:
53
60
  *
54
61
  * ```ts
55
62
  * const view = map.createView({ bands: { ground: ['background', 'ground'], roof: ['roofs'] } });
@@ -59,7 +66,7 @@ export interface TileMapViewOptions {
59
66
  * ```
60
67
  *
61
68
  * **Actors are application-owned siblings.** A `TileMapView` never adopts or
62
- * destroys actors. The view is a helper, not a scene node it does not own the
69
+ * destroys actors. The view is a helper, not a scene node - it does not own the
63
70
  * world container, the {@link TileMap}, the {@link TileLayer}s, or tileset
64
71
  * textures.
65
72
  *
@@ -69,16 +76,28 @@ export interface TileMapViewOptions {
69
76
  * (detaching them from their application parents) but leaves actors, the map,
70
77
  * its layers, and Loader-owned textures untouched. There is no map-replacement
71
78
  * mutation API: to swap maps, destroy the old view, construct a new one, and
72
- * re-parent its bands the actor tree is never involved.
79
+ * re-parent its bands - the actor tree is never involved.
80
+ *
81
+ * **Image layers.** A view also produces exactly one canonical
82
+ * {@link ImageLayerNode} per {@link TileMap.imageLayers} entry (stable identity,
83
+ * map document order), reachable through {@link imageLayerNodes},
84
+ * {@link getImageLayerNodeById}, and {@link getImageLayerNodeByName}. Image
85
+ * layers are selectable in {@link TileMapViewOptions.bands} exactly like tile
86
+ * layers: a band member list may mix both kinds, and the band stacks its
87
+ * members by the map's combined document order
88
+ * ({@link import('./TileMap').TileMap.renderableLayers}). A banded image node
89
+ * is owned by its band; an unbanded one is owned by the view directly, and the
90
+ * application parents it wherever the image belongs in draw order - the same
91
+ * way actors are interleaved.
73
92
  *
74
93
  * @advanced
75
94
  */
76
95
  export declare class TileMapView {
77
96
  private readonly _map;
78
97
  private readonly _cullable;
79
- /** All canonical layer nodes, in map document order. */
98
+ /** All canonical tile-layer nodes, in map document order. */
80
99
  private readonly _layerNodes;
81
- /** Layer id → its canonical layer node. */
100
+ /** Tile layer id → its canonical layer node. */
82
101
  private readonly _layerNodeById;
83
102
  /** Bands in definition (insertion) order. */
84
103
  private readonly _bands;
@@ -88,8 +107,12 @@ export declare class TileMapView {
88
107
  private readonly _bandDefs;
89
108
  /** Layer node → its owning band (absent = view-owned / unbanded). */
90
109
  private readonly _nodeBand;
91
- /** Unbanded layer nodes owned directly by the view, in map document order. */
110
+ /** Unbanded tile-layer nodes owned directly by the view, in map document order. */
92
111
  private readonly _directLayerNodes;
112
+ /** All canonical image layer nodes, in map document order. */
113
+ private readonly _imageLayerNodes;
114
+ /** Image layer id → its canonical image layer node. */
115
+ private readonly _imageLayerNodeById;
93
116
  private _destroyed;
94
117
  private _pixelSnapMode;
95
118
  /**
@@ -101,7 +124,7 @@ export declare class TileMapView {
101
124
  constructor(map: TileMap, options?: TileMapViewOptions);
102
125
  /** The runtime map this view composes. Referenced, never owned. */
103
126
  get map(): TileMap;
104
- /** All canonical layer nodes, one per map layer, in map document order. */
127
+ /** All canonical tile-layer nodes, one per map tile layer, in map document order. */
105
128
  get layers(): readonly TileLayerNode[];
106
129
  /** The bands, in definition (insertion) order. */
107
130
  get bands(): readonly TileMapBand[];
@@ -112,30 +135,47 @@ export declare class TileMapView {
112
135
  * forwarded to every chunk drawable, current and rebuilt by
113
136
  * {@link refreshLayers}). Snaps tile chunk origins to the active render
114
137
  * target's device-pixel grid for crisp tiles; with integer tile pitch the grid
115
- * stays exact and adjacent chunks cannot drift apart. Purely visual tile
138
+ * stays exact and adjacent chunks cannot drift apart. Purely visual - tile
116
139
  * data, layer offsets, chunk revisions, and culling are unchanged. Setting the
117
140
  * current value is a no-op; an invalid value throws and leaves the prior mode
118
141
  * unchanged.
119
142
  *
120
- * @default 'none'
143
+ * @default PixelSnapMode.None
121
144
  * @stable
122
145
  */
123
146
  get pixelSnapMode(): PixelSnapMode;
124
147
  set pixelSnapMode(mode: PixelSnapMode);
125
148
  /**
126
- * The canonical layer node for the layer with the given **id**, or
127
- * `undefined`. Ids are authoritative and unique this is the unambiguous
128
- * lookup. The returned node may be reparented into the caller's own
129
- * containers; the view still tracks it for refresh and destruction.
149
+ * The canonical layer node for the **tile** layer with the given **id**, or
150
+ * `undefined`. Tile ids are authoritative and unique - this is the
151
+ * unambiguous lookup. The returned node may be reparented into the caller's
152
+ * own containers; the view still tracks it for refresh and destruction.
130
153
  */
131
154
  getLayerNodeById(id: number): TileLayerNode | undefined;
132
155
  /**
133
- * Every canonical layer node whose layer has the given **name**, in map
156
+ * Every canonical tile-layer node whose layer has the given **name**, in map
134
157
  * document order. Layer names are not guaranteed unique, so this returns an
135
158
  * array (empty when no layer matches). Prefer {@link getLayerNodeById} when
136
159
  * you have the id.
137
160
  */
138
161
  getLayerNodesByName(name: string): readonly TileLayerNode[];
162
+ /** All canonical image layer nodes, one per map image layer, in map document order. */
163
+ get imageLayerNodes(): readonly ImageLayerNode[];
164
+ /**
165
+ * The canonical image layer node for the image layer with the given **id**,
166
+ * or `undefined`. Ids are authoritative and unique - this is the unambiguous
167
+ * lookup. The returned node may be reparented into the caller's own
168
+ * containers; the view still tracks it for refresh and destruction.
169
+ */
170
+ getImageLayerNodeById(id: number): ImageLayerNode | undefined;
171
+ /**
172
+ * The canonical image layer node for the image layer with the given
173
+ * **name**, or `undefined` if no image layer has that name. Prefer
174
+ * {@link getImageLayerNodeById} when you have the id.
175
+ * @throws If more than one image layer shares that name (reference such
176
+ * layers by id instead).
177
+ */
178
+ getImageLayerNodeByName(name: string): ImageLayerNode | undefined;
139
179
  /**
140
180
  * The band registered under `name`.
141
181
  * @throws If no band with that name was defined.
@@ -144,17 +184,19 @@ export declare class TileMapView {
144
184
  /** Whether a band with the given name was defined. */
145
185
  hasBand(name: string): boolean;
146
186
  /**
147
- * Rebuild the view after **structural** map changes (layers added to or
148
- * removed from the map). Ordinary tile edits and chunk creation/removal do
149
- * NOT need this those are handled by chunk revisions and
150
- * {@link TileLayerNode.refresh} respectively.
187
+ * Rebuild the view after **structural** map changes (tile or image layers
188
+ * added to or removed from the map). Ordinary tile edits and chunk
189
+ * creation/removal do NOT need this - those are handled by chunk revisions
190
+ * and {@link TileLayerNode.refresh} respectively.
151
191
  *
152
- * - Removed layers: their generated layer node is detached and destroyed.
153
- * - Unchanged layers: keep their existing layer node (stable identity).
154
- * - Added layers: a new layer node is created and assigned to the first band
155
- * whose definition selects it (by id, or by a currently-unambiguous name),
156
- * otherwise owned directly by the view.
157
- * - Every band's children are re-ordered to map document order.
192
+ * - Removed layers (tile or image): their generated node is detached and
193
+ * destroyed.
194
+ * - Unchanged layers: keep their existing node (stable identity).
195
+ * - Added layers (tile or image): a new node is created and assigned to the
196
+ * first band whose definition selects it (by a currently-unambiguous id or
197
+ * name), otherwise owned directly by the view.
198
+ * - Every band's children are re-ordered to the map's combined document
199
+ * order ({@link import('./TileMap').TileMap.renderableLayers}).
158
200
  *
159
201
  * Application actors are never touched, and bands keep their placement in the
160
202
  * application scene graph.
@@ -163,20 +205,39 @@ export declare class TileMapView {
163
205
  */
164
206
  refreshLayers(): this;
165
207
  /**
166
- * Destroy the view: every band and generated layer node is destroyed (and
167
- * detached from its application parent), freeing cached chunk geometry.
168
- * Idempotent. Application actors, sibling content, the {@link TileMap}, its
169
- * {@link TileLayer}s, and Loader-owned tileset textures all survive.
208
+ * Destroy the view: every band, generated tile-layer node, and generated
209
+ * {@link ImageLayerNode} is destroyed (and detached from its application
210
+ * parent), freeing cached chunk geometry. Banded nodes are destroyed by
211
+ * their band; unbanded ones by the view directly. Idempotent. Application
212
+ * actors, sibling content, the {@link TileMap}, its {@link TileLayer}s and
213
+ * image layers, and Loader-owned textures all survive.
170
214
  */
171
215
  destroy(): void;
172
216
  /** Resolve one band definition into a {@link TileMapBand} and record it. */
173
217
  private _defineBand;
174
- /** Resolve a single selector to a layer id, throwing on unknown/ambiguous. */
218
+ /**
219
+ * Resolve a single selector to a tile or image layer instance, throwing on
220
+ * unknown/ambiguous. Instances (not ids) disambiguate fallback-ordered maps
221
+ * in which a tile layer and an image layer share an id.
222
+ */
175
223
  private _resolveSelector;
224
+ /** The canonical node for a tile or image layer instance, if one exists. */
225
+ private _nodeFor;
176
226
  /** Assign a freshly created node to the first band that selects its layer. */
177
227
  private _assignNewNode;
178
- /** Whether a band definition selects the given layer (unambiguously by name). */
228
+ /**
229
+ * Whether a band definition selects the given layer - only by a selector
230
+ * that is currently unambiguous (a unique name, or an id not shared across
231
+ * kinds), mirroring {@link _resolveSelector}'s construction-time rules.
232
+ */
179
233
  private _definitionSelects;
180
- /** Detach + destroy a node, dropping it from band membership and registries. */
181
- private _removeNode;
234
+ /** Whether an id currently belongs to both a tile layer and an image layer. */
235
+ private _isCrossKindId;
236
+ /** Detach + destroy a tile node, dropping it from bands and registries. */
237
+ private _removeTileNode;
238
+ /** Detach + destroy an image node, dropping it from bands and registries. */
239
+ private _removeImageNode;
240
+ /** Release a node from its band, or from the view's direct-ownership list. */
241
+ private _releaseFromOwner;
182
242
  }
243
+ //# sourceMappingURL=TileMapView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TileMapView.d.ts","sourceRoot":"","sources":["../../src/TileMapView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG,SAAS,iBAAiB,EAAE,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACjE;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IAEpC,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,gDAAgD;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoC;IAEnE,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,wBAAwB;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,qEAAqE;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0D;IACpF,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuB;IAEzD,8DAA8D;IAC9D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwB;IACzD,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IAEzE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAqC;IAE3D;;;;;OAKG;gBACgB,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,kBAAkB;IA+B7D,mEAAmE;IACnE,IAAW,GAAG,IAAI,OAAO,CAExB;IAED,qFAAqF;IACrF,IAAW,MAAM,IAAI,SAAS,aAAa,EAAE,CAE5C;IAED,kDAAkD;IAClD,IAAW,KAAK,IAAI,SAAS,WAAW,EAAE,CAEzC;IAED,4CAA4C;IAC5C,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;;;;;;;;;;;OAYG;IACH,IAAW,aAAa,IAAI,aAAa,CAExC;IAED,IAAW,aAAa,CAAC,IAAI,EAAE,aAAa,EAe3C;IAED;;;;;OAKG;IACI,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI9D;;;;;OAKG;IACI,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,aAAa,EAAE;IAIlE,uFAAuF;IACvF,IAAW,eAAe,IAAI,SAAS,cAAc,EAAE,CAEtD;IAED;;;;;OAKG;IACI,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIpE;;;;;;OAMG;IACI,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAcxE;;;OAGG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAYtC,sDAAsD;IAC/C,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIrC;;;;;;;;;;;;;;;;;;;OAmBG;IACI,aAAa,IAAI,IAAI;IAgG5B;;;;;;;OAOG;IACI,OAAO,IAAI,IAAI;IAsCtB,4EAA4E;IAC5E,OAAO,CAAC,WAAW;IAwCnB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuCxB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ;IAUhB,8EAA8E;IAC9E,OAAO,CAAC,cAAc;IAatB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAmB1B,+EAA+E;IAC/E,OAAO,CAAC,cAAc;IAItB,2EAA2E;IAC3E,OAAO,CAAC,eAAe;IAevB,6EAA6E;IAC7E,OAAO,CAAC,gBAAgB;IAkBxB,8EAA8E;IAC9E,OAAO,CAAC,iBAAiB;CAc1B"}