@carbonenginejs/runtime-resource 0.1.0 → 0.7.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/FORMAT-PROVENANCE.md +14 -5
- package/README.md +537 -241
- package/dist/CjsMotherLode.js +1244 -29
- package/dist/CjsMotherLode.js.map +1 -1
- package/dist/CjsResMan.js +2537 -272
- package/dist/CjsResMan.js.map +1 -1
- package/dist/CjsResource.js +218 -18
- package/dist/CjsResource.js.map +1 -1
- package/dist/format/CjsBlueReader.js +269 -0
- package/dist/format/CjsBlueReader.js.map +1 -0
- package/dist/format/CjsFormat.js +44 -30
- package/dist/format/CjsFormat.js.map +1 -1
- package/dist/format/CjsReader.js +18 -0
- package/dist/format/CjsReader.js.map +1 -0
- package/dist/format/CjsResourceProbe.js +12 -4
- package/dist/format/CjsResourceProbe.js.map +1 -1
- package/dist/formats/black/CjsBlackFormat.js +12 -6
- package/dist/formats/black/CjsBlackFormat.js.map +1 -1
- package/dist/formats/black/core/CjsBlackReader.js +27 -148
- package/dist/formats/black/core/CjsBlackReader.js.map +1 -1
- package/dist/formats/bnk/CjsBnkFormat.js +140 -147
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
- package/dist/formats/bnk/core/graph.js +140 -0
- package/dist/formats/bnk/core/graph.js.map +1 -0
- package/dist/formats/bnk/core/helpers.js +58 -3
- package/dist/formats/bnk/core/helpers.js.map +1 -1
- package/dist/formats/bnk/core/musicNodes.js +521 -0
- package/dist/formats/bnk/core/musicNodes.js.map +1 -0
- package/dist/formats/bnk/index.js +0 -1
- package/dist/formats/bnk/index.js.map +1 -1
- package/dist/formats/cmf/CjsCmfFormat.js +14 -8
- package/dist/formats/cmf/CjsCmfFormat.js.map +1 -1
- package/dist/formats/dds/CjsDdsFormat.js +12 -6
- package/dist/formats/dds/CjsDdsFormat.js.map +1 -1
- package/dist/formats/fbx/CjsFbxFormat.js +12 -6
- package/dist/formats/fbx/CjsFbxFormat.js.map +1 -1
- package/dist/formats/flac/CjsFlacFormat.js +10 -4
- package/dist/formats/flac/CjsFlacFormat.js.map +1 -1
- package/dist/formats/gif/CjsGifFormat.js +11 -5
- package/dist/formats/gif/CjsGifFormat.js.map +1 -1
- package/dist/formats/gltf/CjsGltfFormat.js +12 -6
- package/dist/formats/gltf/CjsGltfFormat.js.map +1 -1
- package/dist/formats/jpeg/CjsJpegFormat.js +11 -5
- package/dist/formats/jpeg/CjsJpegFormat.js.map +1 -1
- package/dist/formats/mp3/CjsMp3Format.js +11 -5
- package/dist/formats/mp3/CjsMp3Format.js.map +1 -1
- package/dist/formats/mp4/CjsMp4Format.js +10 -4
- package/dist/formats/mp4/CjsMp4Format.js.map +1 -1
- package/dist/formats/obj/CjsObjFormat.js +12 -6
- package/dist/formats/obj/CjsObjFormat.js.map +1 -1
- package/dist/formats/ogg/CjsOggFormat.js +9 -3
- package/dist/formats/ogg/CjsOggFormat.js.map +1 -1
- package/dist/formats/png/CjsPngFormat.js +11 -5
- package/dist/formats/png/CjsPngFormat.js.map +1 -1
- package/dist/formats/red/CjsRedFormat.js +19 -5
- package/dist/formats/red/CjsRedFormat.js.map +1 -1
- package/dist/formats/red/core/CjsRedReader.js +63 -70
- package/dist/formats/red/core/CjsRedReader.js.map +1 -1
- package/dist/formats/red/core/helpers.js +3 -0
- package/dist/formats/red/core/helpers.js.map +1 -1
- package/dist/formats/stl/CjsStlFormat.js +77 -16
- package/dist/formats/stl/CjsStlFormat.js.map +1 -1
- package/dist/formats/stl/core/helpers.js +4 -0
- package/dist/formats/stl/core/helpers.js.map +1 -1
- package/dist/formats/stl/core/stl.js +100 -15
- package/dist/formats/stl/core/stl.js.map +1 -1
- package/dist/formats/tga/CjsTgaFormat.js +11 -5
- package/dist/formats/tga/CjsTgaFormat.js.map +1 -1
- package/dist/formats/wav/CjsWavFormat.js +11 -5
- package/dist/formats/wav/CjsWavFormat.js.map +1 -1
- package/dist/formats/webm/CjsWebmFormat.js +10 -4
- package/dist/formats/webm/CjsWebmFormat.js.map +1 -1
- package/dist/formats/webp/CjsWebpFormat.js +9 -3
- package/dist/formats/webp/CjsWebpFormat.js.map +1 -1
- package/dist/formats/wem/CjsWemFormat.js +50 -6
- package/dist/formats/wem/CjsWemFormat.js.map +1 -1
- package/dist/formats/wem/core/helpers.js +84 -3
- package/dist/formats/wem/core/helpers.js.map +1 -1
- package/dist/formats/wem/core/ptadpcm.js +77 -0
- package/dist/formats/wem/core/ptadpcm.js.map +1 -0
- package/dist/formats/wem/core/resolve.js +121 -0
- package/dist/formats/wem/core/resolve.js.map +1 -0
- package/dist/formats/yaml/CjsYamlFormat.js +11 -5
- package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
- package/dist/formats/yaml/core/CjsYamlReader.js +3 -2
- package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
- package/dist/index.js +28 -32
- package/dist/index.js.map +1 -1
- package/dist/{generated/resources → resources}/AudioGeometryResData.js +2 -2
- package/dist/resources/AudioGeometryResData.js.map +1 -0
- package/dist/{generated/resources → resources}/GStateBindingCallbackData.js +2 -2
- package/dist/resources/GStateBindingCallbackData.js.map +1 -0
- package/dist/{generated/resources → resources}/MeshDecalData.js +2 -2
- package/dist/resources/MeshDecalData.js.map +1 -0
- package/dist/{generated/resources → resources}/MeshDecalLodData.js +2 -2
- package/dist/resources/MeshDecalLodData.js.map +1 -0
- package/dist/resources/Tr2GrannyIntersectionResult.js +60 -0
- package/dist/resources/Tr2GrannyIntersectionResult.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2MaterialArea.js +2 -2
- package/dist/resources/Tr2MaterialArea.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2MaterialMesh.js +2 -2
- package/dist/resources/Tr2MaterialMesh.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2MaterialRes.js +2 -2
- package/dist/resources/Tr2MaterialRes.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2ShaderPermutation.js +2 -2
- package/dist/resources/Tr2ShaderPermutation.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TextureLodManager.js +50 -10
- package/dist/resources/Tr2TextureLodManager.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TextureLodUpdateRequest.js +2 -2
- package/dist/resources/Tr2TextureLodUpdateRequest.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePackChannel.js +2 -2
- package/dist/resources/Tr2TexturePackChannel.js.map +1 -0
- package/dist/resources/Tr2TexturePipeline.js +68 -0
- package/dist/resources/Tr2TexturePipeline.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineParams.js +2 -2
- package/dist/resources/Tr2TexturePipelineParams.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepCompress.js +3 -3
- package/dist/resources/Tr2TexturePipelineStepCompress.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepLimitSize.js +2 -2
- package/dist/resources/Tr2TexturePipelineStepLimitSize.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepLoad.js +2 -2
- package/dist/resources/Tr2TexturePipelineStepLoad.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepPack.js +3 -3
- package/dist/resources/Tr2TexturePipelineStepPack.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResAreaData.js +2 -2
- package/dist/resources/TriGeometryResAreaData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResJointData.js +2 -2
- package/dist/resources/TriGeometryResJointData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResLodData.js +2 -2
- package/dist/resources/TriGeometryResLodData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResMeshData.js +2 -2
- package/dist/resources/TriGeometryResMeshData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResSkeletonData.js +2 -2
- package/dist/resources/TriGeometryResSkeletonData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriJointBinding.js +2 -2
- package/dist/resources/TriJointBinding.js.map +1 -0
- package/dist/{generated/resources → resources}/TriMorphTargetGeometryConstants.js +2 -2
- package/dist/resources/TriMorphTargetGeometryConstants.js.map +1 -0
- package/dist/{generated/resources → resources}/TriRtGeometryConstants.js +2 -2
- package/dist/resources/TriRtGeometryConstants.js.map +1 -0
- package/dist/resources/enums.js.map +1 -0
- package/dist/resources/texturePipelineBehavior.js +320 -0
- package/dist/resources/texturePipelineBehavior.js.map +1 -0
- package/format-notices/bnk/NOTICE +7 -4
- package/package.json +51 -51
- package/resource-lifecycle.md +262 -70
- package/dist/generated/resources/AudioGeometryResData.js.map +0 -1
- package/dist/generated/resources/CmfVertexReader.js +0 -46
- package/dist/generated/resources/CmfVertexReader.js.map +0 -1
- package/dist/generated/resources/GStateBindingCallbackData.js.map +0 -1
- package/dist/generated/resources/MeshDecalData.js.map +0 -1
- package/dist/generated/resources/MeshDecalLodData.js.map +0 -1
- package/dist/generated/resources/Tr2AsyncSave.js +0 -46
- package/dist/generated/resources/Tr2AsyncSave.js.map +0 -1
- package/dist/generated/resources/Tr2CmfContents.js +0 -37
- package/dist/generated/resources/Tr2CmfContents.js.map +0 -1
- package/dist/generated/resources/Tr2GrannyIntersectionResult.js +0 -58
- package/dist/generated/resources/Tr2GrannyIntersectionResult.js.map +0 -1
- package/dist/generated/resources/Tr2LoadPrepareFence.js +0 -37
- package/dist/generated/resources/Tr2LoadPrepareFence.js.map +0 -1
- package/dist/generated/resources/Tr2MaterialArea.js.map +0 -1
- package/dist/generated/resources/Tr2MaterialMesh.js.map +0 -1
- package/dist/generated/resources/Tr2MaterialRes.js.map +0 -1
- package/dist/generated/resources/Tr2ShaderPermutation.js.map +0 -1
- package/dist/generated/resources/Tr2TextureLodManager.js.map +0 -1
- package/dist/generated/resources/Tr2TextureLodUpdateRequest.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePackChannel.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipeline.js +0 -44
- package/dist/generated/resources/Tr2TexturePipeline.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineParams.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepCompress.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepLimitSize.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepLoad.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepPack.js.map +0 -1
- package/dist/generated/resources/TriGeometryResAreaData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResJointData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResLodData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResMeshData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResSkeletonData.js.map +0 -1
- package/dist/generated/resources/TriJointBinding.js.map +0 -1
- package/dist/generated/resources/TriMorphTargetGeometryConstants.js.map +0 -1
- package/dist/generated/resources/TriRtGeometryConstants.js.map +0 -1
- package/dist/generated/resources/enums.js.map +0 -1
- package/dist/generated/resources/index.js +0 -32
- package/dist/generated/resources/index.js.map +0 -1
- /package/dist/{generated/resources → resources}/enums.js +0 -0
package/README.md
CHANGED
|
@@ -1,241 +1,537 @@
|
|
|
1
|
-
# @carbonenginejs/runtime-resource
|
|
2
|
-
|
|
3
|
-
CarbonEngineJS resource lifecycle, cache, format selection, source, and object
|
|
4
|
-
loading contracts.
|
|
5
|
-
|
|
6
|
-
This package owns the GPU-free resource layer:
|
|
7
|
-
|
|
8
|
-
- `CjsResource` state and Carbon-style resource methods.
|
|
9
|
-
- `CjsTextureArrayRes` and `CjsTextureParameterProxy` for material-facing,
|
|
10
|
-
frame-coalesced texture-array inputs without changing ordinary texture
|
|
11
|
-
parameter behavior.
|
|
12
|
-
- `CjsMotherLode`
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
source
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
1
|
+
# @carbonenginejs/runtime-resource
|
|
2
|
+
|
|
3
|
+
CarbonEngineJS resource lifecycle, cache, format selection, source, and object
|
|
4
|
+
loading contracts.
|
|
5
|
+
|
|
6
|
+
This package owns the GPU-free resource layer:
|
|
7
|
+
|
|
8
|
+
- `CjsResource` state and Carbon-style resource methods.
|
|
9
|
+
- `CjsTextureArrayRes` and `CjsTextureParameterProxy` for material-facing,
|
|
10
|
+
frame-coalesced texture-array inputs without changing ordinary texture
|
|
11
|
+
parameter behavior.
|
|
12
|
+
- `CjsMotherLode` canonical identity, explicit replacement results, activity
|
|
13
|
+
and lock metadata, deterministic payload/adapter cleanup, and cache stats.
|
|
14
|
+
- `CjsResMan` semantic resource construction, registered-format selection,
|
|
15
|
+
concurrency-limited source loading, staged prepare queues, layered
|
|
16
|
+
source/read/resource deduplication, object loader dispatch, and prefetch.
|
|
17
|
+
- Raw `CjsEventEmitter` from `core-types/model` for manager/runtime events
|
|
18
|
+
without requiring `CjsModel` inheritance. External listeners unregister
|
|
19
|
+
directly with `OffEvent`; listener scopes, owner-side `ListenTo` helpers,
|
|
20
|
+
and a separate resource notification layer are not part of the contract.
|
|
21
|
+
- Path normalization and extension helpers.
|
|
22
|
+
- Source adapters for memory and `fetch`.
|
|
23
|
+
- Plain reader/converter payload objects with focused shared validators.
|
|
24
|
+
- Canonical Carbon resource classes that validate and hold CPU payloads
|
|
25
|
+
privately:
|
|
26
|
+
`TriTextureRes`, `TriGeometryRes`, `Tr2EffectRes`, `Tr2ImageRes`,
|
|
27
|
+
`TriGrannyRes`, `Tr2GrannyStateRes`, and `Tr2LightProfileRes`.
|
|
28
|
+
- `Tr2TexturePipeline` for Carbon-shaped CPU-only load, limit-size, compress
|
|
29
|
+
validation, and channel-pack steps, plus `Tr2TextureLodManager` for explicit
|
|
30
|
+
texture-resource membership without device-memory policy.
|
|
31
|
+
- Opaque engine-owned subobject slots for backend adapters.
|
|
32
|
+
- Format policy, format class contracts, and load/prepare state mapping stay
|
|
33
|
+
inside this package's implementation and public API rather than external
|
|
34
|
+
workspace notes.
|
|
35
|
+
- Non-shader format implementations are owned as explicit tree-shakeable
|
|
36
|
+
subpaths under `@carbonenginejs/runtime-resource/formats/<name>`.
|
|
37
|
+
|
|
38
|
+
It intentionally does not own WebGL/WebGPU realization. Engine packages should adapt prepared resources into backend objects.
|
|
39
|
+
|
|
40
|
+
Authoring source is decorated JavaScript. Published/consumer output is built ESM in `npm/dist`.
|
|
41
|
+
|
|
42
|
+
Completed Carbon data classes live with maintained source under
|
|
43
|
+
`src/resources`; `src/generated` is reserved for unresolved active ports and is
|
|
44
|
+
currently absent. Native shapes that JavaScript replaces or does not use are
|
|
45
|
+
retained only under `src/dropped`, with their disposition documented there,
|
|
46
|
+
and are never exported or bundled.
|
|
47
|
+
|
|
48
|
+
## Package relationships
|
|
49
|
+
|
|
50
|
+
- `runtime-core` may configure and expose a `CjsResMan`, but does not own its
|
|
51
|
+
implementation.
|
|
52
|
+
- `runtime-trinity` and `runtime-sof` may request GPU-free objects and resources
|
|
53
|
+
without selecting an engine.
|
|
54
|
+
- `engine-webgpu` and future WebGL engines consume loaded resources and own all
|
|
55
|
+
backend allocations, preparation, replacement, and destruction.
|
|
56
|
+
|
|
57
|
+
Concrete formats are not imported or registered by the package root:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
import { CjsResMan } from "@carbonenginejs/runtime-resource";
|
|
61
|
+
import { CjsMp4Format } from "@carbonenginejs/runtime-resource/formats/mp4";
|
|
62
|
+
|
|
63
|
+
const resMan = new CjsResMan().Register({
|
|
64
|
+
source,
|
|
65
|
+
formats: [ CjsMp4Format ]
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const resource = resMan.GetResource("res:/video/intro.mp4");
|
|
69
|
+
const video = await resource.Ready();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Formats return plain payload objects. Semantic resource classes apply them
|
|
73
|
+
through `SetPayload()`, validate their own required fields, and throw
|
|
74
|
+
`CJS_RESOURCE_PAYLOAD_INVALID` before replacing a previously valid payload.
|
|
75
|
+
`GetPayload()`, `HasPayload()`, and `ReleasePayload()` manage transient CPU
|
|
76
|
+
retention without introducing a parallel DTO class hierarchy.
|
|
77
|
+
|
|
78
|
+
Red payload output reserves configurable type, ID, reference, and sequence
|
|
79
|
+
values markers (`_type`, `_id`, `_reference`, and `_values` by default).
|
|
80
|
+
Repeated or cyclic sequences use an ID-bearing values envelope; unique
|
|
81
|
+
sequences remain arrays. Authored fields may not collide with active markers,
|
|
82
|
+
so remap the marker options when those names are real data. Disabling the
|
|
83
|
+
reference marker preserves actual JavaScript identity; cyclic output in that
|
|
84
|
+
mode is intentionally not JSON-serializable.
|
|
85
|
+
|
|
86
|
+
## Texture CPU pipeline and LOD membership
|
|
87
|
+
|
|
88
|
+
`Tr2TexturePipeline` is the Carbon texture-specific CPU bitmap pipeline, not a
|
|
89
|
+
general resource prepare stage. `GetResourceDependencies()` returns the sorted
|
|
90
|
+
unique paths required by load and channel-pack steps. `Execute()` resolves
|
|
91
|
+
those inputs from an explicit `inputs` map/object, an async `load(path)`
|
|
92
|
+
callback, or an injected `CjsResMan`, then returns a canonical plain
|
|
93
|
+
`rgba8unorm` payload:
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
import {
|
|
97
|
+
Tr2TexturePipeline,
|
|
98
|
+
Tr2TexturePipelineStepLoad,
|
|
99
|
+
Tr2TexturePipelineStepLimitSize
|
|
100
|
+
} from "@carbonenginejs/runtime-resource";
|
|
101
|
+
|
|
102
|
+
const load = new Tr2TexturePipelineStepLoad();
|
|
103
|
+
load.path = "res:/texture/source.png";
|
|
104
|
+
const limit = new Tr2TexturePipelineStepLimitSize();
|
|
105
|
+
limit.maxWidth = 512;
|
|
106
|
+
|
|
107
|
+
const pipeline = new Tr2TexturePipeline();
|
|
108
|
+
pipeline.steps = [ load, limit ];
|
|
109
|
+
const rgba = await pipeline.Execute(0, 0, { resMan });
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The maintained runtime path currently accepts canonical `rgba8unorm` inputs.
|
|
113
|
+
Load copies the source bitmap, limit-size repeatedly performs a 2x2 CPU
|
|
114
|
+
downsample, pack builds logical RGBA channels from independent inputs, and
|
|
115
|
+
Carbon's present compress step remains validation-only because the native
|
|
116
|
+
method is itself a no-op. Unsupported step types fail explicitly.
|
|
117
|
+
|
|
118
|
+
`Tr2TextureLodManager` owns only ordered resource membership through
|
|
119
|
+
`RegisterTexture()`, `UnregisterTexture()`, and `GetManagedTextures()`. Engine
|
|
120
|
+
packages continue to own GPU allocations, upload accounting, device budgets,
|
|
121
|
+
capability limits, and device-loss recovery.
|
|
122
|
+
|
|
123
|
+
## Wwise soundbanks and media
|
|
124
|
+
|
|
125
|
+
`formats/bnk` and `formats/wem` cover the Wwise audio pipeline end to end.
|
|
126
|
+
`CjsBnkFormat.inspect()` decodes the chunk map, embedded media index, bank
|
|
127
|
+
names, and the HIRC listing with version-stable typed fields (event action
|
|
128
|
+
lists, action type/target, sound and music-track source ids; pinned against
|
|
129
|
+
bank generator version 150). The Wwise-domain toolkit is grouped under the
|
|
130
|
+
`CjsBnkFormat.wwise` static: the SoundbanksInfo catalog helpers, the FNV-1
|
|
131
|
+
id hash, and event → media resolution:
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
import { CjsBnkFormat } from "@carbonenginejs/runtime-resource/formats/bnk";
|
|
135
|
+
import { CjsWemFormat } from "@carbonenginejs/runtime-resource/formats/wem";
|
|
136
|
+
|
|
137
|
+
const inspections = bankByteArrays.map(bytes => CjsBnkFormat.inspect(bytes));
|
|
138
|
+
const { eventMedia } = CjsBnkFormat.wwise.eventMediaFromBanks(inspections);
|
|
139
|
+
// eventMedia: Map<eventObjectId, Set<wemId>> - banks may split events from
|
|
140
|
+
// their target sounds, so pass every related bank to one call.
|
|
141
|
+
|
|
142
|
+
const ogg = CjsWemFormat.toOgg(wemBytes); // Wwise Vorbis -> Ogg (lossless)
|
|
143
|
+
const pcm = CjsWemFormat.toPcm(wemBytes); // PTADPCM / 16-bit PCM -> float32
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The read/inspect path stays a pure container reader; `wwise.eventMediaFromBanks`
|
|
147
|
+
is graph interpretation offered for consumers with their own engines — the
|
|
148
|
+
resource lifecycle never calls it.
|
|
149
|
+
|
|
150
|
+
## STL export
|
|
151
|
+
|
|
152
|
+
`CjsStlFormat` writes shared geometry directly to binary or ASCII STL. The
|
|
153
|
+
writer consumes `mesh.vertex.position` and triangular `mesh.indices[].faces`;
|
|
154
|
+
multiple meshes and index groups are flattened in encounter order because STL
|
|
155
|
+
does not carry portable scene, material, skin, or animation structure.
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
import { CjsStlFormat } from "@carbonenginejs/runtime-resource/formats/stl";
|
|
159
|
+
|
|
160
|
+
const bytes = CjsStlFormat.write(sharedGeometry, {
|
|
161
|
+
binary: true,
|
|
162
|
+
solidName: "ship_hull",
|
|
163
|
+
scale: 1000,
|
|
164
|
+
requireWatertight: true
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Writes do not mutate the shared input. Facet normals are recalculated from
|
|
169
|
+
winding by default; set `recalculateNormals: false` to average valid vertex
|
|
170
|
+
normals. Degenerate triangles are skipped by default. Index values must be safe
|
|
171
|
+
integers within the position channel, and binary output rejects coordinates
|
|
172
|
+
outside float32 range instead of silently emitting infinities. The
|
|
173
|
+
`requireWatertight` option rejects open, non-manifold, inconsistently wound, or
|
|
174
|
+
degenerate output.
|
|
175
|
+
|
|
176
|
+
## MotherLode ownership
|
|
177
|
+
|
|
178
|
+
`CjsResMan` resolves each normalized path and promised output to one canonical
|
|
179
|
+
MotherLode key. `Insert(key, resource, options)` reports `{ inserted, replaced,
|
|
180
|
+
displaced }`; replacement, deletion, clearing, and shutdown destroy attached
|
|
181
|
+
adapter allocations and release the complete CPU payload by default. Callers
|
|
182
|
+
that deliberately retain ownership may pass `{ cleanup: false }` and keep the
|
|
183
|
+
returned displaced resource. If replacement cleanup fails, insertion throws a
|
|
184
|
+
contextual error and leaves the existing owner registered. These ordinary
|
|
185
|
+
ownership removals preserve the handle's last resource state; `PURGED` is
|
|
186
|
+
reserved for successful policy eviction through inactivity or byte pressure.
|
|
187
|
+
|
|
188
|
+
Canonical resource identity is the normalized source path plus its promised
|
|
189
|
+
output tag. `variant` is the explicit tag; otherwise `emit`, `requirement`, or
|
|
190
|
+
`payload` supplies it. Human-readable identities are written as
|
|
191
|
+
`res:/ship.gr2@cmf`, although MotherLode uses an internal delimiter. Reader,
|
|
192
|
+
constructor, and format-option implementations never enter the key. CjsLibrary
|
|
193
|
+
chooses the promised output and ResMan executes the current setup-time format
|
|
194
|
+
registration for it.
|
|
195
|
+
|
|
196
|
+
Output selection is case-insensitive for identity and matching, but format
|
|
197
|
+
readers receive the canonical declared spelling (for example `cmfJson`). A
|
|
198
|
+
legacy direct object loader exposes only its unforced default; named output
|
|
199
|
+
variants belong on a format class. Unsupported `@output` requests fail before
|
|
200
|
+
cache lookup, so a resident handle cannot bypass the declaration.
|
|
201
|
+
|
|
202
|
+
A released CPU payload retains only the small request needed to reconstruct
|
|
203
|
+
that same path/output from its source and `sourceRevision`. The retained
|
|
204
|
+
promised-output fields and source provenance win over later
|
|
205
|
+
`Ready()`/`GetObject()` overrides, while cache/reload policy remains per-call.
|
|
206
|
+
Payload leases protect active consumers; an engine may release its own backend
|
|
207
|
+
adapter without destroying shared CPU data. Change setup-time registrations
|
|
208
|
+
only with an explicit resource reset (`Delete`/`Clear`) or a new manager. A
|
|
209
|
+
changed output contract must use a new tag such as `@cmf2`.
|
|
210
|
+
|
|
211
|
+
`Startup()` and `Shutdown()` are idempotent. `HasKey`, `Lookup`, `Delete`,
|
|
212
|
+
`GetKeys`, `GetValues`, `GetSize`, `SetCacheSize`, `GetCacheSize`, `GetStats`,
|
|
213
|
+
`TrimCache`, `ReplaceExpected`, `Clear`, and `ClearCached` provide the
|
|
214
|
+
Carbon-shaped cache vocabulary plus the exact-owner compare-and-swap required
|
|
215
|
+
by staged JavaScript reload. The old `Has`, `GetCount`, and `DeleteAll` names
|
|
216
|
+
remain temporary compatibility aliases.
|
|
217
|
+
|
|
218
|
+
Byte budgeting applies only to records explicitly admitted with
|
|
219
|
+
`{ cached: true, bytes }`; JavaScript reachability is never inferred. The byte
|
|
220
|
+
value is a caller-supplied safe-integer eviction weight, not a heuristic walk of
|
|
221
|
+
the resource graph. `TrimCache()` removes positive-byte cached identities in
|
|
222
|
+
oldest-admission order until `cacheBytes <= cacheSize`. Live, locked,
|
|
223
|
+
`cacheable: false`, and zero-byte entries do not create pressure. With default
|
|
224
|
+
cleanup, successful pressure eviction performs the same deterministic
|
|
225
|
+
payload/adapter cleanup as inactivity eviction and marks detached compatible
|
|
226
|
+
handles `PURGED`.
|
|
227
|
+
|
|
228
|
+
`SetCacheSize()` installs and immediately enforces a new budget. `Update()` and
|
|
229
|
+
`Tick()` retry cache housekeeping after pumping queues; `{ cache: false }`
|
|
230
|
+
skips it for one update. Cleanup failure leaves that candidate canonical,
|
|
231
|
+
continues through later candidates, and throws
|
|
232
|
+
`CJS_MOTHERLODE_CACHE_TRIM_FAILED` with a partial result.
|
|
233
|
+
|
|
234
|
+
`CjsResMan` binds resource-facing `KeepAlive`, `KeepPayloadAlive`, `Lock`, and
|
|
235
|
+
`Unlock` operations to the canonical key. Publishing a non-null payload renews
|
|
236
|
+
its independent lease; `GetPayload()`, `HasPayload()`, `IsGood()`, and other
|
|
237
|
+
queries remain pure. `PurgeInactive(options)` performs an explicit deterministic
|
|
238
|
+
sweep using independent identity and payload frame/time limits. Locks skip both
|
|
239
|
+
forms of eviction. Identity expiry cleans adapters and payloads, detaches the
|
|
240
|
+
handle, marks it `PURGED`, and removes it; payload expiry releases only the CPU
|
|
241
|
+
payload. A sweep never fetches, prepares, or reloads a resource.
|
|
242
|
+
|
|
243
|
+
Generic/base reader results participate in the same payload ownership: the
|
|
244
|
+
manager stores the complete result through `SetPayload()` and mirrors it on the
|
|
245
|
+
compatibility `object` property. Payload release clears that alias only while
|
|
246
|
+
it still identifies the released value. Concurrent object/readiness calls
|
|
247
|
+
share only their in-flight operation; settled promises are removed so evicted
|
|
248
|
+
graphs are collectible and failed operations can be explicitly retried. A
|
|
249
|
+
resident payload returns without rereading, while a released payload is rebuilt
|
|
250
|
+
only by an explicit `GetObject()` or `Ready()` call.
|
|
251
|
+
|
|
252
|
+
Source and parsed-format caches use explicit provenance. `sourceRevision` is an
|
|
253
|
+
opaque caller/source-supplied string or finite number identifying source
|
|
254
|
+
content for one source object and normalized path. It scopes read caches only;
|
|
255
|
+
it does not alter MotherLode resource identity, and changing it does not replace a
|
|
256
|
+
resident payload without `reload: true`.
|
|
257
|
+
|
|
258
|
+
`cacheSource` and `cacheFormat` are tri-state per-call policies:
|
|
259
|
+
|
|
260
|
+
- omitted: share in-flight or explicitly retained work, then drop a newly
|
|
261
|
+
completed record;
|
|
262
|
+
- `true`: share and retain success; a joining caller upgrades the record;
|
|
263
|
+
- `false`: bypass sharing and retention.
|
|
264
|
+
|
|
265
|
+
Failures are never retained. Format records are additionally isolated by
|
|
266
|
+
selected source object, frozen registration descriptor, revision, and effective
|
|
267
|
+
format options. Re-registering a format with new defaults therefore cannot
|
|
268
|
+
reuse an old descriptor's parse. Registered defaults are copied into deeply
|
|
269
|
+
frozen plain-object/array snapshots. Material format options that cannot be
|
|
270
|
+
represented safely (for example class instances with hidden mutable state)
|
|
271
|
+
bypass format-cache sharing instead of risking a false match; functions and
|
|
272
|
+
byte views use cache-local identity plus visible byte content where applicable.
|
|
273
|
+
|
|
274
|
+
`reload: true` synchronously detaches every queued/source/format read record for
|
|
275
|
+
the selected source/path before fresh work starts. Existing consumers keep
|
|
276
|
+
their detached promises; reload does not abort them. Fresh success repopulates
|
|
277
|
+
only caches explicitly requested with `cacheSource: true` or
|
|
278
|
+
`cacheFormat: true`. `InvalidateReadCache(path, { source, sourceRevision })`
|
|
279
|
+
provides the same no-abort invalidation explicitly; omitting `sourceRevision`
|
|
280
|
+
removes all revisions for that source/path. `Delete()` remains canonical
|
|
281
|
+
resource-identity-only, while `Clear()` resets all read ledgers.
|
|
282
|
+
|
|
283
|
+
A resource loader retains the effective selected source and `sourceRevision`
|
|
284
|
+
for reconstruction, including the manager default selected at creation, but
|
|
285
|
+
not cache flags or one-shot reload.
|
|
286
|
+
|
|
287
|
+
Reload is candidate-first. When an owner already exists,
|
|
288
|
+
`GetResource(path, { reload: true })` returns a distinct off-registry candidate
|
|
289
|
+
without changing ordinary lookup. `Ready()` on that candidate, `GetObject()` /
|
|
290
|
+
`FetchResource()` with `reload: true`, and the explicit `ReloadObject()` /
|
|
291
|
+
`ReloadResource()` helpers all run the same queued contract:
|
|
292
|
+
|
|
293
|
+
1. purge-lock the exact former owner and invalidate reusable reads once;
|
|
294
|
+
2. read, convert through the selected format, and publish payload state only on the detached candidate;
|
|
295
|
+
3. require the newest per-key reload token and exact former ownership;
|
|
296
|
+
4. compare-and-swap the fully loaded CPU candidate into MotherLode;
|
|
297
|
+
5. invalidate and clean the displaced handle after the lookup switch.
|
|
298
|
+
|
|
299
|
+
Source, format, or publication failure therefore leaves the former handle, state,
|
|
300
|
+
payload, and adapters canonical; the failed candidate's attached payload and
|
|
301
|
+
adapters are cleaned and its original error is retained. An otherwise-
|
|
302
|
+
successful candidate that was superseded, deleted, cleared, or replaced rejects
|
|
303
|
+
with `CJS_RESMAN_STALE_RELOAD_CANDIDATE` and cannot resurrect the key. Failed
|
|
304
|
+
freshness attempts still invalidate reusable source/format records when their
|
|
305
|
+
work begins; the already-published canonical payload is not dependent on those
|
|
306
|
+
records. If displaced-owner cleanup fails after the swap,
|
|
307
|
+
the promise rejects with `CJS_MOTHERLODE_REPLACE_CLEANUP_FAILED`, whose result
|
|
308
|
+
explicitly reports `committed: true`; the good candidate remains canonical.
|
|
309
|
+
|
|
310
|
+
This deliberately differs from Carbon's `BlueAsyncRes::Reload`, which reloads
|
|
311
|
+
one stable handle in place and releases its old data before success. Existing
|
|
312
|
+
JavaScript references likewise are never silently retargeted: they keep the
|
|
313
|
+
displaced handle, while fresh lookup sees the committed candidate.
|
|
314
|
+
|
|
315
|
+
Every queued, direct, standalone, and candidate resource preparation captures the exact
|
|
316
|
+
MotherLode, canonical key, resource handle, and manager-local ownership
|
|
317
|
+
generation. Delete, Clear, reload replacement, or handle reinsertion makes old
|
|
318
|
+
work stale before it can enter another state or publish. Otherwise-
|
|
319
|
+
successful obsolete work rejects with `CJS_RESMAN_STALE_RESOURCE_OPERATION`;
|
|
320
|
+
an obsolete source/format failure preserves its original rejection while
|
|
321
|
+
suppressing `SetError()` on the detached handle.
|
|
322
|
+
|
|
323
|
+
Candidate work is a normal `Wait()` root and blocks synchronous MotherLode
|
|
324
|
+
replacement while active. MotherLode replacement otherwise remains synchronous
|
|
325
|
+
configuration and rejects with
|
|
326
|
+
`CJS_RESMAN_ACTIVE_RESOURCE_OPERATIONS` while queued or direct mutations are
|
|
327
|
+
active. `Wait()` drains queued roots; callers must separately await direct load
|
|
328
|
+
or direct prepare promises before retrying replacement. Started source or
|
|
329
|
+
format work is not yet aborted; deterministic cleanup applies to the staged
|
|
330
|
+
candidate resource itself.
|
|
331
|
+
|
|
332
|
+
Automatic scheduling is available only when a caller supplies
|
|
333
|
+
`autoPurgePolicy` to the constructor/`Register()` or calls
|
|
334
|
+
`SetAutoPurgePolicy()`. It is disabled by default and deliberately accepts only
|
|
335
|
+
millisecond limits: MotherLode activity frames count explicit observations and
|
|
336
|
+
are not renderer frames. `Update()`/`Tick()` run a due sweep after queue pumps;
|
|
337
|
+
`{ purge: false }` skips it for one call. The first pump after configuration is
|
|
338
|
+
due immediately, then `intervalMilliseconds` limits cadence. Manager-owned
|
|
339
|
+
queued and direct resource work holds a balanced purge lock until completion.
|
|
340
|
+
|
|
341
|
+
```js
|
|
342
|
+
const resMan = new CjsResMan({
|
|
343
|
+
source,
|
|
344
|
+
autoPurgePolicy: {
|
|
345
|
+
intervalMilliseconds: 1000,
|
|
346
|
+
maxIdleMilliseconds: 60_000,
|
|
347
|
+
payloadMaxIdleMilliseconds: 10_000
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
resMan.Update();
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Cache trimming and automatic inactivity sweeps retain the strict no-reload
|
|
355
|
+
rule. Application retention defaults, automatic resource/payload byte
|
|
356
|
+
estimation, separate CPU/adapter budgets, and purged-resource/device-loss
|
|
357
|
+
recovery policy remain later work.
|
|
358
|
+
|
|
359
|
+
## Queued CPU load and publication
|
|
360
|
+
|
|
361
|
+
`GetObject()`, `LoadObject()`, and resource `Ready()` use two manager-owned
|
|
362
|
+
queues:
|
|
363
|
+
|
|
364
|
+
```text
|
|
365
|
+
BACKGROUND: deduplicated source load, limited by maxConcurrentLoads
|
|
366
|
+
MAIN: reader/format conversion -> resource publication
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
The main reader/format operation and publication are separate queue items.
|
|
370
|
+
`maxPrepareTime` is a per-pump budget in seconds, and
|
|
371
|
+
`maxPrepareItemsPerTick` can add an item-count limit. The default scheduler
|
|
372
|
+
keeps promise-based calls working; a `CjsLibrary` or direct caller can provide
|
|
373
|
+
its frame scheduler:
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
const resMan = new CjsResMan({
|
|
377
|
+
source,
|
|
378
|
+
maxConcurrentLoads: 8,
|
|
379
|
+
maxPrepareTime: 0.005,
|
|
380
|
+
queueScheduler: callback => requestAnimationFrame(callback)
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
await resMan.FetchResource("res:/model/ship.gr2", {
|
|
384
|
+
requirement: "geometry",
|
|
385
|
+
emit: "cmf"
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
The selected format class owns conversion to the promised CPU output.
|
|
390
|
+
`CjsResMan` does not inspect WebGL, WebGPU, texture, geometry, or codec support,
|
|
391
|
+
and it does not run backend realization. An engine consumes the published CPU
|
|
392
|
+
resource afterward through its own explicit operation.
|
|
393
|
+
|
|
394
|
+
Blue-compatible queue controls are exposed directly on `CjsResMan`:
|
|
395
|
+
`AddToQueue`, `CancelFromQueue`, `GetNextIdForQueue`,
|
|
396
|
+
`PumpMainThreadQueue`, `PauseQueue`, `ResumeQueue`, `GetPendingLoads`, and
|
|
397
|
+
`GetPendingPrepares`. `Update()`/`Tick()` pump work. `Wait()` synchronously
|
|
398
|
+
captures queued resource-operation roots and low-level queue tasks that already
|
|
399
|
+
exist when it is called. Captured resource roots include publication work
|
|
400
|
+
enqueued after an asynchronous read; unrelated later roots/tasks do not
|
|
401
|
+
postpone the fence. Failure and queued cancellation count as settlement and remain
|
|
402
|
+
observable through their original operation promises.
|
|
403
|
+
|
|
404
|
+
By default `Wait()` pumps the two queues directly within their ordinary budgets
|
|
405
|
+
and never runs automatic purge housekeeping. It preserves pause state;
|
|
406
|
+
`{ pump: false }` leaves all progress to an external driver. A standalone
|
|
407
|
+
canonical `PrepareResourceObjectQueued()` call is a queued root. Direct
|
|
408
|
+
`LoadResourceObject()`, direct `PrepareResourceObject()`, standalone
|
|
409
|
+
`ReadResource()`, and standalone `ReadFormatOnce()` calls bypass both queues
|
|
410
|
+
and are outside this fence unless they own a captured queue task, although
|
|
411
|
+
direct resource mutations are still tracked for safe MotherLode replacement.
|
|
412
|
+
`WaitUrgent()` remains deferred until the queue has real per-item priority and
|
|
413
|
+
urgent-membership semantics.
|
|
414
|
+
|
|
415
|
+
Format classes own input extensions. Resource classes are registered by a
|
|
416
|
+
semantic requirement, never by file extension:
|
|
417
|
+
|
|
418
|
+
```js
|
|
419
|
+
const resMan = new CjsResMan().Register({
|
|
420
|
+
source,
|
|
421
|
+
formats: [ CjsDdsFormat, CjsPngFormat ],
|
|
422
|
+
resourceTypes: [ TriTextureRes, Tr2ImageRes ]
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
const texture = resMan.GetResource("res:/image/ship.png", {
|
|
426
|
+
requirement: "texture",
|
|
427
|
+
emit: "image"
|
|
428
|
+
});
|
|
429
|
+
const image = resMan.GetResource("res:/image/ship.png", {
|
|
430
|
+
requirement: "image",
|
|
431
|
+
emit: "image"
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Those are distinct resource identities but share the normalized source-byte
|
|
436
|
+
operation. The manager does not expose an extension-to-resource compatibility
|
|
437
|
+
registry.
|
|
438
|
+
|
|
439
|
+
Texture-array resources expose one ordinary-looking proxy per ordered layer:
|
|
440
|
+
|
|
441
|
+
```js
|
|
442
|
+
const textureArray = new CjsTextureArrayRes({
|
|
443
|
+
paths: [
|
|
444
|
+
"res:/detail1.dds",
|
|
445
|
+
"res:/detail2.dds",
|
|
446
|
+
"res:/detail3.dds"
|
|
447
|
+
],
|
|
448
|
+
layerNames: [ "Detail1Map", "Detail2Map", "Detail3Map" ],
|
|
449
|
+
updateScheduler: resource => frameQueue.add(resource)
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
const detail2 = textureArray.GetLayerParameter(1);
|
|
453
|
+
detail2.SetValue("res:/replacement.dds");
|
|
454
|
+
|
|
455
|
+
detail2.textureRes === textureArray; // true
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Proxy setters only update their source path and invalidate the parent. The
|
|
459
|
+
parent is scheduled once even if several proxies change in the same frame.
|
|
460
|
+
The next-frame consumer calls `Update()` or `ConsumeUpdateRequest()` to obtain
|
|
461
|
+
one immutable ordered snapshot. Runtime-resource does not know which shader
|
|
462
|
+
metadata caused the aggregate request; shader packages and engine adapters map
|
|
463
|
+
public parameter names to layer indices.
|
|
464
|
+
|
|
465
|
+
Public effect parameters remain separate from these internal proxies. Their
|
|
466
|
+
authored paths and individual 2D source resources are not replaced by the
|
|
467
|
+
aggregate. An engine-owned, non-persisted bridge mirrors public changes into
|
|
468
|
+
the fixed internal layers.
|
|
469
|
+
|
|
470
|
+
Consumed snapshots are explicit in-flight generations. An adapter either
|
|
471
|
+
publishes the current candidate atomically, requeues retryable work, or records
|
|
472
|
+
failure:
|
|
473
|
+
|
|
474
|
+
```js
|
|
475
|
+
const request = textureArray.ConsumeUpdateRequest();
|
|
476
|
+
|
|
477
|
+
try {
|
|
478
|
+
const candidate = await adapter.PrepareTextureArray(request);
|
|
479
|
+
const result = textureArray.CommitPreparedAdapterRevision(
|
|
480
|
+
request.revision,
|
|
481
|
+
"webgpu",
|
|
482
|
+
candidate
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
// A rejected/stale candidate is destroyed by the commit method by default.
|
|
486
|
+
// The adapter owns disposal of a successfully displaced allocation.
|
|
487
|
+
result.displaced?.destroy();
|
|
488
|
+
} catch (error) {
|
|
489
|
+
textureArray.FailUpdateRequest(request.revision, error, { retry: true });
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
await textureArray.Ready(); // the generation requested at call time
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
`SetLayerResource()` attaches a resolved source without rewriting the logical
|
|
496
|
+
requested path. `TouchLayer()` invalidates an in-place source revision.
|
|
497
|
+
`RetryUpdateRequest()` restores consumed work, and `HandleAdapterLoss()` drops
|
|
498
|
+
an unusable adapter allocation and schedules a complete topology rebuild.
|
|
499
|
+
Topology-changing snapshots set `topologyChanged: true` and report only valid
|
|
500
|
+
current layer indices in `dirtyLayers`.
|
|
501
|
+
|
|
502
|
+
## Development
|
|
503
|
+
|
|
504
|
+
Install dependencies and run the non-interactive baseline checks from the
|
|
505
|
+
repository root:
|
|
506
|
+
|
|
507
|
+
```sh
|
|
508
|
+
npm install
|
|
509
|
+
npm run lint
|
|
510
|
+
npm run check
|
|
511
|
+
npm test
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
`npm run check` builds the consumer package and proves that decorator metadata
|
|
515
|
+
matches between authoring source and built output. `npm test` additionally runs
|
|
516
|
+
the complete GPU-free unit suite; it requires no private assets, credentials,
|
|
517
|
+
network access, browser, or GPU after dependencies are installed.
|
|
518
|
+
|
|
519
|
+
See [Runtime Resource Lifecycle](resource-lifecycle.md) for state, retention,
|
|
520
|
+
and texture-array generation contracts. See
|
|
521
|
+
[Format ownership and fork provenance](FORMAT-PROVENANCE.md) for copied-reader
|
|
522
|
+
ownership, licenses, exclusions, and the deferred GR2 migration. Both documents
|
|
523
|
+
ship with the published package.
|
|
524
|
+
|
|
525
|
+
## Provenance
|
|
526
|
+
|
|
527
|
+
CarbonEngine and Fenris Creations (CCP Games) are named for interoperability
|
|
528
|
+
and provenance context. This package contains CarbonEngineJS original resource
|
|
529
|
+
infrastructure, CarbonEngine-shaped resource ports, and maintained copies of
|
|
530
|
+
the non-shader readers identified in `FORMAT-PROVENANCE.md`. It does not copy
|
|
531
|
+
Fenris Creations game assets, proprietary documentation, or shader source.
|
|
532
|
+
CarbonEngine and historical JavaScript implementations were used as the
|
|
533
|
+
behavioral references described in the package notices.
|
|
534
|
+
|
|
535
|
+
This project is not affiliated with, endorsed by, or sponsored by CCP Games or
|
|
536
|
+
CCP ehf. EVE Online and related marks remain the property of their respective
|
|
537
|
+
owners.
|