@kurot/core 2.1.1 → 2.2.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/CHANGELOG.md +41 -0
- package/README.md +37 -2
- package/dist/kurot/display/DisplayObject.d.ts +2 -1
- package/dist/kurot/display/DisplayObject.d.ts.map +1 -1
- package/dist/kurot/display/DisplayObject.js.map +1 -1
- package/dist/kurot/player/canvas/CanvasRenderer.d.ts +2 -0
- package/dist/kurot/player/canvas/CanvasRenderer.d.ts.map +1 -1
- package/dist/kurot/player/canvas/CanvasRenderer.js +37 -1
- package/dist/kurot/player/canvas/CanvasRenderer.js.map +1 -1
- package/dist/kurot/player/pipes/BitmapTextPipe.d.ts +20 -0
- package/dist/kurot/player/pipes/BitmapTextPipe.d.ts.map +1 -0
- package/dist/kurot/player/pipes/BitmapTextPipe.js +27 -0
- package/dist/kurot/player/pipes/BitmapTextPipe.js.map +1 -0
- package/dist/kurot/player/pipes/index.d.ts +2 -0
- package/dist/kurot/player/pipes/index.d.ts.map +1 -1
- package/dist/kurot/player/pipes/index.js +1 -0
- package/dist/kurot/player/pipes/index.js.map +1 -1
- package/dist/kurot/player/webgl/WebGLRenderer.d.ts +1 -0
- package/dist/kurot/player/webgl/WebGLRenderer.d.ts.map +1 -1
- package/dist/kurot/player/webgl/WebGLRenderer.js +8 -0
- package/dist/kurot/player/webgl/WebGLRenderer.js.map +1 -1
- package/dist/kurot/resource/Resource.d.ts.map +1 -1
- package/dist/kurot/resource/Resource.js +4 -0
- package/dist/kurot/resource/Resource.js.map +1 -1
- package/dist/kurot/resource/ResourceItem.d.ts +1 -0
- package/dist/kurot/resource/ResourceItem.d.ts.map +1 -1
- package/dist/kurot/resource/ResourceItem.js +1 -0
- package/dist/kurot/resource/ResourceItem.js.map +1 -1
- package/dist/kurot/resource/analyzers/FontAnalyzer.d.ts +16 -0
- package/dist/kurot/resource/analyzers/FontAnalyzer.d.ts.map +1 -0
- package/dist/kurot/resource/analyzers/FontAnalyzer.js +75 -0
- package/dist/kurot/resource/analyzers/FontAnalyzer.js.map +1 -0
- package/dist/kurot/resource/analyzers/index.d.ts +1 -0
- package/dist/kurot/resource/analyzers/index.d.ts.map +1 -1
- package/dist/kurot/resource/analyzers/index.js +1 -0
- package/dist/kurot/resource/analyzers/index.js.map +1 -1
- package/dist/kurot/resource/index.d.ts +1 -0
- package/dist/kurot/resource/index.d.ts.map +1 -1
- package/dist/kurot/resource/index.js +1 -0
- package/dist/kurot/resource/index.js.map +1 -1
- package/dist/kurot/text/BitmapFont.d.ts +15 -21
- package/dist/kurot/text/BitmapFont.d.ts.map +1 -1
- package/dist/kurot/text/BitmapFont.js +59 -66
- package/dist/kurot/text/BitmapFont.js.map +1 -1
- package/dist/kurot/text/BitmapText.d.ts +29 -19
- package/dist/kurot/text/BitmapText.d.ts.map +1 -1
- package/dist/kurot/text/BitmapText.js +93 -141
- package/dist/kurot/text/BitmapText.js.map +1 -1
- package/dist/kurot/text/index.d.ts +1 -0
- package/dist/kurot/text/index.d.ts.map +1 -1
- package/dist/kurot/text/index.js.map +1 -1
- package/docs/ai-context.md +22 -7
- package/docs/architecture.md +322 -276
- package/docs/bitmap-fonts.md +85 -0
- package/docs/resource.md +185 -156
- package/docs/text-layout.md +8 -6
- package/package.json +3 -2
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Bitmap fonts
|
|
2
|
+
|
|
3
|
+
Available in Core 2.2.0 with the published `@kurot/bitmap-font ^0.1.0` dependency.
|
|
4
|
+
Package installs and local builds resolve the font kernel from npm. Installed
|
|
5
|
+
Core 2.1.1 does not include FontAnalyzer or BitmapText rendering; update Core and
|
|
6
|
+
the lockfile to receive them. Source versions alone do not confirm publication.
|
|
7
|
+
|
|
8
|
+
A bitmap font is a descriptor plus a full image page. Core owns image loading and
|
|
9
|
+
rendering; @kurot/bitmap-font owns validation, parsing, serialization and layout.
|
|
10
|
+
See [the shared format](../../bitmap-font/docs/format.md).
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { BitmapFont, BitmapText, resource } from '@kurot/core';
|
|
14
|
+
|
|
15
|
+
resource.addResource({
|
|
16
|
+
name: 'number_font_fnt',
|
|
17
|
+
type: 'font',
|
|
18
|
+
url: 'resource/assets/font/number_font.fnt',
|
|
19
|
+
});
|
|
20
|
+
const font = await resource.load<BitmapFont>('number_font_fnt');
|
|
21
|
+
const text = new BitmapText();
|
|
22
|
+
text.font = font;
|
|
23
|
+
text.multiline = false;
|
|
24
|
+
text.text = '1,234.56';
|
|
25
|
+
stage.addChild(text);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`font` is a built-in ResourceType and FontAnalyzer. The descriptor's file is
|
|
29
|
+
resolved relative to the descriptor URL, including URLs with queries. Loading
|
|
30
|
+
resolves only after both descriptor and page are ready. Concurrent requests for
|
|
31
|
+
one font share the pending load. A separately configured PNG resource has
|
|
32
|
+
independent ownership; loading it is not required for the font.
|
|
33
|
+
|
|
34
|
+
Supported descriptors: native version-1 JSON, Egret frames JSON, single-page
|
|
35
|
+
unpacked BMFont text. XML/binary/multi-page/channel-packed fonts are unsupported.
|
|
36
|
+
Glyph coordinates must fit a complete, unrotated page texture.
|
|
37
|
+
|
|
38
|
+
## Direct texture injection and ownership
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const font = new BitmapFont(pageTexture, descriptor, { ownsTexture: false });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Direct construction owns the page by default, retaining the SpriteSheet lifecycle
|
|
45
|
+
contract. Set ownsTexture=false for a page owned by a project asset cache. Font
|
|
46
|
+
dispose is idempotent, invalidates subsequent getTexture calls, and disposes only
|
|
47
|
+
owned page data. BitmapText borrows the font; removing text never disposes it.
|
|
48
|
+
FontAnalyzer owns its internal page cache and frees it on resource.destroy(name).
|
|
49
|
+
Do not destroy a font while text using it remains displayed.
|
|
50
|
+
|
|
51
|
+
Parsed `font.data` is a deeply frozen snapshot. Changes require a new font; render
|
|
52
|
+
layout caches assume data does not mutate. Glyph subtextures are borrowed views.
|
|
53
|
+
|
|
54
|
+
## Text metrics and rendering
|
|
55
|
+
|
|
56
|
+
BitmapText has text/font, lineSpacing/letterSpacing, smoothing, multiline,
|
|
57
|
+
left/center/right textAlign and top/middle/bottom verticalAlign. The default is
|
|
58
|
+
multiline=true. Font metrics, fallback spaces, kerning, wrapping and bounds come
|
|
59
|
+
from layoutBitmapText. `getLayout()` and `getGlyphs()` expose borrowed readonly
|
|
60
|
+
layout data, while textWidth/textHeight report admitted line metrics.
|
|
61
|
+
measureText(width?, height?) measures independently without mutating rendered
|
|
62
|
+
constraints or invalidating its cached layout. UI uses it for measurement.
|
|
63
|
+
|
|
64
|
+
Width and height are constraints, not scales; set scaleX/scaleY to resize font
|
|
65
|
+
art. NaN removes a dimension constraint. Height admits complete line boxes;
|
|
66
|
+
multiline=false draws the first hard-separated line without width wrapping.
|
|
67
|
+
Explicit zero height draws nothing. Default textureScaleFactor=1 is required for
|
|
68
|
+
font assets in this initial implementation.
|
|
69
|
+
|
|
70
|
+
WebGL's BitmapTextPipe submits cropped glyph quads to ordinary texture batching,
|
|
71
|
+
with current transforms, alpha, tint, blend, clipping and filters. Canvas uses the
|
|
72
|
+
same layout and glyph geometry, including tint; cacheAsTexture and RenderTexture
|
|
73
|
+
use that Canvas path. Both honor font offsets without allocating child nodes.
|
|
74
|
+
Changing text/font/metrics invalidates layout and rendering, including an
|
|
75
|
+
existing WebGL instruction without a scene rebuild.
|
|
76
|
+
|
|
77
|
+
Core 2.2.0 fixes BitmapText's previous setter-only width/height accessors.
|
|
78
|
+
BitmapText.EMPTY_FACTOR is retained as a deprecated field; per-font spaceAdvance
|
|
79
|
+
now controls fallback spaces. Line-height, trailing-advance and complete-line
|
|
80
|
+
clipping follow the shared
|
|
81
|
+
format contract rather than the old unrendered class's approximate measurements.
|
|
82
|
+
|
|
83
|
+
The matching UI release provides BitmapLabel for native/programmatic skins;
|
|
84
|
+
published UI 3.1.0 does not include it. KUI catalog/CLI adoption is separate;
|
|
85
|
+
existing installed compilers do not gain a new tag automatically.
|
package/docs/resource.md
CHANGED
|
@@ -1,39 +1,43 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Resource Manager
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Overview
|
|
4
4
|
|
|
5
|
-
Kurot
|
|
5
|
+
Kurot's resource manager is an asynchronous loading and caching system adapted
|
|
6
|
+
from Egret RES. It provides:
|
|
6
7
|
|
|
7
|
-
- **async/await API** —
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
-
|
|
8
|
+
- **async/await API** — loading operations return promises.
|
|
9
|
+
- **Type safety** — the `ResourceType` enum and generic `get<T>()` API.
|
|
10
|
+
- **Configuration-driven loading** — support for Egret `resource.json` files.
|
|
11
|
+
- **Group loading** — concurrency control (2 concurrent loads by default) and
|
|
12
|
+
automatic retries (3 retries by default).
|
|
13
|
+
- **Extensibility** — custom analyzers for additional resource types.
|
|
14
|
+
- **Shared font kernel** — FontAnalyzer parses descriptors through
|
|
15
|
+
`@kurot/bitmap-font`; loading uses Core's `net/` and `events/` modules.
|
|
13
16
|
|
|
14
|
-
##
|
|
17
|
+
## Directory structure
|
|
15
18
|
|
|
16
19
|
```
|
|
17
20
|
packages/core/src/kurot/resource/
|
|
18
|
-
├── index.ts —
|
|
19
|
-
├── Resource.ts —
|
|
20
|
-
├── ResourceConfig.ts —
|
|
21
|
-
├── ResourceLoader.ts —
|
|
22
|
-
├── ResourceItem.ts —
|
|
23
|
-
├── ResourceEvent.ts —
|
|
21
|
+
├── index.ts — public exports
|
|
22
|
+
├── Resource.ts — resource manager and shared instance
|
|
23
|
+
├── ResourceConfig.ts — resource configuration parsing
|
|
24
|
+
├── ResourceLoader.ts — queued loading, concurrency and retries
|
|
25
|
+
├── ResourceItem.ts — resource items and the ResourceType enum
|
|
26
|
+
├── ResourceEvent.ts — resource event types
|
|
24
27
|
└── analyzers/
|
|
25
28
|
├── index.ts
|
|
26
|
-
├── AnalyzerBase.ts —
|
|
27
|
-
├── ImageAnalyzer.ts —
|
|
28
|
-
├── JsonAnalyzer.ts — JSON
|
|
29
|
-
├── TextAnalyzer.ts —
|
|
30
|
-
├── SoundAnalyzer.ts —
|
|
31
|
-
|
|
29
|
+
├── AnalyzerBase.ts — analyzer base class
|
|
30
|
+
├── ImageAnalyzer.ts — image → Texture
|
|
31
|
+
├── JsonAnalyzer.ts — JSON file → object
|
|
32
|
+
├── TextAnalyzer.ts — plain text → string
|
|
33
|
+
├── SoundAnalyzer.ts — audio → HTMLAudioElement
|
|
34
|
+
├── FontAnalyzer.ts — font descriptor + image → BitmapFont
|
|
35
|
+
└── SheetAnalyzer.ts — sprite-sheet JSON + image → SpriteSheet
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
##
|
|
38
|
+
## Quick start
|
|
35
39
|
|
|
36
|
-
### 1.
|
|
40
|
+
### 1. Prepare a configuration file
|
|
37
41
|
|
|
38
42
|
```json
|
|
39
43
|
// resource.json
|
|
@@ -50,100 +54,101 @@ packages/core/src/kurot/resource/
|
|
|
50
54
|
}
|
|
51
55
|
```
|
|
52
56
|
|
|
53
|
-
### 2.
|
|
57
|
+
### 2. Load and use resources
|
|
54
58
|
|
|
55
59
|
```typescript
|
|
56
60
|
import { resource, ResourceType } from '@kurot/core';
|
|
57
61
|
|
|
58
|
-
//
|
|
62
|
+
// Load the configuration.
|
|
59
63
|
await resource.loadConfig('resource.json', 'assets/');
|
|
60
64
|
|
|
61
|
-
//
|
|
65
|
+
// Load a resource group.
|
|
62
66
|
await resource.loadGroup('preload');
|
|
63
67
|
|
|
64
|
-
//
|
|
68
|
+
// Read a cached resource with a generic result type.
|
|
65
69
|
const texture = resource.get<Texture>('bg');
|
|
66
70
|
|
|
67
|
-
//
|
|
71
|
+
// Load a single resource asynchronously.
|
|
68
72
|
const data = await resource.load<object>('config');
|
|
69
73
|
|
|
70
|
-
//
|
|
74
|
+
// Track this group's loading progress.
|
|
71
75
|
await resource.loadGroup('game', 0, (loaded, total) => {
|
|
72
|
-
console.log(
|
|
76
|
+
console.log(`Progress: ${loaded}/${total}`);
|
|
73
77
|
});
|
|
74
78
|
```
|
|
75
79
|
|
|
76
|
-
## API
|
|
80
|
+
## API reference
|
|
77
81
|
|
|
78
|
-
### Resource
|
|
82
|
+
### Resource
|
|
79
83
|
|
|
80
|
-
####
|
|
84
|
+
#### Configuration
|
|
81
85
|
|
|
82
|
-
|
|
|
83
|
-
| -------------------------- |
|
|
84
|
-
| `loadConfig(url, folder?)` |
|
|
85
|
-
| `addResource(def)` |
|
|
86
|
+
| Method | Description |
|
|
87
|
+
| -------------------------- | -------------------------------------------------------------- |
|
|
88
|
+
| `loadConfig(url, folder?)` | Load and parse resource.json; `folder` prefixes resource URLs. |
|
|
89
|
+
| `addResource(def)` | Add a resource definition `{ name, url, type }` dynamically. |
|
|
86
90
|
|
|
87
|
-
####
|
|
91
|
+
#### Loading
|
|
88
92
|
|
|
89
|
-
|
|
|
90
|
-
| ----------------------------------------- |
|
|
91
|
-
| `loadGroup(name, priority?, onProgress?)` |
|
|
92
|
-
| `load<T>(name)` |
|
|
93
|
+
| Method | Description |
|
|
94
|
+
| ----------------------------------------- | ----------------------------------------------------------------- |
|
|
95
|
+
| `loadGroup(name, priority?, onProgress?)` | Load a group and return a promise; skip resources already loaded. |
|
|
96
|
+
| `load<T>(name)` | Load a single resource and return its cached data. |
|
|
93
97
|
|
|
94
|
-
####
|
|
98
|
+
#### Cache and lookup
|
|
95
99
|
|
|
96
|
-
|
|
|
97
|
-
| ----------------- |
|
|
98
|
-
| `get<T>(name)` |
|
|
99
|
-
| `hasRes(name)` |
|
|
100
|
-
| `hasGroup(name)` |
|
|
101
|
-
| `getGroupNames()` |
|
|
100
|
+
| Method | Description |
|
|
101
|
+
| ----------------- | ------------------------------------------------------------------------ |
|
|
102
|
+
| `get<T>(name)` | Read a cached resource synchronously; return `undefined` if unavailable. |
|
|
103
|
+
| `hasRes(name)` | Check whether a resource is cached by an analyzer. |
|
|
104
|
+
| `hasGroup(name)` | Check whether a group exists. |
|
|
105
|
+
| `getGroupNames()` | Return all group names. |
|
|
102
106
|
|
|
103
|
-
####
|
|
107
|
+
#### Destruction
|
|
104
108
|
|
|
105
|
-
|
|
|
106
|
-
| -------------------- |
|
|
107
|
-
| `destroy(name)` |
|
|
108
|
-
| `destroyGroup(name)` |
|
|
109
|
-
| `destroyAll()` |
|
|
109
|
+
| Method | Description |
|
|
110
|
+
| -------------------- | ----------------------------------------------- |
|
|
111
|
+
| `destroy(name)` | Destroy a resource and release its cached data. |
|
|
112
|
+
| `destroyGroup(name)` | Destroy all resources in a group. |
|
|
113
|
+
| `destroyAll()` | Destroy all loaded resources. |
|
|
110
114
|
|
|
111
|
-
####
|
|
115
|
+
#### Events
|
|
112
116
|
|
|
113
|
-
|
|
|
114
|
-
| ---------------------- |
|
|
115
|
-
| `on(type, listener)` |
|
|
116
|
-
| `off(type, listener)` |
|
|
117
|
-
| `onProgress(callback)` |
|
|
117
|
+
| Method | Description |
|
|
118
|
+
| ---------------------- | ------------------------------------------------------- |
|
|
119
|
+
| `on(type, listener)` | Listen for a resource event. |
|
|
120
|
+
| `off(type, listener)` | Remove an event listener. |
|
|
121
|
+
| `onProgress(callback)` | Register a progress listener `(loaded, total) => void`. |
|
|
118
122
|
|
|
119
|
-
####
|
|
123
|
+
#### Extension
|
|
120
124
|
|
|
121
|
-
|
|
|
122
|
-
| ---------------------------------- |
|
|
123
|
-
| `registerAnalyzer(type, analyzer)` |
|
|
125
|
+
| Method | Description |
|
|
126
|
+
| ---------------------------------- | ------------------------------------------------ |
|
|
127
|
+
| `registerAnalyzer(type, analyzer)` | Register an analyzer for a custom resource type. |
|
|
124
128
|
|
|
125
|
-
### ResourceType
|
|
129
|
+
### ResourceType
|
|
126
130
|
|
|
127
|
-
|
|
|
128
|
-
| --------- |
|
|
129
|
-
| `'image'` |
|
|
130
|
-
| `'json'` | JSON
|
|
131
|
-
| `'text'` |
|
|
132
|
-
| `'sound'` |
|
|
133
|
-
| `'sheet'` |
|
|
131
|
+
| Value | Description |
|
|
132
|
+
| --------- | --------------------------------------------- |
|
|
133
|
+
| `'image'` | Image resource producing a `Texture`. |
|
|
134
|
+
| `'json'` | JSON file parsed as an `object`. |
|
|
135
|
+
| `'text'` | Plain-text file returned as a `string`. |
|
|
136
|
+
| `'sound'` | Audio file returned as an `HTMLAudioElement`. |
|
|
137
|
+
| `'sheet'` | Sprite sheet returned as a `SpriteSheet`. |
|
|
138
|
+
| `'font'` | Bitmap font returned as a `BitmapFont`. |
|
|
134
139
|
|
|
135
|
-
### ResourceEventType
|
|
140
|
+
### ResourceEventType
|
|
136
141
|
|
|
137
|
-
|
|
|
138
|
-
| ------------------- |
|
|
139
|
-
| `CONFIG_COMPLETE` |
|
|
140
|
-
| `CONFIG_LOAD_ERROR` |
|
|
141
|
-
| `GROUP_COMPLETE` |
|
|
142
|
-
| `GROUP_PROGRESS` |
|
|
143
|
-
| `GROUP_LOAD_ERROR` |
|
|
144
|
-
| `ITEM_LOAD_ERROR` |
|
|
142
|
+
| Event | Trigger |
|
|
143
|
+
| ------------------- | ----------------------------------------- |
|
|
144
|
+
| `CONFIG_COMPLETE` | Configuration loading completes. |
|
|
145
|
+
| `CONFIG_LOAD_ERROR` | Configuration loading fails. |
|
|
146
|
+
| `GROUP_COMPLETE` | All resources in a group finish loading. |
|
|
147
|
+
| `GROUP_PROGRESS` | A resource in the group finishes loading. |
|
|
148
|
+
| `GROUP_LOAD_ERROR` | A resource in the group fails to load. |
|
|
149
|
+
| `ITEM_LOAD_ERROR` | A single resource fails to load. |
|
|
145
150
|
|
|
146
|
-
### ResourceEvent
|
|
151
|
+
### ResourceEvent
|
|
147
152
|
|
|
148
153
|
```typescript
|
|
149
154
|
interface ResourceEvent {
|
|
@@ -155,20 +160,20 @@ interface ResourceEvent {
|
|
|
155
160
|
}
|
|
156
161
|
```
|
|
157
162
|
|
|
158
|
-
##
|
|
163
|
+
## Built-in analyzers
|
|
159
164
|
|
|
160
165
|
### ImageAnalyzer
|
|
161
166
|
|
|
162
|
-
|
|
167
|
+
Load an image and create a `Texture`. Destruction calls `texture.dispose()`.
|
|
163
168
|
|
|
164
169
|
```typescript
|
|
165
170
|
const texture = resource.get<Texture>('bg');
|
|
166
|
-
// texture
|
|
171
|
+
// Use the texture with a Bitmap display object.
|
|
167
172
|
```
|
|
168
173
|
|
|
169
174
|
### JsonAnalyzer
|
|
170
175
|
|
|
171
|
-
|
|
176
|
+
Load a JSON file through `HttpRequest` and parse it into an object.
|
|
172
177
|
|
|
173
178
|
```typescript
|
|
174
179
|
const config = resource.get<Record<string, unknown>>('config');
|
|
@@ -176,15 +181,33 @@ const config = resource.get<Record<string, unknown>>('config');
|
|
|
176
181
|
|
|
177
182
|
### TextAnalyzer
|
|
178
183
|
|
|
179
|
-
|
|
184
|
+
Load a plain-text file through `HttpRequest`.
|
|
180
185
|
|
|
181
186
|
```typescript
|
|
182
187
|
const text = resource.get<string>('readme');
|
|
183
188
|
```
|
|
184
189
|
|
|
190
|
+
### FontAnalyzer (2.2.0)
|
|
191
|
+
|
|
192
|
+
Load a font descriptor and its image page, resolved relative to the descriptor,
|
|
193
|
+
and return a `BitmapFont`. Supported formats are Egret JSON `.fnt`, native JSON
|
|
194
|
+
and single-page, unpacked BMFont text. Concurrent requests for the same font share
|
|
195
|
+
one load. Destroying the font releases its internal page; a separately configured
|
|
196
|
+
PNG resource retains independent ownership. Display objects borrow the font, so
|
|
197
|
+
removing text does not destroy it. See [bitmap fonts](bitmap-fonts.md) for formats,
|
|
198
|
+
texture restrictions and lifecycle contracts.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { BitmapFont, resource } from '@kurot/core';
|
|
202
|
+
|
|
203
|
+
resource.addResource({ name: 'numbers', type: 'font', url: 'assets/number_font.fnt' });
|
|
204
|
+
const font = await resource.load<BitmapFont>('numbers');
|
|
205
|
+
```
|
|
206
|
+
|
|
185
207
|
### SoundAnalyzer
|
|
186
208
|
|
|
187
|
-
|
|
209
|
+
Load an audio file and return an `HTMLAudioElement`. Destruction calls `pause()`
|
|
210
|
+
and releases `src`.
|
|
188
211
|
|
|
189
212
|
```typescript
|
|
190
213
|
const audio = resource.get<HTMLAudioElement>('bgm');
|
|
@@ -193,27 +216,27 @@ audio.play();
|
|
|
193
216
|
|
|
194
217
|
### SheetAnalyzer
|
|
195
218
|
|
|
196
|
-
|
|
219
|
+
Load a sprite sheet in TexturePacker JSON format in two steps:
|
|
197
220
|
|
|
198
|
-
1.
|
|
199
|
-
2.
|
|
221
|
+
1. Load the JSON descriptor to obtain frame data and the image path.
|
|
222
|
+
2. Load the image and create subtextures.
|
|
200
223
|
|
|
201
|
-
|
|
224
|
+
Resources can be retrieved in three ways:
|
|
202
225
|
|
|
203
226
|
```typescript
|
|
204
|
-
//
|
|
227
|
+
// Retrieve the complete SpriteSheet.
|
|
205
228
|
const sheet = resource.get<SpriteSheet>('hero');
|
|
206
229
|
|
|
207
|
-
//
|
|
230
|
+
// Retrieve a subtexture directly by its subkey name.
|
|
208
231
|
const frame = resource.get<Texture>('hero_idle_01');
|
|
209
232
|
|
|
210
|
-
//
|
|
233
|
+
// Retrieve a subtexture with dot notation.
|
|
211
234
|
const frame2 = resource.get<Texture>('hero.idle_01');
|
|
212
235
|
```
|
|
213
236
|
|
|
214
|
-
##
|
|
237
|
+
## Custom analyzers
|
|
215
238
|
|
|
216
|
-
|
|
239
|
+
Extend `AnalyzerBase` to implement a custom resource type:
|
|
217
240
|
|
|
218
241
|
```typescript
|
|
219
242
|
import { AnalyzerBase } from '@kurot/core';
|
|
@@ -242,92 +265,98 @@ class XmlAnalyzer extends AnalyzerBase {
|
|
|
242
265
|
}
|
|
243
266
|
}
|
|
244
267
|
|
|
245
|
-
//
|
|
268
|
+
// Register the analyzer.
|
|
246
269
|
resource.registerAnalyzer('xml', new XmlAnalyzer());
|
|
247
270
|
```
|
|
248
271
|
|
|
249
|
-
##
|
|
272
|
+
## Queued loading (ResourceLoader)
|
|
250
273
|
|
|
251
|
-
`ResourceLoader`
|
|
274
|
+
`ResourceLoader` is the internal queue loader. It supports:
|
|
252
275
|
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
|
|
276
|
+
- **Concurrency control** — `threadCount` limits simultaneous loads (default 2).
|
|
277
|
+
- **Automatic retries** — `retryCount` controls retries before reporting failure
|
|
278
|
+
(default 3).
|
|
279
|
+
- **Notifications** — `onComplete`, `onError` and `onProgress` callbacks.
|
|
256
280
|
|
|
257
|
-
|
|
281
|
+
Applications normally use `Resource.loadGroup()` instead of accessing
|
|
282
|
+
`ResourceLoader` directly.
|
|
258
283
|
|
|
259
|
-
##
|
|
284
|
+
## Configuration format
|
|
260
285
|
|
|
261
|
-
###
|
|
286
|
+
### Standard format (2.0.0)
|
|
262
287
|
|
|
263
288
|
```json
|
|
264
289
|
{
|
|
265
290
|
"resources": [
|
|
266
291
|
{
|
|
267
|
-
"name": "
|
|
268
|
-
"type": "image|json|text|sound|sheet",
|
|
269
|
-
"url": "
|
|
292
|
+
"name": "uniqueResourceName",
|
|
293
|
+
"type": "image|json|text|sound|sheet|font",
|
|
294
|
+
"url": "relative-or-absolute-path",
|
|
270
295
|
"subkeys": { "frameName": { "scale9grid": "1,1,2,2" }, "ordinaryFrame": {} }
|
|
271
296
|
}
|
|
272
297
|
],
|
|
273
298
|
"groups": [
|
|
274
299
|
{
|
|
275
|
-
"name": "
|
|
276
|
-
"keys": "
|
|
300
|
+
"name": "groupName",
|
|
301
|
+
"keys": "resource1,resource2"
|
|
277
302
|
}
|
|
278
303
|
]
|
|
279
304
|
}
|
|
280
305
|
```
|
|
281
306
|
|
|
282
|
-
|
|
283
|
-
`scale9grid`
|
|
284
|
-
|
|
307
|
+
`subkeys` is an object map. Refresh legacy sheets explicitly in the Editor before
|
|
308
|
+
using old string-based manifests. `scale9grid` supplies Image compilation defaults;
|
|
309
|
+
Core does not apply it automatically to arbitrary Bitmap objects. See the
|
|
310
|
+
[resource nine-slice defaults contract](../../ui-document/docs/resource-nine-slice.md).
|
|
285
311
|
|
|
286
|
-
### URL
|
|
312
|
+
### URL resolution
|
|
287
313
|
|
|
288
|
-
-
|
|
289
|
-
-
|
|
314
|
+
- URLs containing `://` are treated as absolute and left unchanged.
|
|
315
|
+
- Other URLs receive the `folder` prefix passed to `loadConfig()`.
|
|
290
316
|
|
|
291
|
-
###
|
|
317
|
+
### Creating groups dynamically
|
|
292
318
|
|
|
293
319
|
```typescript
|
|
294
320
|
import { resource, ResourceConfig } from '@kurot/core';
|
|
295
321
|
|
|
296
|
-
//
|
|
297
|
-
//
|
|
322
|
+
// Use ResourceConfig.createGroup for low-level group creation.
|
|
323
|
+
// Applications usually define groups in configuration files.
|
|
298
324
|
```
|
|
299
325
|
|
|
300
|
-
##
|
|
301
|
-
|
|
302
|
-
|
|
|
303
|
-
|
|
|
304
|
-
| API
|
|
305
|
-
|
|
|
306
|
-
|
|
|
307
|
-
|
|
|
308
|
-
|
|
|
309
|
-
| XML
|
|
310
|
-
|
|
|
311
|
-
|
|
|
312
|
-
|
|
|
313
|
-
|
|
314
|
-
###
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
- **VersionController** —
|
|
319
|
-
|
|
320
|
-
- **
|
|
321
|
-
- **
|
|
322
|
-
|
|
323
|
-
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
326
|
+
## Comparison with Egret RES
|
|
327
|
+
|
|
328
|
+
| Aspect | Egret RES | Kurot Resource |
|
|
329
|
+
| -------------------- | ------------------------- | ------------------------------------ |
|
|
330
|
+
| API style | Callback `compFunc(data)` | `async/await` and promises |
|
|
331
|
+
| Modules | Global `RES.xxx` | ES module imports |
|
|
332
|
+
| Events | `egret.EventDispatcher` | Lightweight `on/off` API |
|
|
333
|
+
| Type safety | Extensive `any` | Generic `get<T>()` |
|
|
334
|
+
| Versioning | `VersionController` | Handled by build tools |
|
|
335
|
+
| XML parsing | Built in | Handled by the KUI XML compiler |
|
|
336
|
+
| Internationalization | Built in | Outside the resource loader's scope |
|
|
337
|
+
| Analyzer types | 8 | 6 (Image/Json/Text/Sound/Sheet/Font) |
|
|
338
|
+
| Code size | Approximately 3,000 lines | Approximately 1,400 lines |
|
|
339
|
+
|
|
340
|
+
### Omitted features
|
|
341
|
+
|
|
342
|
+
The following legacy features are intentionally omitted:
|
|
343
|
+
|
|
344
|
+
- **VersionController** — modern build tools such as Vite/Webpack handle CDN
|
|
345
|
+
versioning.
|
|
346
|
+
- **i18n** — internationalization is outside the resource loader's scope.
|
|
347
|
+
- **XML/Bin analyzers** — the compiler preprocesses KUI XML; a built-in binary
|
|
348
|
+
analyzer is not included.
|
|
349
|
+
- **AnimationAnalyzer** — not included; a custom analyzer can provide it if needed.
|
|
350
|
+
- **Complex synchronous getRes() sheet-subkey lookup** — replaced by dot notation.
|
|
351
|
+
|
|
352
|
+
## Usage notes
|
|
353
|
+
|
|
354
|
+
1. **Concurrent `loadGroup` calls are queued serially.** They share one internal
|
|
355
|
+
`ResourceLoader`. Calls for the same or different groups retain their own
|
|
356
|
+
callbacks and promise results, but the underlying batches run sequentially.
|
|
357
|
+
2. **`onProgress` listeners are permanent.** For tracking a single load operation,
|
|
358
|
+
use the callback parameter of `loadGroup`.
|
|
359
|
+
3. **Sheet subkey collisions.** Avoid duplicate subtexture names across sheets;
|
|
360
|
+
later sheets do not replace an earlier sheet's subkey registration.
|
|
361
|
+
4. **Resource URLs require same-origin access or CORS.** Browser access rules
|
|
362
|
+
apply to images and audio.
|
package/docs/text-layout.md
CHANGED
|
@@ -65,13 +65,15 @@ regressions. No resource-manifest or CLI XML-format change is involved.
|
|
|
65
65
|
|
|
66
66
|
## Package dependencies
|
|
67
67
|
|
|
68
|
-
UI 3.1.0 and ui-runtime 0.8.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
UI 3.1.0 and ui-runtime 0.8.2 declare Core `^2.1.0` in their peer ranges;
|
|
69
|
+
game 2.0.0 declares `^2.0.0`. Their development dependencies and repository
|
|
70
|
+
examples use Core `^2.1.1`, with lockfiles resolving 2.1.1 for its nested
|
|
71
|
+
scroll-clipping fix. CLI templates use `latest`.
|
|
72
72
|
Label font shrinking calls `invalidateTextMetrics()` and requires Core 2.1.0
|
|
73
|
-
or later. Core 2.
|
|
74
|
-
|
|
73
|
+
or later. Core 2.2.0 preserves that TextField contract and remains accepted by
|
|
74
|
+
these existing peer ranges. Bitmap-font rendering is separate from TextField;
|
|
75
|
+
see [bitmap fonts](bitmap-fonts.md). The new UI BitmapLabel requires Core 2.2.0
|
|
76
|
+
and its own UI release; published UI 3.1.0 does not contain it.
|
|
75
77
|
|
|
76
78
|
References: [UAX #14 revision 55](https://www.unicode.org/reports/tr14/tr14-55.html),
|
|
77
79
|
[official corpus](https://www.unicode.org/Public/17.0.0/ucd/auxiliary/LineBreakTest.txt),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kurot/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Modern rewrite of the Egret game engine — WebGL multi-texture batching, instruction-driven render pipeline, strict TypeScript, Egret-compatible API",
|
|
5
5
|
"author": "Kelvin <kyia.x52@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"access": "public"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@cto.af/linebreak": "4.0.3"
|
|
71
|
+
"@cto.af/linebreak": "4.0.3",
|
|
72
|
+
"@kurot/bitmap-font": "^0.1.0"
|
|
72
73
|
}
|
|
73
74
|
}
|