blecsd 0.1.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/LICENSE +20 -0
- package/README.md +220 -0
- package/dist/3d/index.d.ts +5 -0
- package/dist/3d/index.js +1 -0
- package/dist/audio/index.d.ts +177 -0
- package/dist/audio/index.js +1 -0
- package/dist/border-D_Jb4ZJV.d.ts +257 -0
- package/dist/cell-DwIu2ryP.d.ts +505 -0
- package/dist/chunk-2UBBZFE4.js +1 -0
- package/dist/chunk-35LCBY6P.js +1 -0
- package/dist/chunk-3B7MIVW6.js +1 -0
- package/dist/chunk-3EGGGI5J.js +3 -0
- package/dist/chunk-4LWWONFK.js +1 -0
- package/dist/chunk-4X4N4HNQ.js +2 -0
- package/dist/chunk-5PELJRUQ.js +1 -0
- package/dist/chunk-AEJIX2MW.js +1 -0
- package/dist/chunk-AQ7LW75B.js +1 -0
- package/dist/chunk-AXZQAH4X.js +1 -0
- package/dist/chunk-B6Z2JFRY.js +1 -0
- package/dist/chunk-BCADUCOZ.js +1 -0
- package/dist/chunk-C5PCEQ6G.js +1 -0
- package/dist/chunk-CIK4AMUA.js +1 -0
- package/dist/chunk-DNRXW56C.js +1 -0
- package/dist/chunk-FC5FFAAC.js +12 -0
- package/dist/chunk-FGHEFXLK.js +1 -0
- package/dist/chunk-FYEBZAWN.js +1 -0
- package/dist/chunk-G7GIWWLE.js +1 -0
- package/dist/chunk-GYHI26UE.js +1 -0
- package/dist/chunk-H2YAOJDW.js +1 -0
- package/dist/chunk-J4JZ2NU2.js +1 -0
- package/dist/chunk-JKVHO4LH.js +1 -0
- package/dist/chunk-K2B2OXQ5.js +5 -0
- package/dist/chunk-K37L3G4Z.js +4 -0
- package/dist/chunk-KD55INV7.js +1 -0
- package/dist/chunk-KFAK4A3G.js +1 -0
- package/dist/chunk-LCN2ZITE.js +1 -0
- package/dist/chunk-LYSK5S63.js +1 -0
- package/dist/chunk-NZ55KBM6.js +1 -0
- package/dist/chunk-OMMJ7B5P.js +1 -0
- package/dist/chunk-OUXUPF3V.js +33 -0
- package/dist/chunk-OVT2PPGW.js +19 -0
- package/dist/chunk-P6CJO3BC.js +1 -0
- package/dist/chunk-PSXXMBVJ.js +1 -0
- package/dist/chunk-PXXGH3BV.js +1 -0
- package/dist/chunk-QIKIOVP2.js +1 -0
- package/dist/chunk-SHUC6JWA.js +1 -0
- package/dist/chunk-TDXJDLY6.js +6 -0
- package/dist/chunk-TWSWTBYL.js +1 -0
- package/dist/chunk-TYMY2TBR.js +3 -0
- package/dist/chunk-VNZ6CWJA.js +2 -0
- package/dist/chunk-VOCM5T2G.js +5 -0
- package/dist/chunk-W5OU7Z6J.js +1 -0
- package/dist/chunk-WNG4A3K7.js +4 -0
- package/dist/chunk-XQIGERNI.js +1 -0
- package/dist/chunk-XZA63ZPO.js +1 -0
- package/dist/chunk-YAMOSPWB.js +4 -0
- package/dist/chunk-YD6ULIUR.js +1 -0
- package/dist/chunk-Z4EZERNE.js +1 -0
- package/dist/cli/init.d.ts +86 -0
- package/dist/cli/init.js +179 -0
- package/dist/color-B78w3zH-.d.ts +79 -0
- package/dist/components/index.d.ts +10298 -0
- package/dist/components/index.js +1 -0
- package/dist/core/index.d.ts +6700 -0
- package/dist/core/index.js +1 -0
- package/dist/debug/index.d.ts +711 -0
- package/dist/debug/index.js +1 -0
- package/dist/doubleBuffer-CKQFmlPN.d.ts +95 -0
- package/dist/errors/index.d.ts +1110 -0
- package/dist/errors/index.js +1 -0
- package/dist/events-BbbxkgvX.d.ts +125 -0
- package/dist/game/index.d.ts +486 -0
- package/dist/game/index.js +1 -0
- package/dist/gameLoop-BIPW7-OY.d.ts +219 -0
- package/dist/index-zSGJ2eUk.d.ts +3156 -0
- package/dist/index.d.ts +246 -0
- package/dist/index.js +1 -0
- package/dist/input/index.d.ts +158 -0
- package/dist/input/index.js +1 -0
- package/dist/inputActions-CefRUBuT.d.ts +2637 -0
- package/dist/keyParser-Bwm8-l7v.d.ts +229 -0
- package/dist/mouseParser-Cfrbn3AX.d.ts +177 -0
- package/dist/parser-iMHmQuUh.d.ts +265 -0
- package/dist/program-BZaKqDKH.d.ts +141 -0
- package/dist/renderable-jTMOA-GK.d.ts +302 -0
- package/dist/scheduler-DcfoFuum.d.ts +86 -0
- package/dist/schemas/index.d.ts +936 -0
- package/dist/schemas/index.js +1 -0
- package/dist/systems/index.d.ts +4036 -0
- package/dist/systems/index.js +1 -0
- package/dist/terminal/index.d.ts +7357 -0
- package/dist/terminal/index.js +1 -0
- package/dist/terminus-14-bold-HWSPRLJD.js +1 -0
- package/dist/terminus-14-normal-T3SWMH4D.js +1 -0
- package/dist/tilemap-D1HJvKy3.d.ts +1211 -0
- package/dist/types-BcsvoKzf.d.ts +68 -0
- package/dist/utils/index.d.ts +6104 -0
- package/dist/utils/index.js +1 -0
- package/dist/viewport3d-xI33-_wq.d.ts +182 -0
- package/dist/virtualScrollback-DvZTRU8a.d.ts +274 -0
- package/dist/virtualViewport-Dx2iJliO.d.ts +2334 -0
- package/dist/virtualizedLineStore-DwPEvPkk.d.ts +297 -0
- package/dist/widgets/bigText.d.ts +230 -0
- package/dist/widgets/bigText.js +1 -0
- package/dist/widgets/fonts/index.d.ts +211 -0
- package/dist/widgets/fonts/index.js +1 -0
- package/dist/widgets/index.d.ts +8591 -0
- package/dist/widgets/index.js +1 -0
- package/package.json +213 -0
|
@@ -0,0 +1,4036 @@
|
|
|
1
|
+
import { S as Scheduler } from '../scheduler-DcfoFuum.js';
|
|
2
|
+
import { S as System, W as World, E as Entity, L as LoopPhase } from '../types-BcsvoKzf.js';
|
|
3
|
+
import { d as CollisionPair, f as EmitterAppearance, R as RenderedTileCell } from '../tilemap-D1HJvKy3.js';
|
|
4
|
+
import { E as EventBus, U as UIEventMap } from '../events-BbbxkgvX.js';
|
|
5
|
+
import { b as KeyEvent } from '../keyParser-Bwm8-l7v.js';
|
|
6
|
+
import { M as MouseEvent } from '../mouseParser-Cfrbn3AX.js';
|
|
7
|
+
import { Writable } from 'node:stream';
|
|
8
|
+
import { c as CellChange, S as ScreenBufferData, C as Cell } from '../cell-DwIu2ryP.js';
|
|
9
|
+
import { D as DoubleBufferData } from '../doubleBuffer-CKQFmlPN.js';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { V as VirtualizedLineStore } from '../virtualizedLineStore-DwPEvPkk.js';
|
|
12
|
+
import 'bitecs';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Animation system for updating sprite animations.
|
|
16
|
+
* Processes all entities with Animation component.
|
|
17
|
+
* @module systems/animationSystem
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Query all entities with the Animation component.
|
|
22
|
+
*
|
|
23
|
+
* @param world - The ECS world
|
|
24
|
+
* @returns Array of entity IDs with Animation component
|
|
25
|
+
*/
|
|
26
|
+
declare function queryAnimation(world: World): number[];
|
|
27
|
+
/**
|
|
28
|
+
* Checks if an entity has the Animation component (via system store).
|
|
29
|
+
*
|
|
30
|
+
* @param world - The ECS world
|
|
31
|
+
* @param eid - Entity to check
|
|
32
|
+
* @returns true if entity has Animation component
|
|
33
|
+
*/
|
|
34
|
+
declare function hasAnimationSystem(world: World, eid: number): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Animation system that updates all entities with Animation component.
|
|
37
|
+
*
|
|
38
|
+
* This system should be registered in the UPDATE phase of the game loop.
|
|
39
|
+
* It reads delta time from getDeltaTime() which is set by the scheduler.
|
|
40
|
+
*
|
|
41
|
+
* For each playing animation, the system:
|
|
42
|
+
* 1. Adds elapsed time (scaled by speed)
|
|
43
|
+
* 2. Checks if current frame duration exceeded
|
|
44
|
+
* 3. Advances to next frame (respecting direction)
|
|
45
|
+
* 4. Handles loop/stop when animation completes
|
|
46
|
+
* 5. Updates the entity's Sprite component frame
|
|
47
|
+
*
|
|
48
|
+
* @param world - The ECS world to process
|
|
49
|
+
* @returns The world (unchanged reference)
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import { createScheduler, LoopPhase, animationSystem } from 'blecsd';
|
|
54
|
+
*
|
|
55
|
+
* const scheduler = createScheduler();
|
|
56
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, animationSystem);
|
|
57
|
+
*
|
|
58
|
+
* // In game loop
|
|
59
|
+
* scheduler.run(world, deltaTime);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
declare const animationSystem: System;
|
|
63
|
+
/**
|
|
64
|
+
* Creates a new animation system.
|
|
65
|
+
*
|
|
66
|
+
* Factory function that returns the animationSystem.
|
|
67
|
+
* Useful for cases where you need a fresh reference.
|
|
68
|
+
*
|
|
69
|
+
* @returns The animation system function
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* import { createAnimationSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
74
|
+
*
|
|
75
|
+
* const scheduler = createScheduler();
|
|
76
|
+
* const system = createAnimationSystem();
|
|
77
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, system);
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare function createAnimationSystem(): System;
|
|
81
|
+
/**
|
|
82
|
+
* Registers the animation system with a scheduler.
|
|
83
|
+
*
|
|
84
|
+
* Convenience function that registers animationSystem in the UPDATE phase.
|
|
85
|
+
*
|
|
86
|
+
* @param scheduler - The scheduler to register with
|
|
87
|
+
* @param priority - Optional priority within the UPDATE phase (default: 0)
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* import { createScheduler, registerAnimationSystem } from 'blecsd';
|
|
92
|
+
*
|
|
93
|
+
* const scheduler = createScheduler();
|
|
94
|
+
* registerAnimationSystem(scheduler);
|
|
95
|
+
*
|
|
96
|
+
* // Animation updates will now happen in UPDATE phase
|
|
97
|
+
* scheduler.run(world, deltaTime);
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare function registerAnimationSystem(scheduler: Scheduler, priority?: number): void;
|
|
101
|
+
/**
|
|
102
|
+
* Manually update animations for specific entities.
|
|
103
|
+
*
|
|
104
|
+
* Useful when you need to update animations outside of the system,
|
|
105
|
+
* such as in tests or custom update loops.
|
|
106
|
+
*
|
|
107
|
+
* @param world - The ECS world
|
|
108
|
+
* @param entities - Array of entity IDs to update
|
|
109
|
+
* @param deltaTime - Time elapsed in seconds
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* import { updateAnimations, queryAnimation } from 'blecsd';
|
|
114
|
+
*
|
|
115
|
+
* // Manual update (typically use the system instead)
|
|
116
|
+
* const entities = queryAnimation(world);
|
|
117
|
+
* updateAnimations(world, entities, 0.016); // ~60fps frame
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
declare function updateAnimations(world: World, entities: readonly number[], deltaTime: number): void;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Behavior system for processing AI behaviors each frame.
|
|
124
|
+
*
|
|
125
|
+
* Integrates with the Behavior component to update patrol movement,
|
|
126
|
+
* chase/flee logic, custom behaviors, and wait timers.
|
|
127
|
+
*
|
|
128
|
+
* @module systems/behaviorSystem
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Position resolver function for getting entity positions.
|
|
133
|
+
* Allows the behavior system to work with any position storage.
|
|
134
|
+
*/
|
|
135
|
+
type PositionResolver = (world: World, eid: Entity) => {
|
|
136
|
+
x: number;
|
|
137
|
+
y: number;
|
|
138
|
+
} | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Movement applier function for applying computed movement.
|
|
141
|
+
* Allows the behavior system to work with any movement system.
|
|
142
|
+
*/
|
|
143
|
+
type MovementApplier = (world: World, eid: Entity, dx: number, dy: number, delta: number) => void;
|
|
144
|
+
/**
|
|
145
|
+
* Configuration for the behavior system.
|
|
146
|
+
*/
|
|
147
|
+
interface BehaviorSystemConfig {
|
|
148
|
+
/** Function to resolve entity positions (default: uses Position component) */
|
|
149
|
+
getPosition?: PositionResolver;
|
|
150
|
+
/** Function to apply movement (default: directly modifies Position) */
|
|
151
|
+
applyMovement?: MovementApplier;
|
|
152
|
+
/** Function to get delta time */
|
|
153
|
+
getDelta: () => number;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Creates a behavior system that processes all entities with Behavior components.
|
|
157
|
+
*
|
|
158
|
+
* The system computes movement directions for patrol, chase, and flee behaviors,
|
|
159
|
+
* and applies them via the configured movement applier.
|
|
160
|
+
*
|
|
161
|
+
* @param config - System configuration
|
|
162
|
+
* @param entities - Function returning entity IDs to process
|
|
163
|
+
* @returns A system function
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* import { createBehaviorSystem } from 'blecsd';
|
|
168
|
+
*
|
|
169
|
+
* const behaviorSystem = createBehaviorSystem({
|
|
170
|
+
* getDelta: () => 1/60,
|
|
171
|
+
* }, () => behaviorEntities);
|
|
172
|
+
*
|
|
173
|
+
* // In update loop
|
|
174
|
+
* behaviorSystem(world);
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
declare function createBehaviorSystem(config: BehaviorSystemConfig, entities: (world: World) => readonly Entity[]): System;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Camera system for updating camera positions.
|
|
181
|
+
* Processes all entities with Camera component.
|
|
182
|
+
* @module systems/cameraSystem
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Query all entities with the Camera component.
|
|
187
|
+
*
|
|
188
|
+
* @param world - The ECS world
|
|
189
|
+
* @returns Array of entity IDs with Camera component
|
|
190
|
+
*/
|
|
191
|
+
declare function queryCameras(world: World): number[];
|
|
192
|
+
/**
|
|
193
|
+
* Camera system that updates all cameras with follow targets.
|
|
194
|
+
*
|
|
195
|
+
* This system should be registered in the UPDATE phase, after movement.
|
|
196
|
+
* It updates camera positions to follow their targets with smoothing
|
|
197
|
+
* and dead zone support.
|
|
198
|
+
*
|
|
199
|
+
* @param world - The ECS world to process
|
|
200
|
+
* @returns The world (unchanged reference)
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* import { createScheduler, LoopPhase, cameraSystem } from 'blecsd';
|
|
205
|
+
*
|
|
206
|
+
* const scheduler = createScheduler();
|
|
207
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, cameraSystem, 20); // After movement and collision
|
|
208
|
+
*
|
|
209
|
+
* // In game loop
|
|
210
|
+
* scheduler.run(world, deltaTime);
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
declare const cameraSystem: System;
|
|
214
|
+
/**
|
|
215
|
+
* Creates a new camera system.
|
|
216
|
+
*
|
|
217
|
+
* Factory function that returns the cameraSystem.
|
|
218
|
+
*
|
|
219
|
+
* @returns The camera system function
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* import { createCameraSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
224
|
+
*
|
|
225
|
+
* const scheduler = createScheduler();
|
|
226
|
+
* const system = createCameraSystem();
|
|
227
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, system, 20);
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
declare function createCameraSystem(): System;
|
|
231
|
+
/**
|
|
232
|
+
* Registers the camera system with a scheduler.
|
|
233
|
+
*
|
|
234
|
+
* Convenience function that registers cameraSystem in the UPDATE phase.
|
|
235
|
+
* Uses priority 20 by default to run after movement (priority 0) and collision (priority 10).
|
|
236
|
+
*
|
|
237
|
+
* @param scheduler - The scheduler to register with
|
|
238
|
+
* @param priority - Optional priority within the UPDATE phase (default: 20)
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* import { createScheduler, registerCameraSystem } from 'blecsd';
|
|
243
|
+
*
|
|
244
|
+
* const scheduler = createScheduler();
|
|
245
|
+
* registerCameraSystem(scheduler);
|
|
246
|
+
*
|
|
247
|
+
* // Camera updates will happen in UPDATE phase after movement
|
|
248
|
+
* scheduler.run(world, deltaTime);
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
declare function registerCameraSystem(scheduler: Scheduler, priority?: number): void;
|
|
252
|
+
/**
|
|
253
|
+
* Manually updates all cameras.
|
|
254
|
+
*
|
|
255
|
+
* Useful when you need to update cameras outside of the system,
|
|
256
|
+
* such as in tests or custom update loops.
|
|
257
|
+
*
|
|
258
|
+
* @param world - The ECS world
|
|
259
|
+
* @param deltaTime - Time elapsed in seconds
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* import { updateCameras } from 'blecsd';
|
|
264
|
+
*
|
|
265
|
+
* // Manual camera update (typically use the system instead)
|
|
266
|
+
* updateCameras(world, 0.016);
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
declare function updateCameras(world: World, deltaTime: number): void;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Collision system for detecting entity collisions.
|
|
273
|
+
* Processes all entities with Collider component.
|
|
274
|
+
* @module systems/collisionSystem
|
|
275
|
+
*/
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Collision event data.
|
|
279
|
+
*/
|
|
280
|
+
interface CollisionEventData {
|
|
281
|
+
/** First entity in collision */
|
|
282
|
+
readonly entityA: number;
|
|
283
|
+
/** Second entity in collision */
|
|
284
|
+
readonly entityB: number;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Collision event map for the EventBus.
|
|
288
|
+
*/
|
|
289
|
+
interface CollisionEventMap {
|
|
290
|
+
/** Fired when two solid colliders start colliding */
|
|
291
|
+
collisionStart: CollisionEventData;
|
|
292
|
+
/** Fired when two solid colliders stop colliding */
|
|
293
|
+
collisionEnd: CollisionEventData;
|
|
294
|
+
/** Fired when an entity enters a trigger zone */
|
|
295
|
+
triggerEnter: CollisionEventData;
|
|
296
|
+
/** Fired when an entity exits a trigger zone */
|
|
297
|
+
triggerExit: CollisionEventData;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Collision system state.
|
|
301
|
+
*/
|
|
302
|
+
interface CollisionSystemState {
|
|
303
|
+
/** Event bus for collision events */
|
|
304
|
+
readonly eventBus: EventBus<CollisionEventMap>;
|
|
305
|
+
/** Currently active collision pairs */
|
|
306
|
+
readonly activePairs: Map<string, CollisionPair>;
|
|
307
|
+
/** Currently active trigger pairs */
|
|
308
|
+
readonly activeTriggers: Map<string, CollisionPair>;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Gets the collision event bus.
|
|
312
|
+
*
|
|
313
|
+
* @returns The collision event bus
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```typescript
|
|
317
|
+
* import { getCollisionEventBus } from 'blecsd';
|
|
318
|
+
*
|
|
319
|
+
* const bus = getCollisionEventBus();
|
|
320
|
+
* bus.on('collisionStart', ({ entityA, entityB }) => {
|
|
321
|
+
* console.log(`Collision between ${entityA} and ${entityB}`);
|
|
322
|
+
* });
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
declare function getCollisionEventBus(): EventBus<CollisionEventMap>;
|
|
326
|
+
/**
|
|
327
|
+
* Gets the current active collision pairs.
|
|
328
|
+
*
|
|
329
|
+
* @returns Map of active collision pairs
|
|
330
|
+
*/
|
|
331
|
+
declare function getActiveCollisions(): ReadonlyMap<string, CollisionPair>;
|
|
332
|
+
/**
|
|
333
|
+
* Gets the current active trigger pairs.
|
|
334
|
+
*
|
|
335
|
+
* @returns Map of active trigger pairs
|
|
336
|
+
*/
|
|
337
|
+
declare function getActiveTriggers(): ReadonlyMap<string, CollisionPair>;
|
|
338
|
+
/**
|
|
339
|
+
* Resets the collision system state.
|
|
340
|
+
* Useful for testing or scene changes.
|
|
341
|
+
*/
|
|
342
|
+
declare function resetCollisionState(): void;
|
|
343
|
+
/**
|
|
344
|
+
* Query all entities with the Collider component.
|
|
345
|
+
*
|
|
346
|
+
* @param world - The ECS world
|
|
347
|
+
* @returns Array of entity IDs with Collider component
|
|
348
|
+
*/
|
|
349
|
+
declare function queryColliders(world: World): number[];
|
|
350
|
+
/**
|
|
351
|
+
* Detects all collisions between entities in the world.
|
|
352
|
+
* Uses a simple O(n^2) broad phase (suitable for small entity counts).
|
|
353
|
+
*
|
|
354
|
+
* @param world - The ECS world
|
|
355
|
+
* @returns Array of collision pairs
|
|
356
|
+
*/
|
|
357
|
+
declare function detectCollisions(world: World): CollisionPair[];
|
|
358
|
+
/**
|
|
359
|
+
* Collision system that detects collisions and emits events.
|
|
360
|
+
*
|
|
361
|
+
* This system should be registered in the UPDATE phase, after movement.
|
|
362
|
+
* It detects all collisions between entities with Collider and Position
|
|
363
|
+
* components, and emits events for collision start/end and trigger enter/exit.
|
|
364
|
+
*
|
|
365
|
+
* @param world - The ECS world to process
|
|
366
|
+
* @returns The world (unchanged reference)
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* import { createScheduler, LoopPhase, collisionSystem, getCollisionEventBus } from 'blecsd';
|
|
371
|
+
*
|
|
372
|
+
* const scheduler = createScheduler();
|
|
373
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, collisionSystem, 10); // After movement
|
|
374
|
+
*
|
|
375
|
+
* // Listen for collisions
|
|
376
|
+
* const bus = getCollisionEventBus();
|
|
377
|
+
* bus.on('collisionStart', ({ entityA, entityB }) => {
|
|
378
|
+
* console.log(`Collision: ${entityA} hit ${entityB}`);
|
|
379
|
+
* });
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
declare const collisionSystem: System;
|
|
383
|
+
/**
|
|
384
|
+
* Creates a new collision system.
|
|
385
|
+
*
|
|
386
|
+
* Factory function that returns the collisionSystem.
|
|
387
|
+
*
|
|
388
|
+
* @returns The collision system function
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```typescript
|
|
392
|
+
* import { createCollisionSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
393
|
+
*
|
|
394
|
+
* const scheduler = createScheduler();
|
|
395
|
+
* const system = createCollisionSystem();
|
|
396
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, system, 10);
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
declare function createCollisionSystem(): System;
|
|
400
|
+
/**
|
|
401
|
+
* Registers the collision system with a scheduler.
|
|
402
|
+
*
|
|
403
|
+
* Convenience function that registers collisionSystem in the UPDATE phase.
|
|
404
|
+
* Uses priority 10 by default to run after movement (priority 0).
|
|
405
|
+
*
|
|
406
|
+
* @param scheduler - The scheduler to register with
|
|
407
|
+
* @param priority - Optional priority within the UPDATE phase (default: 10)
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```typescript
|
|
411
|
+
* import { createScheduler, registerCollisionSystem } from 'blecsd';
|
|
412
|
+
*
|
|
413
|
+
* const scheduler = createScheduler();
|
|
414
|
+
* registerCollisionSystem(scheduler);
|
|
415
|
+
*
|
|
416
|
+
* // Collisions will be detected after movement
|
|
417
|
+
* scheduler.run(world, deltaTime);
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
declare function registerCollisionSystem(scheduler: Scheduler, priority?: number): void;
|
|
421
|
+
/**
|
|
422
|
+
* Checks if an entity is currently colliding with any other entity.
|
|
423
|
+
*
|
|
424
|
+
* @param eid - The entity to check
|
|
425
|
+
* @returns true if entity is in any active collision
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* ```typescript
|
|
429
|
+
* import { isColliding } from 'blecsd';
|
|
430
|
+
*
|
|
431
|
+
* if (isColliding(player)) {
|
|
432
|
+
* console.log('Player is touching something!');
|
|
433
|
+
* }
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
declare function isColliding(eid: number): boolean;
|
|
437
|
+
/**
|
|
438
|
+
* Checks if an entity is currently in any trigger zone.
|
|
439
|
+
*
|
|
440
|
+
* @param eid - The entity to check
|
|
441
|
+
* @returns true if entity is in any active trigger
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* import { isInTrigger } from 'blecsd';
|
|
446
|
+
*
|
|
447
|
+
* if (isInTrigger(player)) {
|
|
448
|
+
* console.log('Player is in a trigger zone!');
|
|
449
|
+
* }
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
declare function isInTrigger(eid: number): boolean;
|
|
453
|
+
/**
|
|
454
|
+
* Gets all entities currently colliding with a specific entity.
|
|
455
|
+
*
|
|
456
|
+
* @param eid - The entity to check
|
|
457
|
+
* @returns Array of entity IDs colliding with this entity
|
|
458
|
+
*
|
|
459
|
+
* @example
|
|
460
|
+
* ```typescript
|
|
461
|
+
* import { getCollidingEntities } from 'blecsd';
|
|
462
|
+
*
|
|
463
|
+
* const enemies = getCollidingEntities(player);
|
|
464
|
+
* for (const enemy of enemies) {
|
|
465
|
+
* // Handle collision with each enemy
|
|
466
|
+
* }
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
469
|
+
declare function getCollidingEntities(eid: number): number[];
|
|
470
|
+
/**
|
|
471
|
+
* Gets all trigger zones an entity is currently in.
|
|
472
|
+
*
|
|
473
|
+
* @param eid - The entity to check
|
|
474
|
+
* @returns Array of entity IDs of triggers this entity is in
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* import { getTriggerZones } from 'blecsd';
|
|
479
|
+
*
|
|
480
|
+
* const zones = getTriggerZones(player);
|
|
481
|
+
* for (const zone of zones) {
|
|
482
|
+
* // Handle being in each zone
|
|
483
|
+
* }
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function getTriggerZones(eid: number): number[];
|
|
487
|
+
/**
|
|
488
|
+
* Checks if two specific entities are currently colliding.
|
|
489
|
+
*
|
|
490
|
+
* @param eidA - First entity
|
|
491
|
+
* @param eidB - Second entity
|
|
492
|
+
* @returns true if the entities are colliding
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```typescript
|
|
496
|
+
* import { areColliding } from 'blecsd';
|
|
497
|
+
*
|
|
498
|
+
* if (areColliding(player, enemy)) {
|
|
499
|
+
* // Handle player-enemy collision
|
|
500
|
+
* }
|
|
501
|
+
* ```
|
|
502
|
+
*/
|
|
503
|
+
declare function areColliding(eidA: number, eidB: number): boolean;
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Drag and drop system for interactive entities.
|
|
507
|
+
*
|
|
508
|
+
* Handles drag initiation, position updates during drag, and drop handling.
|
|
509
|
+
* Supports constraints like parent bounds, axis locking, and grid snapping.
|
|
510
|
+
*
|
|
511
|
+
* @module systems/dragSystem
|
|
512
|
+
*/
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Drag constraint configuration.
|
|
516
|
+
*/
|
|
517
|
+
interface DragConstraints {
|
|
518
|
+
/** Constrain to parent bounds */
|
|
519
|
+
constrainToParent?: boolean;
|
|
520
|
+
/** Lock to a single axis */
|
|
521
|
+
constrainAxis?: 'x' | 'y' | null;
|
|
522
|
+
/** Snap to grid */
|
|
523
|
+
snapToGrid?: {
|
|
524
|
+
x: number;
|
|
525
|
+
y: number;
|
|
526
|
+
} | null;
|
|
527
|
+
/** Minimum X position */
|
|
528
|
+
minX?: number;
|
|
529
|
+
/** Maximum X position */
|
|
530
|
+
maxX?: number;
|
|
531
|
+
/** Minimum Y position */
|
|
532
|
+
minY?: number;
|
|
533
|
+
/** Maximum Y position */
|
|
534
|
+
maxY?: number;
|
|
535
|
+
/** Bring entity to front (highest z-index) when dragging starts */
|
|
536
|
+
bringToFront?: boolean;
|
|
537
|
+
/** Z-index to use when bringing to front */
|
|
538
|
+
frontZIndex?: number;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Drag verification callback.
|
|
542
|
+
* Return false to cancel the drag movement.
|
|
543
|
+
*/
|
|
544
|
+
type DragVerifyCallback = (entity: Entity, dx: number, dy: number) => boolean;
|
|
545
|
+
/**
|
|
546
|
+
* Drag start event data.
|
|
547
|
+
*/
|
|
548
|
+
interface DragStartEvent {
|
|
549
|
+
/** Entity being dragged */
|
|
550
|
+
entity: Entity;
|
|
551
|
+
/** Starting X position */
|
|
552
|
+
startX: number;
|
|
553
|
+
/** Starting Y position */
|
|
554
|
+
startY: number;
|
|
555
|
+
/** Mouse X at drag start */
|
|
556
|
+
mouseX: number;
|
|
557
|
+
/** Mouse Y at drag start */
|
|
558
|
+
mouseY: number;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Drag move event data.
|
|
562
|
+
*/
|
|
563
|
+
interface DragMoveEvent {
|
|
564
|
+
/** Entity being dragged */
|
|
565
|
+
entity: Entity;
|
|
566
|
+
/** Current X position */
|
|
567
|
+
x: number;
|
|
568
|
+
/** Current Y position */
|
|
569
|
+
y: number;
|
|
570
|
+
/** Change in X since last move */
|
|
571
|
+
dx: number;
|
|
572
|
+
/** Change in Y since last move */
|
|
573
|
+
dy: number;
|
|
574
|
+
/** Current mouse X */
|
|
575
|
+
mouseX: number;
|
|
576
|
+
/** Current mouse Y */
|
|
577
|
+
mouseY: number;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Drag end event data.
|
|
581
|
+
*/
|
|
582
|
+
interface DragEndEvent {
|
|
583
|
+
/** Entity that was dragged */
|
|
584
|
+
entity: Entity;
|
|
585
|
+
/** Final X position */
|
|
586
|
+
x: number;
|
|
587
|
+
/** Final Y position */
|
|
588
|
+
y: number;
|
|
589
|
+
/** Total change in X */
|
|
590
|
+
totalDx: number;
|
|
591
|
+
/** Total change in Y */
|
|
592
|
+
totalDy: number;
|
|
593
|
+
/** Whether drag was cancelled */
|
|
594
|
+
cancelled: boolean;
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Drop event data.
|
|
598
|
+
*/
|
|
599
|
+
interface DropEvent {
|
|
600
|
+
/** Entity that was dropped */
|
|
601
|
+
entity: Entity;
|
|
602
|
+
/** Drop X position */
|
|
603
|
+
x: number;
|
|
604
|
+
/** Drop Y position */
|
|
605
|
+
y: number;
|
|
606
|
+
/** Entity under drop point (if any) */
|
|
607
|
+
dropTarget: Entity | null;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Drag system event map.
|
|
611
|
+
*/
|
|
612
|
+
interface DragEventMap {
|
|
613
|
+
dragstart: DragStartEvent;
|
|
614
|
+
drag: DragMoveEvent;
|
|
615
|
+
dragend: DragEndEvent;
|
|
616
|
+
drop: DropEvent;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Current drag state.
|
|
620
|
+
*/
|
|
621
|
+
interface DragState {
|
|
622
|
+
/** Entity currently being dragged */
|
|
623
|
+
dragging: Entity | null;
|
|
624
|
+
/** Starting position of drag */
|
|
625
|
+
startX: number;
|
|
626
|
+
startY: number;
|
|
627
|
+
/** Mouse offset from entity origin at drag start */
|
|
628
|
+
offsetX: number;
|
|
629
|
+
offsetY: number;
|
|
630
|
+
/** Last known position during drag */
|
|
631
|
+
lastX: number;
|
|
632
|
+
lastY: number;
|
|
633
|
+
/** Constraints for current drag */
|
|
634
|
+
constraints: DragConstraints;
|
|
635
|
+
/** Verification callback */
|
|
636
|
+
verifyCallback: DragVerifyCallback | null;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Sets drag constraints for an entity.
|
|
640
|
+
*
|
|
641
|
+
* @param eid - The entity ID
|
|
642
|
+
* @param constraints - Drag constraints
|
|
643
|
+
*
|
|
644
|
+
* @example
|
|
645
|
+
* ```typescript
|
|
646
|
+
* import { setDragConstraints } from 'blecsd';
|
|
647
|
+
*
|
|
648
|
+
* // Constrain to parent bounds
|
|
649
|
+
* setDragConstraints(entity, { constrainToParent: true });
|
|
650
|
+
*
|
|
651
|
+
* // Lock to horizontal axis with grid snap
|
|
652
|
+
* setDragConstraints(entity, {
|
|
653
|
+
* constrainAxis: 'x',
|
|
654
|
+
* snapToGrid: { x: 10, y: 10 }
|
|
655
|
+
* });
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
declare function setDragConstraints(eid: Entity, constraints: DragConstraints): void;
|
|
659
|
+
/**
|
|
660
|
+
* Gets drag constraints for an entity.
|
|
661
|
+
*
|
|
662
|
+
* @param eid - The entity ID
|
|
663
|
+
* @returns Drag constraints or empty object
|
|
664
|
+
*/
|
|
665
|
+
declare function getDragConstraints(eid: Entity): DragConstraints;
|
|
666
|
+
/**
|
|
667
|
+
* Clears drag constraints for an entity.
|
|
668
|
+
*
|
|
669
|
+
* @param eid - The entity ID
|
|
670
|
+
*/
|
|
671
|
+
declare function clearDragConstraints(eid: Entity): void;
|
|
672
|
+
/**
|
|
673
|
+
* Sets a drag verification callback for an entity.
|
|
674
|
+
*
|
|
675
|
+
* @param eid - The entity ID
|
|
676
|
+
* @param callback - Verification callback (return false to cancel movement)
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* import { setDragVerifyCallback } from 'blecsd';
|
|
681
|
+
*
|
|
682
|
+
* // Prevent dragging into certain areas
|
|
683
|
+
* setDragVerifyCallback(entity, (entity, dx, dy) => {
|
|
684
|
+
* const newX = Position.x[entity] + dx;
|
|
685
|
+
* const newY = Position.y[entity] + dy;
|
|
686
|
+
*
|
|
687
|
+
* // Don't allow dragging into forbidden zone
|
|
688
|
+
* if (newX > 50 && newX < 60) return false;
|
|
689
|
+
*
|
|
690
|
+
* return true;
|
|
691
|
+
* });
|
|
692
|
+
* ```
|
|
693
|
+
*/
|
|
694
|
+
declare function setDragVerifyCallback(eid: Entity, callback: DragVerifyCallback | null): void;
|
|
695
|
+
/**
|
|
696
|
+
* Gets the drag verification callback for an entity.
|
|
697
|
+
*
|
|
698
|
+
* @param eid - The entity ID
|
|
699
|
+
* @returns The verification callback or null
|
|
700
|
+
*/
|
|
701
|
+
declare function getDragVerifyCallback(eid: Entity): DragVerifyCallback | null;
|
|
702
|
+
/**
|
|
703
|
+
* Creates a drag system with event handling.
|
|
704
|
+
*
|
|
705
|
+
* @param eventBus - Event bus for drag events
|
|
706
|
+
* @returns Drag system API
|
|
707
|
+
*
|
|
708
|
+
* @example
|
|
709
|
+
* ```typescript
|
|
710
|
+
* import { createDragSystem, createEventBus } from 'blecsd';
|
|
711
|
+
*
|
|
712
|
+
* const dragEvents = createEventBus<DragEventMap>();
|
|
713
|
+
* const dragSystem = createDragSystem(dragEvents);
|
|
714
|
+
*
|
|
715
|
+
* // Listen for drag events
|
|
716
|
+
* dragEvents.on('dragstart', (e) => {
|
|
717
|
+
* console.log(`Started dragging entity ${e.entity}`);
|
|
718
|
+
* });
|
|
719
|
+
*
|
|
720
|
+
* dragEvents.on('drag', (e) => {
|
|
721
|
+
* console.log(`Dragged to ${e.x}, ${e.y}`);
|
|
722
|
+
* });
|
|
723
|
+
*
|
|
724
|
+
* dragEvents.on('dragend', (e) => {
|
|
725
|
+
* console.log(`Drag ended, cancelled: ${e.cancelled}`);
|
|
726
|
+
* });
|
|
727
|
+
*
|
|
728
|
+
* // In mouse event handler
|
|
729
|
+
* function onMouseDown(x: number, y: number, entity: Entity) {
|
|
730
|
+
* if (dragSystem.canDrag(world, entity)) {
|
|
731
|
+
* dragSystem.startDrag(world, entity, x, y);
|
|
732
|
+
* }
|
|
733
|
+
* }
|
|
734
|
+
*
|
|
735
|
+
* function onMouseMove(x: number, y: number) {
|
|
736
|
+
* dragSystem.updateDrag(world, x, y);
|
|
737
|
+
* }
|
|
738
|
+
*
|
|
739
|
+
* function onMouseUp(x: number, y: number, dropTarget: Entity | null) {
|
|
740
|
+
* dragSystem.endDrag(world, dropTarget);
|
|
741
|
+
* }
|
|
742
|
+
* ```
|
|
743
|
+
*/
|
|
744
|
+
declare function createDragSystem(eventBus: EventBus<DragEventMap>): {
|
|
745
|
+
/**
|
|
746
|
+
* Gets the current drag state.
|
|
747
|
+
*/
|
|
748
|
+
getState(): Readonly<DragState>;
|
|
749
|
+
/**
|
|
750
|
+
* Checks if an entity is currently being dragged.
|
|
751
|
+
*/
|
|
752
|
+
isDragging(): boolean;
|
|
753
|
+
/**
|
|
754
|
+
* Gets the entity currently being dragged.
|
|
755
|
+
*/
|
|
756
|
+
getDraggingEntity(): Entity | null;
|
|
757
|
+
/**
|
|
758
|
+
* Checks if an entity can be dragged.
|
|
759
|
+
*
|
|
760
|
+
* @param world - The ECS world
|
|
761
|
+
* @param eid - The entity to check
|
|
762
|
+
*/
|
|
763
|
+
canDrag(world: World, eid: Entity): boolean;
|
|
764
|
+
/**
|
|
765
|
+
* Starts dragging an entity.
|
|
766
|
+
*
|
|
767
|
+
* @param world - The ECS world
|
|
768
|
+
* @param eid - The entity to drag
|
|
769
|
+
* @param mouseX - Current mouse X
|
|
770
|
+
* @param mouseY - Current mouse Y
|
|
771
|
+
* @returns True if drag started successfully
|
|
772
|
+
*/
|
|
773
|
+
startDrag(world: World, eid: Entity, mouseX: number, mouseY: number): boolean;
|
|
774
|
+
/**
|
|
775
|
+
* Updates the drag position based on mouse movement.
|
|
776
|
+
*
|
|
777
|
+
* @param world - The ECS world
|
|
778
|
+
* @param mouseX - Current mouse X
|
|
779
|
+
* @param mouseY - Current mouse Y
|
|
780
|
+
* @returns True if position was updated
|
|
781
|
+
*/
|
|
782
|
+
updateDrag(world: World, mouseX: number, mouseY: number): boolean;
|
|
783
|
+
/**
|
|
784
|
+
* Ends the current drag operation.
|
|
785
|
+
*
|
|
786
|
+
* @param world - The ECS world
|
|
787
|
+
* @param dropTarget - Entity under the drop point (if any)
|
|
788
|
+
* @param cancelled - Whether the drag was cancelled
|
|
789
|
+
*/
|
|
790
|
+
endDrag(world: World, dropTarget?: Entity | null, cancelled?: boolean): void;
|
|
791
|
+
/**
|
|
792
|
+
* Cancels the current drag and restores original position.
|
|
793
|
+
*
|
|
794
|
+
* @param world - The ECS world
|
|
795
|
+
*/
|
|
796
|
+
cancelDrag(world: World): void;
|
|
797
|
+
};
|
|
798
|
+
/**
|
|
799
|
+
* Resets all drag-related stores.
|
|
800
|
+
* Useful for testing.
|
|
801
|
+
*/
|
|
802
|
+
declare function resetDragStores(): void;
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Focus Management System
|
|
806
|
+
*
|
|
807
|
+
* Handles keyboard focus navigation and focus state management.
|
|
808
|
+
* Tracks which entity is focused and provides tab/arrow navigation.
|
|
809
|
+
*
|
|
810
|
+
* @module systems/focusSystem
|
|
811
|
+
*
|
|
812
|
+
* @example
|
|
813
|
+
* ```typescript
|
|
814
|
+
* import {
|
|
815
|
+
* focusSystem,
|
|
816
|
+
* focusNext,
|
|
817
|
+
* focusPrev,
|
|
818
|
+
* focusEntity,
|
|
819
|
+
* getFocused,
|
|
820
|
+
* blurAll,
|
|
821
|
+
* } from 'blecsd';
|
|
822
|
+
*
|
|
823
|
+
* // Register with scheduler
|
|
824
|
+
* const scheduler = createScheduler();
|
|
825
|
+
* scheduler.registerSystem(LoopPhase.INPUT, focusSystem);
|
|
826
|
+
*
|
|
827
|
+
* // Navigate focus
|
|
828
|
+
* focusNext(world); // Focus next element
|
|
829
|
+
* focusPrev(world); // Focus previous element
|
|
830
|
+
*
|
|
831
|
+
* // Direct focus
|
|
832
|
+
* focusEntity(world, buttonEntity);
|
|
833
|
+
*
|
|
834
|
+
* // Check current focus
|
|
835
|
+
* const focused = getFocused(world);
|
|
836
|
+
* ```
|
|
837
|
+
*/
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Focus event types.
|
|
841
|
+
*/
|
|
842
|
+
type FocusEventType = 'focus' | 'blur';
|
|
843
|
+
/**
|
|
844
|
+
* Focus event data.
|
|
845
|
+
*/
|
|
846
|
+
interface FocusEventData {
|
|
847
|
+
/** The entity gaining/losing focus */
|
|
848
|
+
readonly entity: Entity;
|
|
849
|
+
/** The previously focused entity (for focus events) */
|
|
850
|
+
readonly previousEntity: Entity | null;
|
|
851
|
+
/** The next focused entity (for blur events) */
|
|
852
|
+
readonly nextEntity: Entity | null;
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Focus event map for type-safe event handling.
|
|
856
|
+
*/
|
|
857
|
+
interface FocusEventMap {
|
|
858
|
+
focus: FocusEventData;
|
|
859
|
+
blur: FocusEventData;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Gets the focus event bus, creating if needed.
|
|
863
|
+
*
|
|
864
|
+
* @returns The focus event bus
|
|
865
|
+
*
|
|
866
|
+
* @example
|
|
867
|
+
* ```typescript
|
|
868
|
+
* const bus = getFocusEventBus();
|
|
869
|
+
* bus.on('focus', (data) => {
|
|
870
|
+
* console.log(`Entity ${data.entity} focused`);
|
|
871
|
+
* });
|
|
872
|
+
* ```
|
|
873
|
+
*/
|
|
874
|
+
declare function getFocusEventBus(): EventBus<FocusEventMap>;
|
|
875
|
+
/**
|
|
876
|
+
* Resets the focus event bus. Used for testing.
|
|
877
|
+
* @internal
|
|
878
|
+
*/
|
|
879
|
+
declare function resetFocusEventBus(): void;
|
|
880
|
+
/**
|
|
881
|
+
* Gets all focusable entities sorted by tab order.
|
|
882
|
+
*
|
|
883
|
+
* @param world - The ECS world
|
|
884
|
+
* @returns Sorted array of focusable entity IDs
|
|
885
|
+
*/
|
|
886
|
+
declare function getFocusableEntities(world: World): Entity[];
|
|
887
|
+
/**
|
|
888
|
+
* Gets the currently focused entity.
|
|
889
|
+
*
|
|
890
|
+
* @param world - The ECS world
|
|
891
|
+
* @returns The focused entity or null if none focused
|
|
892
|
+
*
|
|
893
|
+
* @example
|
|
894
|
+
* ```typescript
|
|
895
|
+
* const focused = getFocused(world);
|
|
896
|
+
* if (focused) {
|
|
897
|
+
* console.log(`Entity ${focused} is focused`);
|
|
898
|
+
* }
|
|
899
|
+
* ```
|
|
900
|
+
*/
|
|
901
|
+
declare function getFocused(world: World): Entity | null;
|
|
902
|
+
/**
|
|
903
|
+
* Focuses a specific entity.
|
|
904
|
+
*
|
|
905
|
+
* @param world - The ECS world
|
|
906
|
+
* @param eid - The entity to focus
|
|
907
|
+
* @returns true if focus was set successfully
|
|
908
|
+
*
|
|
909
|
+
* @example
|
|
910
|
+
* ```typescript
|
|
911
|
+
* focusEntity(world, buttonEntity);
|
|
912
|
+
* ```
|
|
913
|
+
*/
|
|
914
|
+
declare function focusEntity(world: World, eid: Entity): boolean;
|
|
915
|
+
/**
|
|
916
|
+
* Removes focus from all entities.
|
|
917
|
+
*
|
|
918
|
+
* @param world - The ECS world
|
|
919
|
+
*
|
|
920
|
+
* @example
|
|
921
|
+
* ```typescript
|
|
922
|
+
* blurAll(world);
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
declare function blurAll(world: World): void;
|
|
926
|
+
/**
|
|
927
|
+
* Focuses the next focusable entity in tab order.
|
|
928
|
+
*
|
|
929
|
+
* @param world - The ECS world
|
|
930
|
+
* @returns The newly focused entity, or null if none available
|
|
931
|
+
*
|
|
932
|
+
* @example
|
|
933
|
+
* ```typescript
|
|
934
|
+
* // Handle Tab key
|
|
935
|
+
* if (key === 'Tab') {
|
|
936
|
+
* focusNext(world);
|
|
937
|
+
* }
|
|
938
|
+
* ```
|
|
939
|
+
*/
|
|
940
|
+
declare function focusNext(world: World): Entity | null;
|
|
941
|
+
/**
|
|
942
|
+
* Focuses the previous focusable entity in tab order.
|
|
943
|
+
*
|
|
944
|
+
* @param world - The ECS world
|
|
945
|
+
* @returns The newly focused entity, or null if none available
|
|
946
|
+
*
|
|
947
|
+
* @example
|
|
948
|
+
* ```typescript
|
|
949
|
+
* // Handle Shift+Tab key
|
|
950
|
+
* if (key === 'Tab' && shiftKey) {
|
|
951
|
+
* focusPrev(world);
|
|
952
|
+
* }
|
|
953
|
+
* ```
|
|
954
|
+
*/
|
|
955
|
+
declare function focusPrev(world: World): Entity | null;
|
|
956
|
+
/**
|
|
957
|
+
* Focuses the first focusable entity.
|
|
958
|
+
*
|
|
959
|
+
* @param world - The ECS world
|
|
960
|
+
* @returns The focused entity, or null if none available
|
|
961
|
+
*/
|
|
962
|
+
declare function focusFirst(world: World): Entity | null;
|
|
963
|
+
/**
|
|
964
|
+
* Focuses the last focusable entity.
|
|
965
|
+
*
|
|
966
|
+
* @param world - The ECS world
|
|
967
|
+
* @returns The focused entity, or null if none available
|
|
968
|
+
*/
|
|
969
|
+
declare function focusLast(world: World): Entity | null;
|
|
970
|
+
/**
|
|
971
|
+
* Pushes current focus onto the stack and focuses a new entity.
|
|
972
|
+
*
|
|
973
|
+
* Use this when opening modals or popups to preserve the previous focus
|
|
974
|
+
* state for restoration later.
|
|
975
|
+
*
|
|
976
|
+
* @param world - The ECS world
|
|
977
|
+
* @param eid - The entity to focus (e.g., modal or popup)
|
|
978
|
+
* @returns true if push was successful
|
|
979
|
+
*
|
|
980
|
+
* @example
|
|
981
|
+
* ```typescript
|
|
982
|
+
* import { focusPush, focusPop } from 'blecsd';
|
|
983
|
+
*
|
|
984
|
+
* // Open modal - save current focus and focus modal
|
|
985
|
+
* function openModal(world: World, modalEntity: Entity): void {
|
|
986
|
+
* focusPush(world, modalEntity);
|
|
987
|
+
* }
|
|
988
|
+
*
|
|
989
|
+
* // Close modal - restore previous focus
|
|
990
|
+
* function closeModal(world: World): void {
|
|
991
|
+
* focusPop(world);
|
|
992
|
+
* }
|
|
993
|
+
* ```
|
|
994
|
+
*/
|
|
995
|
+
declare function focusPush(world: World, eid: Entity): boolean;
|
|
996
|
+
/**
|
|
997
|
+
* Pops the focus stack and restores the previous focus.
|
|
998
|
+
*
|
|
999
|
+
* Use this when closing modals or popups to restore focus to the
|
|
1000
|
+
* element that was focused before.
|
|
1001
|
+
*
|
|
1002
|
+
* @param world - The ECS world
|
|
1003
|
+
* @returns The restored entity, or null if stack was empty
|
|
1004
|
+
*
|
|
1005
|
+
* @example
|
|
1006
|
+
* ```typescript
|
|
1007
|
+
* import { focusPop } from 'blecsd';
|
|
1008
|
+
*
|
|
1009
|
+
* // Close modal and restore focus
|
|
1010
|
+
* const previousFocus = focusPop(world);
|
|
1011
|
+
* if (previousFocus) {
|
|
1012
|
+
* console.log(`Focus restored to entity ${previousFocus}`);
|
|
1013
|
+
* }
|
|
1014
|
+
* ```
|
|
1015
|
+
*/
|
|
1016
|
+
declare function focusPop(world: World): Entity | null;
|
|
1017
|
+
/**
|
|
1018
|
+
* Saves the current focus without affecting the stack.
|
|
1019
|
+
*
|
|
1020
|
+
* Use this for temporary focus changes that need to be restored
|
|
1021
|
+
* without the full stack mechanism.
|
|
1022
|
+
*
|
|
1023
|
+
* @param world - The ECS world
|
|
1024
|
+
*
|
|
1025
|
+
* @example
|
|
1026
|
+
* ```typescript
|
|
1027
|
+
* import { saveFocus, restoreFocus } from 'blecsd';
|
|
1028
|
+
*
|
|
1029
|
+
* // Save current focus before temporary change
|
|
1030
|
+
* saveFocus(world);
|
|
1031
|
+
*
|
|
1032
|
+
* // ... do something that changes focus ...
|
|
1033
|
+
*
|
|
1034
|
+
* // Restore the saved focus
|
|
1035
|
+
* restoreFocus(world);
|
|
1036
|
+
* ```
|
|
1037
|
+
*/
|
|
1038
|
+
declare function saveFocus(world: World): void;
|
|
1039
|
+
/**
|
|
1040
|
+
* Restores the previously saved focus.
|
|
1041
|
+
*
|
|
1042
|
+
* @param world - The ECS world
|
|
1043
|
+
* @returns The restored entity, or null if no saved focus or entity invalid
|
|
1044
|
+
*
|
|
1045
|
+
* @example
|
|
1046
|
+
* ```typescript
|
|
1047
|
+
* import { restoreFocus } from 'blecsd';
|
|
1048
|
+
*
|
|
1049
|
+
* const restored = restoreFocus(world);
|
|
1050
|
+
* ```
|
|
1051
|
+
*/
|
|
1052
|
+
declare function restoreFocus(world: World): Entity | null;
|
|
1053
|
+
/**
|
|
1054
|
+
* Rewinds focus to the last valid entity in the stack.
|
|
1055
|
+
*
|
|
1056
|
+
* This is useful when the currently focused entity is destroyed or
|
|
1057
|
+
* becomes unfocusable. It searches backwards through the focus stack
|
|
1058
|
+
* to find an entity that still exists and is focusable.
|
|
1059
|
+
*
|
|
1060
|
+
* @param world - The ECS world
|
|
1061
|
+
* @returns The entity that received focus, or null if none found
|
|
1062
|
+
*
|
|
1063
|
+
* @example
|
|
1064
|
+
* ```typescript
|
|
1065
|
+
* import { rewindFocus } from 'blecsd';
|
|
1066
|
+
*
|
|
1067
|
+
* // After destroying a focused entity
|
|
1068
|
+
* rewindFocus(world);
|
|
1069
|
+
* ```
|
|
1070
|
+
*/
|
|
1071
|
+
declare function rewindFocus(world: World): Entity | null;
|
|
1072
|
+
/**
|
|
1073
|
+
* Moves focus by a specified offset in the tab order.
|
|
1074
|
+
*
|
|
1075
|
+
* Positive offset moves forward (like Tab), negative moves backward
|
|
1076
|
+
* (like Shift+Tab). The offset wraps around at the ends.
|
|
1077
|
+
*
|
|
1078
|
+
* @param world - The ECS world
|
|
1079
|
+
* @param offset - Number of positions to move (positive=forward, negative=backward)
|
|
1080
|
+
* @returns The newly focused entity, or null if none available
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
* ```typescript
|
|
1084
|
+
* import { focusOffset } from 'blecsd';
|
|
1085
|
+
*
|
|
1086
|
+
* // Move focus forward by 2
|
|
1087
|
+
* focusOffset(world, 2);
|
|
1088
|
+
*
|
|
1089
|
+
* // Move focus backward by 1
|
|
1090
|
+
* focusOffset(world, -1);
|
|
1091
|
+
* ```
|
|
1092
|
+
*/
|
|
1093
|
+
declare function focusOffset(world: World, offset: number): Entity | null;
|
|
1094
|
+
/**
|
|
1095
|
+
* Gets the current focus stack depth.
|
|
1096
|
+
*
|
|
1097
|
+
* @param world - The ECS world
|
|
1098
|
+
* @returns Number of entries in the focus stack
|
|
1099
|
+
*/
|
|
1100
|
+
declare function getFocusStackDepth(world: World): number;
|
|
1101
|
+
/**
|
|
1102
|
+
* Clears the focus stack.
|
|
1103
|
+
*
|
|
1104
|
+
* Use with caution - this removes all saved focus states.
|
|
1105
|
+
*
|
|
1106
|
+
* @param world - The ECS world
|
|
1107
|
+
*/
|
|
1108
|
+
declare function clearFocusStack(world: World): void;
|
|
1109
|
+
/**
|
|
1110
|
+
* Peeks at the top of the focus stack without popping.
|
|
1111
|
+
*
|
|
1112
|
+
* @param world - The ECS world
|
|
1113
|
+
* @returns The entity at the top of the stack, or null if empty
|
|
1114
|
+
*/
|
|
1115
|
+
declare function peekFocusStack(world: World): Entity | null;
|
|
1116
|
+
/**
|
|
1117
|
+
* Focus system that processes focus-related input.
|
|
1118
|
+
*
|
|
1119
|
+
* Currently this system validates focus state (ensuring focused entity
|
|
1120
|
+
* is still focusable and visible). Tab key handling should be done
|
|
1121
|
+
* in the input system or user code.
|
|
1122
|
+
*
|
|
1123
|
+
* @param world - The ECS world
|
|
1124
|
+
* @returns The world
|
|
1125
|
+
*
|
|
1126
|
+
* @example
|
|
1127
|
+
* ```typescript
|
|
1128
|
+
* import { focusSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
1129
|
+
*
|
|
1130
|
+
* const scheduler = createScheduler();
|
|
1131
|
+
* scheduler.registerSystem(LoopPhase.INPUT, focusSystem);
|
|
1132
|
+
* ```
|
|
1133
|
+
*/
|
|
1134
|
+
declare const focusSystem: System;
|
|
1135
|
+
/**
|
|
1136
|
+
* Creates a focus system.
|
|
1137
|
+
*
|
|
1138
|
+
* @returns A new focus system function
|
|
1139
|
+
*/
|
|
1140
|
+
declare function createFocusSystem(): System;
|
|
1141
|
+
|
|
1142
|
+
/**
|
|
1143
|
+
* Frame budget manager and profiling.
|
|
1144
|
+
*
|
|
1145
|
+
* Measures per-system timing, tracks rolling statistics, and enforces
|
|
1146
|
+
* configurable frame time budgets per phase. Optional on-screen debug overlay.
|
|
1147
|
+
*
|
|
1148
|
+
* @module systems/frameBudget
|
|
1149
|
+
*/
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* Configuration for the frame budget manager.
|
|
1153
|
+
*/
|
|
1154
|
+
interface FrameBudgetConfig {
|
|
1155
|
+
/** Target frame time in ms (default: 16.67 = 60fps) */
|
|
1156
|
+
readonly targetFrameMs: number;
|
|
1157
|
+
/** Per-phase budget overrides in ms (phase -> budget) */
|
|
1158
|
+
readonly phaseBudgets: Readonly<Partial<Record<LoopPhase, number>>>;
|
|
1159
|
+
/** Number of frames to keep in rolling stats (default: 120) */
|
|
1160
|
+
readonly rollingWindowSize: number;
|
|
1161
|
+
/** Whether to emit warnings on budget overruns (default: true) */
|
|
1162
|
+
readonly warnOnOverrun: boolean;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Per-system timing record.
|
|
1166
|
+
*/
|
|
1167
|
+
interface SystemTiming {
|
|
1168
|
+
readonly name: string;
|
|
1169
|
+
readonly lastMs: number;
|
|
1170
|
+
readonly avgMs: number;
|
|
1171
|
+
readonly minMs: number;
|
|
1172
|
+
readonly maxMs: number;
|
|
1173
|
+
readonly p50Ms: number;
|
|
1174
|
+
readonly p95Ms: number;
|
|
1175
|
+
readonly p99Ms: number;
|
|
1176
|
+
readonly count: number;
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Frame-level statistics.
|
|
1180
|
+
*/
|
|
1181
|
+
interface FrameStats {
|
|
1182
|
+
readonly frameTimeMs: number;
|
|
1183
|
+
readonly avgFrameMs: number;
|
|
1184
|
+
readonly p50FrameMs: number;
|
|
1185
|
+
readonly p95FrameMs: number;
|
|
1186
|
+
readonly p99FrameMs: number;
|
|
1187
|
+
readonly fps: number;
|
|
1188
|
+
readonly avgFps: number;
|
|
1189
|
+
readonly totalFrames: number;
|
|
1190
|
+
readonly budgetOverruns: number;
|
|
1191
|
+
readonly systemTimings: readonly SystemTiming[];
|
|
1192
|
+
readonly phaseTimings: Readonly<Record<string, number>>;
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Budget alert emitted when a phase exceeds its budget.
|
|
1196
|
+
*/
|
|
1197
|
+
interface BudgetAlert {
|
|
1198
|
+
readonly phase: LoopPhase;
|
|
1199
|
+
readonly budgetMs: number;
|
|
1200
|
+
readonly actualMs: number;
|
|
1201
|
+
readonly frame: number;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Frame budget manager state.
|
|
1205
|
+
*/
|
|
1206
|
+
interface FrameBudgetManager {
|
|
1207
|
+
readonly config: FrameBudgetConfig;
|
|
1208
|
+
readonly stats: FrameStats;
|
|
1209
|
+
readonly alerts: readonly BudgetAlert[];
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Creates and activates the frame budget manager.
|
|
1213
|
+
*
|
|
1214
|
+
* @param config - Optional configuration overrides
|
|
1215
|
+
* @returns The frame budget manager
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```typescript
|
|
1219
|
+
* import { createFrameBudgetManager } from 'blecsd';
|
|
1220
|
+
*
|
|
1221
|
+
* const manager = createFrameBudgetManager({ targetFrameMs: 16.67 });
|
|
1222
|
+
* ```
|
|
1223
|
+
*/
|
|
1224
|
+
declare function createFrameBudgetManager(config?: Partial<FrameBudgetConfig>): FrameBudgetManager;
|
|
1225
|
+
/**
|
|
1226
|
+
* Records the execution time of a named system.
|
|
1227
|
+
*
|
|
1228
|
+
* @param name - The system name
|
|
1229
|
+
* @param timeMs - Execution time in milliseconds
|
|
1230
|
+
*/
|
|
1231
|
+
declare function recordFrameBudgetSystemTime(name: string, timeMs: number): void;
|
|
1232
|
+
/**
|
|
1233
|
+
* Records phase completion time and checks budget.
|
|
1234
|
+
*
|
|
1235
|
+
* @param phase - The loop phase
|
|
1236
|
+
* @param timeMs - Phase execution time in milliseconds
|
|
1237
|
+
*/
|
|
1238
|
+
declare function recordPhaseTime(phase: LoopPhase, timeMs: number): void;
|
|
1239
|
+
/**
|
|
1240
|
+
* Records a complete frame time.
|
|
1241
|
+
*
|
|
1242
|
+
* @param frameTimeMs - Total frame time in milliseconds
|
|
1243
|
+
*/
|
|
1244
|
+
declare function recordFrameTime(frameTimeMs: number): void;
|
|
1245
|
+
/**
|
|
1246
|
+
* Wraps a system with automatic timing.
|
|
1247
|
+
*
|
|
1248
|
+
* @param name - The system name for profiling
|
|
1249
|
+
* @param system - The system function to wrap
|
|
1250
|
+
* @returns A wrapped system that records its execution time
|
|
1251
|
+
*
|
|
1252
|
+
* @example
|
|
1253
|
+
* ```typescript
|
|
1254
|
+
* import { profiledSystem } from 'blecsd';
|
|
1255
|
+
*
|
|
1256
|
+
* const timedMovement = profiledSystem('movement', movementSystem);
|
|
1257
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, timedMovement);
|
|
1258
|
+
* ```
|
|
1259
|
+
*/
|
|
1260
|
+
declare function profiledSystem(name: string, system: System): System;
|
|
1261
|
+
/**
|
|
1262
|
+
* Gets current frame budget statistics.
|
|
1263
|
+
*
|
|
1264
|
+
* @returns The current stats snapshot
|
|
1265
|
+
*/
|
|
1266
|
+
declare function getFrameBudgetStats(): FrameBudgetManager;
|
|
1267
|
+
/**
|
|
1268
|
+
* Registers a callback for budget overrun alerts.
|
|
1269
|
+
*
|
|
1270
|
+
* @param callback - Alert handler
|
|
1271
|
+
*/
|
|
1272
|
+
declare function onBudgetAlert(callback: (alert: BudgetAlert) => void): void;
|
|
1273
|
+
/**
|
|
1274
|
+
* Resets all profiling data.
|
|
1275
|
+
*/
|
|
1276
|
+
declare function resetFrameBudget(): void;
|
|
1277
|
+
/**
|
|
1278
|
+
* Destroys the frame budget manager.
|
|
1279
|
+
*/
|
|
1280
|
+
declare function destroyFrameBudgetManager(): void;
|
|
1281
|
+
/**
|
|
1282
|
+
* Exports metrics as a JSON-serializable object for external analysis.
|
|
1283
|
+
*
|
|
1284
|
+
* @returns Metrics data
|
|
1285
|
+
*/
|
|
1286
|
+
declare function exportFrameBudgetMetrics(): Record<string, unknown>;
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Input system for processing keyboard and mouse events.
|
|
1290
|
+
* Handles hit testing, focus management, and event dispatch.
|
|
1291
|
+
* @module systems/inputSystem
|
|
1292
|
+
*/
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* Input event types that can be queued.
|
|
1296
|
+
*/
|
|
1297
|
+
type InputEventType = 'key' | 'mouse';
|
|
1298
|
+
/**
|
|
1299
|
+
* Queued key event.
|
|
1300
|
+
*/
|
|
1301
|
+
interface QueuedKeyEvent {
|
|
1302
|
+
type: 'key';
|
|
1303
|
+
event: KeyEvent;
|
|
1304
|
+
timestamp: number;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Queued mouse event.
|
|
1308
|
+
*/
|
|
1309
|
+
interface QueuedMouseEvent {
|
|
1310
|
+
type: 'mouse';
|
|
1311
|
+
event: MouseEvent;
|
|
1312
|
+
timestamp: number;
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Union of all queued input events.
|
|
1316
|
+
*/
|
|
1317
|
+
type QueuedInputEvent = QueuedKeyEvent | QueuedMouseEvent;
|
|
1318
|
+
/**
|
|
1319
|
+
* Result of hit testing a point.
|
|
1320
|
+
*/
|
|
1321
|
+
interface HitTestResult {
|
|
1322
|
+
/** Entity that was hit */
|
|
1323
|
+
entity: Entity;
|
|
1324
|
+
/** Local X coordinate within the entity */
|
|
1325
|
+
localX: number;
|
|
1326
|
+
/** Local Y coordinate within the entity */
|
|
1327
|
+
localY: number;
|
|
1328
|
+
/** Z-index of the entity */
|
|
1329
|
+
zIndex: number;
|
|
1330
|
+
}
|
|
1331
|
+
/**
|
|
1332
|
+
* Input system state and configuration.
|
|
1333
|
+
*/
|
|
1334
|
+
interface InputSystemState {
|
|
1335
|
+
/** Queue of pending input events */
|
|
1336
|
+
eventQueue: QueuedInputEvent[];
|
|
1337
|
+
/** Entity that currently has mouse capture (for drag operations) */
|
|
1338
|
+
capturedEntity: Entity | null;
|
|
1339
|
+
/** Last known mouse position */
|
|
1340
|
+
lastMouseX: number;
|
|
1341
|
+
lastMouseY: number;
|
|
1342
|
+
/** Entity under the mouse last frame */
|
|
1343
|
+
lastHoveredEntity: Entity | null;
|
|
1344
|
+
/** Global event bus for dispatching UI events */
|
|
1345
|
+
eventBus: EventBus<UIEventMap>;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Global input system state.
|
|
1349
|
+
* Can be accessed and modified for testing or custom input handling.
|
|
1350
|
+
*/
|
|
1351
|
+
declare const inputState: InputSystemState;
|
|
1352
|
+
/**
|
|
1353
|
+
* Resets input system state.
|
|
1354
|
+
* Useful for testing or when reinitializing the input system.
|
|
1355
|
+
*
|
|
1356
|
+
* @example
|
|
1357
|
+
* ```typescript
|
|
1358
|
+
* import { resetInputState } from 'blecsd';
|
|
1359
|
+
*
|
|
1360
|
+
* // Clear all pending events and state
|
|
1361
|
+
* resetInputState();
|
|
1362
|
+
* ```
|
|
1363
|
+
*/
|
|
1364
|
+
declare function resetInputState(): void;
|
|
1365
|
+
/**
|
|
1366
|
+
* Queues a keyboard event for processing.
|
|
1367
|
+
*
|
|
1368
|
+
* @param event - The parsed key event from the input stream
|
|
1369
|
+
*
|
|
1370
|
+
* @example
|
|
1371
|
+
* ```typescript
|
|
1372
|
+
* import { queueKeyEvent } from 'blecsd';
|
|
1373
|
+
*
|
|
1374
|
+
* // Queue a key event for next frame
|
|
1375
|
+
* queueKeyEvent({ name: 'a', ctrl: false, meta: false, shift: false, raw: 'a' });
|
|
1376
|
+
* ```
|
|
1377
|
+
*/
|
|
1378
|
+
declare function queueKeyEvent(event: KeyEvent): void;
|
|
1379
|
+
/**
|
|
1380
|
+
* Queues a mouse event for processing.
|
|
1381
|
+
*
|
|
1382
|
+
* @param event - The parsed mouse event from the input stream
|
|
1383
|
+
*
|
|
1384
|
+
* @example
|
|
1385
|
+
* ```typescript
|
|
1386
|
+
* import { queueMouseEvent } from 'blecsd';
|
|
1387
|
+
*
|
|
1388
|
+
* // Queue a mouse event for next frame
|
|
1389
|
+
* queueMouseEvent({ x: 10, y: 5, button: 'left', action: 'press', raw: '' });
|
|
1390
|
+
* ```
|
|
1391
|
+
*/
|
|
1392
|
+
declare function queueMouseEvent(event: MouseEvent): void;
|
|
1393
|
+
/**
|
|
1394
|
+
* Gets the current event queue.
|
|
1395
|
+
* Mainly useful for debugging and testing.
|
|
1396
|
+
*/
|
|
1397
|
+
declare function getEventQueue(): readonly QueuedInputEvent[];
|
|
1398
|
+
/**
|
|
1399
|
+
* Clears all queued events.
|
|
1400
|
+
*/
|
|
1401
|
+
declare function clearEventQueue(): void;
|
|
1402
|
+
/**
|
|
1403
|
+
* Gets the global input event bus.
|
|
1404
|
+
* Use this to subscribe to UI events from anywhere.
|
|
1405
|
+
*
|
|
1406
|
+
* @returns The global UI event bus
|
|
1407
|
+
*
|
|
1408
|
+
* @example
|
|
1409
|
+
* ```typescript
|
|
1410
|
+
* import { getInputEventBus } from 'blecsd';
|
|
1411
|
+
*
|
|
1412
|
+
* const eventBus = getInputEventBus();
|
|
1413
|
+
* eventBus.on('click', (event) => {
|
|
1414
|
+
* console.log(`Clicked at ${event.x}, ${event.y}`);
|
|
1415
|
+
* });
|
|
1416
|
+
* ```
|
|
1417
|
+
*/
|
|
1418
|
+
declare function getInputEventBus(): EventBus<UIEventMap>;
|
|
1419
|
+
/**
|
|
1420
|
+
* Captures mouse events to a specific entity.
|
|
1421
|
+
* While captured, all mouse events are sent to this entity
|
|
1422
|
+
* regardless of hit testing. Used for drag operations.
|
|
1423
|
+
*
|
|
1424
|
+
* @param entity - Entity to capture events to, or null to release
|
|
1425
|
+
*
|
|
1426
|
+
* @example
|
|
1427
|
+
* ```typescript
|
|
1428
|
+
* import { captureMouseTo, releaseMouse } from 'blecsd';
|
|
1429
|
+
*
|
|
1430
|
+
* // Start drag
|
|
1431
|
+
* captureMouseTo(entityId);
|
|
1432
|
+
*
|
|
1433
|
+
* // End drag
|
|
1434
|
+
* releaseMouse();
|
|
1435
|
+
* ```
|
|
1436
|
+
*/
|
|
1437
|
+
declare function captureMouseTo(entity: Entity | null): void;
|
|
1438
|
+
/**
|
|
1439
|
+
* Releases mouse capture.
|
|
1440
|
+
*/
|
|
1441
|
+
declare function releaseMouse(): void;
|
|
1442
|
+
/**
|
|
1443
|
+
* Checks if an entity is currently capturing mouse events.
|
|
1444
|
+
*/
|
|
1445
|
+
declare function isMouseCaptured(): boolean;
|
|
1446
|
+
/**
|
|
1447
|
+
* Gets the entity currently capturing mouse events.
|
|
1448
|
+
*/
|
|
1449
|
+
declare function getMouseCaptureEntity(): Entity | null;
|
|
1450
|
+
/**
|
|
1451
|
+
* Tests if a point is inside an entity's bounding box.
|
|
1452
|
+
* Uses Position and Dimensions components.
|
|
1453
|
+
*
|
|
1454
|
+
* @param world - The ECS world
|
|
1455
|
+
* @param eid - Entity to test
|
|
1456
|
+
* @param x - X coordinate to test
|
|
1457
|
+
* @param y - Y coordinate to test
|
|
1458
|
+
* @returns true if point is inside entity bounds
|
|
1459
|
+
*
|
|
1460
|
+
* @example
|
|
1461
|
+
* ```typescript
|
|
1462
|
+
* import { pointInEntity } from 'blecsd';
|
|
1463
|
+
*
|
|
1464
|
+
* if (pointInEntity(world, entity, mouseX, mouseY)) {
|
|
1465
|
+
* console.log('Mouse is over entity');
|
|
1466
|
+
* }
|
|
1467
|
+
* ```
|
|
1468
|
+
*/
|
|
1469
|
+
declare function pointInEntity(world: World, eid: Entity, x: number, y: number): boolean;
|
|
1470
|
+
/**
|
|
1471
|
+
* Performs hit testing at a point to find all entities under it.
|
|
1472
|
+
* Returns entities sorted by z-index (highest first).
|
|
1473
|
+
*
|
|
1474
|
+
* @param world - The ECS world
|
|
1475
|
+
* @param x - X coordinate to test
|
|
1476
|
+
* @param y - Y coordinate to test
|
|
1477
|
+
* @returns Array of hit test results, sorted by z-index (highest first)
|
|
1478
|
+
*
|
|
1479
|
+
* @example
|
|
1480
|
+
* ```typescript
|
|
1481
|
+
* import { hitTest } from 'blecsd';
|
|
1482
|
+
*
|
|
1483
|
+
* const hits = hitTest(world, mouseX, mouseY);
|
|
1484
|
+
* if (hits.length > 0) {
|
|
1485
|
+
* const topEntity = hits[0].entity;
|
|
1486
|
+
* console.log(`Top entity at click: ${topEntity}`);
|
|
1487
|
+
* }
|
|
1488
|
+
* ```
|
|
1489
|
+
*/
|
|
1490
|
+
declare function hitTest(world: World, x: number, y: number): HitTestResult[];
|
|
1491
|
+
/**
|
|
1492
|
+
* Gets the topmost interactive entity at a point.
|
|
1493
|
+
* Only returns entities that can receive input.
|
|
1494
|
+
*
|
|
1495
|
+
* @param world - The ECS world
|
|
1496
|
+
* @param x - X coordinate to test
|
|
1497
|
+
* @param y - Y coordinate to test
|
|
1498
|
+
* @returns The topmost interactive entity or null
|
|
1499
|
+
*/
|
|
1500
|
+
declare function getInteractiveEntityAt(world: World, x: number, y: number): Entity | null;
|
|
1501
|
+
/**
|
|
1502
|
+
* The input system processes all queued input events.
|
|
1503
|
+
* This system should be registered in the INPUT phase (automatically protected).
|
|
1504
|
+
*
|
|
1505
|
+
* The system:
|
|
1506
|
+
* 1. Processes all queued key and mouse events
|
|
1507
|
+
* 2. Updates KeyboardInput and MouseInput components
|
|
1508
|
+
* 3. Performs hit testing for mouse events
|
|
1509
|
+
* 4. Updates Interactive component state (hovered, pressed)
|
|
1510
|
+
* 5. Manages focus changes (click to focus, Tab navigation)
|
|
1511
|
+
* 6. Dispatches UI events to the event bus
|
|
1512
|
+
*
|
|
1513
|
+
* @param world - The ECS world to process
|
|
1514
|
+
* @returns The world (unchanged reference)
|
|
1515
|
+
*
|
|
1516
|
+
* @example
|
|
1517
|
+
* ```typescript
|
|
1518
|
+
* import { createScheduler, inputSystem, registerInputSystem } from 'blecsd';
|
|
1519
|
+
*
|
|
1520
|
+
* const scheduler = createScheduler();
|
|
1521
|
+
* registerInputSystem(scheduler);
|
|
1522
|
+
*
|
|
1523
|
+
* // In game loop
|
|
1524
|
+
* scheduler.run(world, deltaTime);
|
|
1525
|
+
* ```
|
|
1526
|
+
*/
|
|
1527
|
+
declare const inputSystem: System;
|
|
1528
|
+
/**
|
|
1529
|
+
* Creates a new input system.
|
|
1530
|
+
*
|
|
1531
|
+
* Factory function that returns the inputSystem.
|
|
1532
|
+
* Useful for cases where you need a fresh reference.
|
|
1533
|
+
*
|
|
1534
|
+
* @returns The input system function
|
|
1535
|
+
*
|
|
1536
|
+
* @example
|
|
1537
|
+
* ```typescript
|
|
1538
|
+
* import { createInputSystem, createScheduler } from 'blecsd';
|
|
1539
|
+
*
|
|
1540
|
+
* const scheduler = createScheduler();
|
|
1541
|
+
* const system = createInputSystem();
|
|
1542
|
+
* // Note: Use registerInputSystem instead for proper INPUT phase registration
|
|
1543
|
+
* ```
|
|
1544
|
+
*/
|
|
1545
|
+
declare function createInputSystem(): System;
|
|
1546
|
+
/**
|
|
1547
|
+
* Registers the input system with a scheduler.
|
|
1548
|
+
*
|
|
1549
|
+
* Registers inputSystem in the protected INPUT phase.
|
|
1550
|
+
* This ensures input is always processed first.
|
|
1551
|
+
*
|
|
1552
|
+
* @param scheduler - The scheduler to register with
|
|
1553
|
+
* @param priority - Optional priority within the INPUT phase (default: 0)
|
|
1554
|
+
*
|
|
1555
|
+
* @example
|
|
1556
|
+
* ```typescript
|
|
1557
|
+
* import { createScheduler, registerInputSystem } from 'blecsd';
|
|
1558
|
+
*
|
|
1559
|
+
* const scheduler = createScheduler();
|
|
1560
|
+
* registerInputSystem(scheduler);
|
|
1561
|
+
*
|
|
1562
|
+
* // Input events will now be processed in INPUT phase
|
|
1563
|
+
* scheduler.run(world, deltaTime);
|
|
1564
|
+
* ```
|
|
1565
|
+
*/
|
|
1566
|
+
declare function registerInputSystem(scheduler: Scheduler, priority?: number): void;
|
|
1567
|
+
/**
|
|
1568
|
+
* Clears input state for an entity.
|
|
1569
|
+
* Resets KeyboardInput and MouseInput components to default state.
|
|
1570
|
+
*
|
|
1571
|
+
* @param world - The ECS world
|
|
1572
|
+
* @param eid - Entity to clear input state for
|
|
1573
|
+
*
|
|
1574
|
+
* @example
|
|
1575
|
+
* ```typescript
|
|
1576
|
+
* import { clearEntityInput } from 'blecsd';
|
|
1577
|
+
*
|
|
1578
|
+
* // Clear all input state when entity loses focus
|
|
1579
|
+
* clearEntityInput(world, entity);
|
|
1580
|
+
* ```
|
|
1581
|
+
*/
|
|
1582
|
+
declare function clearEntityInput(world: World, eid: Entity): void;
|
|
1583
|
+
/**
|
|
1584
|
+
* Query all entities that can receive input.
|
|
1585
|
+
* Returns entities with either Interactive or Focusable components.
|
|
1586
|
+
*
|
|
1587
|
+
* @param world - The ECS world
|
|
1588
|
+
* @returns Array of entity IDs that can receive input
|
|
1589
|
+
*/
|
|
1590
|
+
declare function queryInputReceivers(world: World): number[];
|
|
1591
|
+
|
|
1592
|
+
/**
|
|
1593
|
+
* Layout system for computing entity positions and dimensions.
|
|
1594
|
+
* Runs in the LAYOUT phase to pre-compute absolute positions in tree order.
|
|
1595
|
+
* @module systems/layoutSystem
|
|
1596
|
+
*/
|
|
1597
|
+
|
|
1598
|
+
/**
|
|
1599
|
+
* Computed Layout component stores the final computed positions and dimensions.
|
|
1600
|
+
* This component is written by the layout system and read by the render system.
|
|
1601
|
+
*
|
|
1602
|
+
* @example
|
|
1603
|
+
* ```typescript
|
|
1604
|
+
* import { ComputedLayout, getComputedLayout } from 'blecsd';
|
|
1605
|
+
*
|
|
1606
|
+
* // After layout system runs, computed values are available
|
|
1607
|
+
* const layout = getComputedLayout(world, entity);
|
|
1608
|
+
* if (layout) {
|
|
1609
|
+
* console.log(`Absolute: (${layout.x}, ${layout.y})`);
|
|
1610
|
+
* console.log(`Size: ${layout.width}x${layout.height}`);
|
|
1611
|
+
* }
|
|
1612
|
+
* ```
|
|
1613
|
+
*/
|
|
1614
|
+
declare const ComputedLayout: {
|
|
1615
|
+
/** Computed absolute X position (screen column) */
|
|
1616
|
+
x: Float32Array<ArrayBuffer>;
|
|
1617
|
+
/** Computed absolute Y position (screen row) */
|
|
1618
|
+
y: Float32Array<ArrayBuffer>;
|
|
1619
|
+
/** Computed width in cells */
|
|
1620
|
+
width: Float32Array<ArrayBuffer>;
|
|
1621
|
+
/** Computed height in cells */
|
|
1622
|
+
height: Float32Array<ArrayBuffer>;
|
|
1623
|
+
/** Whether layout is valid (0 = needs recompute, 1 = valid) */
|
|
1624
|
+
valid: Uint8Array<ArrayBuffer>;
|
|
1625
|
+
};
|
|
1626
|
+
/**
|
|
1627
|
+
* Computed layout data returned by getComputedLayout.
|
|
1628
|
+
*/
|
|
1629
|
+
interface ComputedLayoutData {
|
|
1630
|
+
readonly x: number;
|
|
1631
|
+
readonly y: number;
|
|
1632
|
+
readonly width: number;
|
|
1633
|
+
readonly height: number;
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Gets the computed layout of an entity.
|
|
1637
|
+
*
|
|
1638
|
+
* @param world - The ECS world
|
|
1639
|
+
* @param eid - The entity ID
|
|
1640
|
+
* @returns Computed layout data or undefined if not available
|
|
1641
|
+
*
|
|
1642
|
+
* @example
|
|
1643
|
+
* ```typescript
|
|
1644
|
+
* const layout = getComputedLayout(world, entity);
|
|
1645
|
+
* if (layout) {
|
|
1646
|
+
* console.log(`Position: (${layout.x}, ${layout.y})`);
|
|
1647
|
+
* }
|
|
1648
|
+
* ```
|
|
1649
|
+
*/
|
|
1650
|
+
declare function getComputedLayout(world: World, eid: Entity): ComputedLayoutData | undefined;
|
|
1651
|
+
/**
|
|
1652
|
+
* Checks if an entity has a valid computed layout.
|
|
1653
|
+
*
|
|
1654
|
+
* @param world - The ECS world
|
|
1655
|
+
* @param eid - The entity ID
|
|
1656
|
+
* @returns true if the entity has a valid computed layout
|
|
1657
|
+
*/
|
|
1658
|
+
declare function hasComputedLayout(world: World, eid: Entity): boolean;
|
|
1659
|
+
/**
|
|
1660
|
+
* Invalidates the computed layout of an entity.
|
|
1661
|
+
* Call this when position or dimensions change to trigger recalculation.
|
|
1662
|
+
*
|
|
1663
|
+
* @param world - The ECS world
|
|
1664
|
+
* @param eid - The entity ID
|
|
1665
|
+
*/
|
|
1666
|
+
declare function invalidateLayout(world: World, eid: Entity): void;
|
|
1667
|
+
/**
|
|
1668
|
+
* Layout system that computes absolute positions for all entities.
|
|
1669
|
+
* Runs in tree order (parents before children) to support relative positioning.
|
|
1670
|
+
*
|
|
1671
|
+
* The system:
|
|
1672
|
+
* 1. Finds all root entities (no parent)
|
|
1673
|
+
* 2. Computes layout for each root and its descendants
|
|
1674
|
+
* 3. Handles percentage dimensions relative to parent
|
|
1675
|
+
* 4. Respects min/max constraints
|
|
1676
|
+
* 5. Stores results in ComputedLayout component
|
|
1677
|
+
*
|
|
1678
|
+
* @param world - The ECS world
|
|
1679
|
+
* @returns The world (unchanged)
|
|
1680
|
+
*
|
|
1681
|
+
* @example
|
|
1682
|
+
* ```typescript
|
|
1683
|
+
* import { layoutSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
1684
|
+
*
|
|
1685
|
+
* const scheduler = createScheduler();
|
|
1686
|
+
* scheduler.registerSystem(LoopPhase.LAYOUT, layoutSystem);
|
|
1687
|
+
* ```
|
|
1688
|
+
*/
|
|
1689
|
+
declare const layoutSystem: System;
|
|
1690
|
+
/**
|
|
1691
|
+
* Creates the layout system function.
|
|
1692
|
+
* This is an alternative to using the layoutSystem directly for custom configuration.
|
|
1693
|
+
*
|
|
1694
|
+
* @returns A new layout system function
|
|
1695
|
+
*
|
|
1696
|
+
* @example
|
|
1697
|
+
* ```typescript
|
|
1698
|
+
* import { createLayoutSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
1699
|
+
*
|
|
1700
|
+
* const scheduler = createScheduler();
|
|
1701
|
+
* scheduler.registerSystem(LoopPhase.LAYOUT, createLayoutSystem());
|
|
1702
|
+
* ```
|
|
1703
|
+
*/
|
|
1704
|
+
declare function createLayoutSystem(): System;
|
|
1705
|
+
/**
|
|
1706
|
+
* Forces a full layout recalculation for all entities.
|
|
1707
|
+
* Call this after major changes like screen resize.
|
|
1708
|
+
*
|
|
1709
|
+
* @param world - The ECS world
|
|
1710
|
+
*
|
|
1711
|
+
* @example
|
|
1712
|
+
* ```typescript
|
|
1713
|
+
* import { invalidateAllLayouts } from 'blecsd';
|
|
1714
|
+
*
|
|
1715
|
+
* // After terminal resize
|
|
1716
|
+
* invalidateAllLayouts(world);
|
|
1717
|
+
* ```
|
|
1718
|
+
*/
|
|
1719
|
+
declare function invalidateAllLayouts(world: World): void;
|
|
1720
|
+
/**
|
|
1721
|
+
* Computes layout for a single entity immediately.
|
|
1722
|
+
* Useful for getting layout outside the normal system loop.
|
|
1723
|
+
*
|
|
1724
|
+
* @param world - The ECS world
|
|
1725
|
+
* @param eid - The entity ID
|
|
1726
|
+
* @returns Computed layout data or undefined if entity lacks Position
|
|
1727
|
+
*
|
|
1728
|
+
* @example
|
|
1729
|
+
* ```typescript
|
|
1730
|
+
* import { computeLayoutNow } from 'blecsd';
|
|
1731
|
+
*
|
|
1732
|
+
* const layout = computeLayoutNow(world, entity);
|
|
1733
|
+
* if (layout) {
|
|
1734
|
+
* console.log(`Position: (${layout.x}, ${layout.y})`);
|
|
1735
|
+
* }
|
|
1736
|
+
* ```
|
|
1737
|
+
*/
|
|
1738
|
+
declare function computeLayoutNow(world: World, eid: Entity): ComputedLayoutData | undefined;
|
|
1739
|
+
/**
|
|
1740
|
+
* Gets the computed content bounds for an entity (position + dimensions).
|
|
1741
|
+
* Returns the bounding rectangle in screen coordinates.
|
|
1742
|
+
*
|
|
1743
|
+
* @param world - The ECS world
|
|
1744
|
+
* @param eid - The entity ID
|
|
1745
|
+
* @returns Bounding rectangle or undefined
|
|
1746
|
+
*
|
|
1747
|
+
* @example
|
|
1748
|
+
* ```typescript
|
|
1749
|
+
* import { getComputedBounds } from 'blecsd';
|
|
1750
|
+
*
|
|
1751
|
+
* const bounds = getComputedBounds(world, entity);
|
|
1752
|
+
* if (bounds) {
|
|
1753
|
+
* console.log(`Bounds: (${bounds.left}, ${bounds.top}) to (${bounds.right}, ${bounds.bottom})`);
|
|
1754
|
+
* }
|
|
1755
|
+
* ```
|
|
1756
|
+
*/
|
|
1757
|
+
declare function getComputedBounds(world: World, eid: Entity): {
|
|
1758
|
+
left: number;
|
|
1759
|
+
top: number;
|
|
1760
|
+
right: number;
|
|
1761
|
+
bottom: number;
|
|
1762
|
+
} | undefined;
|
|
1763
|
+
|
|
1764
|
+
/**
|
|
1765
|
+
* Movement system for updating entity positions based on velocity.
|
|
1766
|
+
* Processes all entities with Velocity component.
|
|
1767
|
+
* @module systems/movementSystem
|
|
1768
|
+
*/
|
|
1769
|
+
|
|
1770
|
+
/**
|
|
1771
|
+
* Query all entities with the Velocity component.
|
|
1772
|
+
*
|
|
1773
|
+
* @param world - The ECS world
|
|
1774
|
+
* @returns Array of entity IDs with Velocity component
|
|
1775
|
+
*/
|
|
1776
|
+
declare function queryMovement(world: World): number[];
|
|
1777
|
+
/**
|
|
1778
|
+
* Checks if an entity has the Velocity component (via system store).
|
|
1779
|
+
*
|
|
1780
|
+
* @param world - The ECS world
|
|
1781
|
+
* @param eid - Entity to check
|
|
1782
|
+
* @returns true if entity has Velocity component
|
|
1783
|
+
*/
|
|
1784
|
+
declare function hasMovementSystem(world: World, eid: number): boolean;
|
|
1785
|
+
/**
|
|
1786
|
+
* Movement system that updates all entities with Velocity component.
|
|
1787
|
+
*
|
|
1788
|
+
* This system should be registered in the PHYSICS phase of the game loop.
|
|
1789
|
+
* It reads delta time from getDeltaTime() which is set by the scheduler.
|
|
1790
|
+
*
|
|
1791
|
+
* For each entity with Velocity, the system:
|
|
1792
|
+
* 1. Applies acceleration to velocity (if Acceleration component present)
|
|
1793
|
+
* 2. Applies friction to velocity
|
|
1794
|
+
* 3. Clamps velocity to max speed
|
|
1795
|
+
* 4. Applies velocity to position (if Position component present)
|
|
1796
|
+
*
|
|
1797
|
+
* @param world - The ECS world to process
|
|
1798
|
+
* @returns The world (unchanged reference)
|
|
1799
|
+
*
|
|
1800
|
+
* @example
|
|
1801
|
+
* ```typescript
|
|
1802
|
+
* import { createScheduler, LoopPhase, movementSystem } from 'blecsd';
|
|
1803
|
+
*
|
|
1804
|
+
* const scheduler = createScheduler();
|
|
1805
|
+
* scheduler.registerSystem(LoopPhase.PHYSICS, movementSystem);
|
|
1806
|
+
*
|
|
1807
|
+
* // In game loop
|
|
1808
|
+
* scheduler.run(world, deltaTime);
|
|
1809
|
+
* ```
|
|
1810
|
+
*/
|
|
1811
|
+
declare const movementSystem: System;
|
|
1812
|
+
/**
|
|
1813
|
+
* Creates a new movement system.
|
|
1814
|
+
*
|
|
1815
|
+
* Factory function that returns the movementSystem.
|
|
1816
|
+
*
|
|
1817
|
+
* @returns The movement system function
|
|
1818
|
+
*
|
|
1819
|
+
* @example
|
|
1820
|
+
* ```typescript
|
|
1821
|
+
* import { createMovementSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
1822
|
+
*
|
|
1823
|
+
* const scheduler = createScheduler();
|
|
1824
|
+
* const system = createMovementSystem();
|
|
1825
|
+
* scheduler.registerSystem(LoopPhase.PHYSICS, system);
|
|
1826
|
+
* ```
|
|
1827
|
+
*/
|
|
1828
|
+
declare function createMovementSystem(): System;
|
|
1829
|
+
/**
|
|
1830
|
+
* Registers the movement system with a scheduler.
|
|
1831
|
+
*
|
|
1832
|
+
* Convenience function that registers movementSystem in the PHYSICS phase.
|
|
1833
|
+
*
|
|
1834
|
+
* @param scheduler - The scheduler to register with
|
|
1835
|
+
* @param priority - Optional priority within the PHYSICS phase (default: 0)
|
|
1836
|
+
*
|
|
1837
|
+
* @example
|
|
1838
|
+
* ```typescript
|
|
1839
|
+
* import { createScheduler, registerMovementSystem } from 'blecsd';
|
|
1840
|
+
*
|
|
1841
|
+
* const scheduler = createScheduler();
|
|
1842
|
+
* registerMovementSystem(scheduler);
|
|
1843
|
+
*
|
|
1844
|
+
* // Movement updates will now happen in PHYSICS phase
|
|
1845
|
+
* scheduler.run(world, deltaTime);
|
|
1846
|
+
* ```
|
|
1847
|
+
*/
|
|
1848
|
+
declare function registerMovementSystem(scheduler: Scheduler, priority?: number): void;
|
|
1849
|
+
/**
|
|
1850
|
+
* Manually update movement for specific entities.
|
|
1851
|
+
*
|
|
1852
|
+
* Useful when you need to update movement outside of the system,
|
|
1853
|
+
* such as in tests or custom update loops.
|
|
1854
|
+
*
|
|
1855
|
+
* @param world - The ECS world
|
|
1856
|
+
* @param entities - Array of entity IDs to update
|
|
1857
|
+
* @param deltaTime - Time elapsed in seconds
|
|
1858
|
+
*
|
|
1859
|
+
* @example
|
|
1860
|
+
* ```typescript
|
|
1861
|
+
* import { updateMovements, queryMovement } from 'blecsd';
|
|
1862
|
+
*
|
|
1863
|
+
* // Manual update (typically use the system instead)
|
|
1864
|
+
* const entities = queryMovement(world);
|
|
1865
|
+
* updateMovements(world, entities, 0.016);
|
|
1866
|
+
* ```
|
|
1867
|
+
*/
|
|
1868
|
+
declare function updateMovements(world: World, entities: readonly number[], deltaTime: number): void;
|
|
1869
|
+
|
|
1870
|
+
/**
|
|
1871
|
+
* Output system for writing rendered buffer to terminal.
|
|
1872
|
+
* Runs in the POST_RENDER phase after all rendering is complete.
|
|
1873
|
+
* @module systems/outputSystem
|
|
1874
|
+
*/
|
|
1875
|
+
|
|
1876
|
+
/**
|
|
1877
|
+
* Output state maintained across frames.
|
|
1878
|
+
*/
|
|
1879
|
+
interface OutputState {
|
|
1880
|
+
/** Last cursor X position (0-indexed) */
|
|
1881
|
+
lastX: number;
|
|
1882
|
+
/** Last cursor Y position (0-indexed) */
|
|
1883
|
+
lastY: number;
|
|
1884
|
+
/** Last foreground color */
|
|
1885
|
+
lastFg: number;
|
|
1886
|
+
/** Last background color */
|
|
1887
|
+
lastBg: number;
|
|
1888
|
+
/** Last attributes */
|
|
1889
|
+
lastAttrs: number;
|
|
1890
|
+
/** Whether we're in alternate screen mode */
|
|
1891
|
+
alternateScreen: boolean;
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* Creates initial output state.
|
|
1895
|
+
*/
|
|
1896
|
+
declare function createOutputState(): OutputState;
|
|
1897
|
+
/**
|
|
1898
|
+
* Generates optimized output for all cell changes.
|
|
1899
|
+
*
|
|
1900
|
+
* @param state - Output state
|
|
1901
|
+
* @param changes - Array of cell changes
|
|
1902
|
+
* @returns ANSI output string
|
|
1903
|
+
*
|
|
1904
|
+
* @example
|
|
1905
|
+
* ```typescript
|
|
1906
|
+
* import { generateOutput, createOutputState } from 'blecsd';
|
|
1907
|
+
*
|
|
1908
|
+
* const state = createOutputState();
|
|
1909
|
+
* const output = generateOutput(state, changes);
|
|
1910
|
+
* process.stdout.write(output);
|
|
1911
|
+
* ```
|
|
1912
|
+
*/
|
|
1913
|
+
declare function generateOutput(state: OutputState, changes: readonly CellChange[]): string;
|
|
1914
|
+
/**
|
|
1915
|
+
* Sets the output stream for the output system.
|
|
1916
|
+
*
|
|
1917
|
+
* @param stream - Writable stream (typically process.stdout)
|
|
1918
|
+
*
|
|
1919
|
+
* @example
|
|
1920
|
+
* ```typescript
|
|
1921
|
+
* import { setOutputStream } from 'blecsd';
|
|
1922
|
+
*
|
|
1923
|
+
* setOutputStream(process.stdout);
|
|
1924
|
+
* ```
|
|
1925
|
+
*/
|
|
1926
|
+
declare function setOutputStream(stream: Writable): void;
|
|
1927
|
+
/**
|
|
1928
|
+
* Gets the current output stream.
|
|
1929
|
+
*
|
|
1930
|
+
* @returns The current output stream or null
|
|
1931
|
+
*/
|
|
1932
|
+
declare function getOutputStream(): Writable | null;
|
|
1933
|
+
/**
|
|
1934
|
+
* Clears the output stream reference.
|
|
1935
|
+
*/
|
|
1936
|
+
declare function clearOutputStream(): void;
|
|
1937
|
+
/**
|
|
1938
|
+
* Sets the double buffer for the output system.
|
|
1939
|
+
*
|
|
1940
|
+
* @param db - The double buffer
|
|
1941
|
+
*
|
|
1942
|
+
* @example
|
|
1943
|
+
* ```typescript
|
|
1944
|
+
* import { setOutputBuffer, createDoubleBuffer } from 'blecsd';
|
|
1945
|
+
*
|
|
1946
|
+
* const db = createDoubleBuffer(80, 24);
|
|
1947
|
+
* setOutputBuffer(db);
|
|
1948
|
+
* ```
|
|
1949
|
+
*/
|
|
1950
|
+
declare function setOutputBuffer(db: DoubleBufferData): void;
|
|
1951
|
+
/**
|
|
1952
|
+
* Gets the current output buffer.
|
|
1953
|
+
*
|
|
1954
|
+
* @returns The current double buffer or null
|
|
1955
|
+
*/
|
|
1956
|
+
declare function getOutputBuffer(): DoubleBufferData | null;
|
|
1957
|
+
/**
|
|
1958
|
+
* Clears the output buffer reference.
|
|
1959
|
+
*/
|
|
1960
|
+
declare function clearOutputBuffer(): void;
|
|
1961
|
+
/**
|
|
1962
|
+
* Gets or creates the output state.
|
|
1963
|
+
*
|
|
1964
|
+
* @returns The output state
|
|
1965
|
+
*/
|
|
1966
|
+
declare function getOutputState(): OutputState;
|
|
1967
|
+
/**
|
|
1968
|
+
* Resets the output state.
|
|
1969
|
+
*/
|
|
1970
|
+
declare function resetOutputState(): void;
|
|
1971
|
+
/**
|
|
1972
|
+
* Output system that writes rendered content to the terminal.
|
|
1973
|
+
*
|
|
1974
|
+
* The system:
|
|
1975
|
+
* 1. Gets minimal updates from the double buffer
|
|
1976
|
+
* 2. Generates optimized ANSI sequences
|
|
1977
|
+
* 3. Writes to the output stream
|
|
1978
|
+
* 4. Swaps buffers and clears dirty regions
|
|
1979
|
+
*
|
|
1980
|
+
* @param world - The ECS world
|
|
1981
|
+
* @returns The world (unchanged)
|
|
1982
|
+
*
|
|
1983
|
+
* @example
|
|
1984
|
+
* ```typescript
|
|
1985
|
+
* import {
|
|
1986
|
+
* outputSystem,
|
|
1987
|
+
* setOutputStream,
|
|
1988
|
+
* setOutputBuffer,
|
|
1989
|
+
* createScheduler,
|
|
1990
|
+
* LoopPhase,
|
|
1991
|
+
* } from 'blecsd';
|
|
1992
|
+
*
|
|
1993
|
+
* // Setup
|
|
1994
|
+
* setOutputStream(process.stdout);
|
|
1995
|
+
* setOutputBuffer(doubleBuffer);
|
|
1996
|
+
*
|
|
1997
|
+
* // Register in POST_RENDER phase
|
|
1998
|
+
* const scheduler = createScheduler();
|
|
1999
|
+
* scheduler.registerSystem(LoopPhase.POST_RENDER, outputSystem);
|
|
2000
|
+
* ```
|
|
2001
|
+
*/
|
|
2002
|
+
declare const outputSystem: System;
|
|
2003
|
+
/**
|
|
2004
|
+
* Creates the output system function.
|
|
2005
|
+
*
|
|
2006
|
+
* @returns A new output system function
|
|
2007
|
+
*
|
|
2008
|
+
* @example
|
|
2009
|
+
* ```typescript
|
|
2010
|
+
* import { createOutputSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
2011
|
+
*
|
|
2012
|
+
* const scheduler = createScheduler();
|
|
2013
|
+
* scheduler.registerSystem(LoopPhase.POST_RENDER, createOutputSystem());
|
|
2014
|
+
* ```
|
|
2015
|
+
*/
|
|
2016
|
+
declare function createOutputSystem(): System;
|
|
2017
|
+
/**
|
|
2018
|
+
* Writes raw output to the stream.
|
|
2019
|
+
* Bypasses the double buffer for immediate output.
|
|
2020
|
+
*
|
|
2021
|
+
* @param data - String data to write
|
|
2022
|
+
*
|
|
2023
|
+
* @example
|
|
2024
|
+
* ```typescript
|
|
2025
|
+
* import { writeRaw } from 'blecsd';
|
|
2026
|
+
*
|
|
2027
|
+
* // Write raw ANSI sequence
|
|
2028
|
+
* writeRaw('\x1b[2J'); // Clear screen
|
|
2029
|
+
* ```
|
|
2030
|
+
*/
|
|
2031
|
+
declare function writeRaw(data: string): void;
|
|
2032
|
+
/**
|
|
2033
|
+
* Hides the terminal cursor.
|
|
2034
|
+
*
|
|
2035
|
+
* @example
|
|
2036
|
+
* ```typescript
|
|
2037
|
+
* import { hideCursor } from 'blecsd';
|
|
2038
|
+
*
|
|
2039
|
+
* hideCursor();
|
|
2040
|
+
* ```
|
|
2041
|
+
*/
|
|
2042
|
+
declare function hideCursor(): void;
|
|
2043
|
+
/**
|
|
2044
|
+
* Shows the terminal cursor.
|
|
2045
|
+
*
|
|
2046
|
+
* @example
|
|
2047
|
+
* ```typescript
|
|
2048
|
+
* import { showCursor } from 'blecsd';
|
|
2049
|
+
*
|
|
2050
|
+
* showCursor();
|
|
2051
|
+
* ```
|
|
2052
|
+
*/
|
|
2053
|
+
declare function showCursor(): void;
|
|
2054
|
+
/**
|
|
2055
|
+
* Enters alternate screen buffer mode.
|
|
2056
|
+
*
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```typescript
|
|
2059
|
+
* import { enterAlternateScreen } from 'blecsd';
|
|
2060
|
+
*
|
|
2061
|
+
* enterAlternateScreen();
|
|
2062
|
+
* // ... render application ...
|
|
2063
|
+
* leaveAlternateScreen();
|
|
2064
|
+
* ```
|
|
2065
|
+
*/
|
|
2066
|
+
declare function enterAlternateScreen(): void;
|
|
2067
|
+
/**
|
|
2068
|
+
* Leaves alternate screen buffer mode.
|
|
2069
|
+
*
|
|
2070
|
+
* @example
|
|
2071
|
+
* ```typescript
|
|
2072
|
+
* import { leaveAlternateScreen } from 'blecsd';
|
|
2073
|
+
*
|
|
2074
|
+
* leaveAlternateScreen();
|
|
2075
|
+
* ```
|
|
2076
|
+
*/
|
|
2077
|
+
declare function leaveAlternateScreen(): void;
|
|
2078
|
+
/**
|
|
2079
|
+
* Clears the entire screen.
|
|
2080
|
+
*
|
|
2081
|
+
* @example
|
|
2082
|
+
* ```typescript
|
|
2083
|
+
* import { clearScreen } from 'blecsd';
|
|
2084
|
+
*
|
|
2085
|
+
* clearScreen();
|
|
2086
|
+
* ```
|
|
2087
|
+
*/
|
|
2088
|
+
declare function clearScreen(): void;
|
|
2089
|
+
/**
|
|
2090
|
+
* Moves cursor to home position (0, 0).
|
|
2091
|
+
*
|
|
2092
|
+
* @example
|
|
2093
|
+
* ```typescript
|
|
2094
|
+
* import { cursorHome } from 'blecsd';
|
|
2095
|
+
*
|
|
2096
|
+
* cursorHome();
|
|
2097
|
+
* ```
|
|
2098
|
+
*/
|
|
2099
|
+
declare function cursorHome(): void;
|
|
2100
|
+
/**
|
|
2101
|
+
* Resets all terminal attributes.
|
|
2102
|
+
*
|
|
2103
|
+
* @example
|
|
2104
|
+
* ```typescript
|
|
2105
|
+
* import { resetAttributes } from 'blecsd';
|
|
2106
|
+
*
|
|
2107
|
+
* resetAttributes();
|
|
2108
|
+
* ```
|
|
2109
|
+
*/
|
|
2110
|
+
declare function resetAttributes(): void;
|
|
2111
|
+
/**
|
|
2112
|
+
* Flushes output and resets terminal state.
|
|
2113
|
+
* Call this before exiting the application.
|
|
2114
|
+
*
|
|
2115
|
+
* @example
|
|
2116
|
+
* ```typescript
|
|
2117
|
+
* import { cleanup } from 'blecsd';
|
|
2118
|
+
*
|
|
2119
|
+
* // Before exiting
|
|
2120
|
+
* cleanup();
|
|
2121
|
+
* ```
|
|
2122
|
+
*/
|
|
2123
|
+
declare function cleanup(): void;
|
|
2124
|
+
|
|
2125
|
+
/**
|
|
2126
|
+
* Fast panel movement and resizing system.
|
|
2127
|
+
*
|
|
2128
|
+
* Provides instant panel position updates on input with deferred
|
|
2129
|
+
* content re-layout. Uses dirty rect optimization and optional
|
|
2130
|
+
* content simplification during drag for 60fps movement.
|
|
2131
|
+
*
|
|
2132
|
+
* @module systems/panelMovement
|
|
2133
|
+
*/
|
|
2134
|
+
|
|
2135
|
+
/**
|
|
2136
|
+
* Resize handle positions.
|
|
2137
|
+
*/
|
|
2138
|
+
type ResizeHandle = 'top' | 'bottom' | 'left' | 'right' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
|
|
2139
|
+
/**
|
|
2140
|
+
* Panel movement constraints.
|
|
2141
|
+
*/
|
|
2142
|
+
interface PanelConstraints {
|
|
2143
|
+
/** Minimum panel width (default: 4) */
|
|
2144
|
+
readonly minWidth: number;
|
|
2145
|
+
/** Minimum panel height (default: 2) */
|
|
2146
|
+
readonly minHeight: number;
|
|
2147
|
+
/** Maximum panel width (0 = no limit) */
|
|
2148
|
+
readonly maxWidth: number;
|
|
2149
|
+
/** Maximum panel height (0 = no limit) */
|
|
2150
|
+
readonly maxHeight: number;
|
|
2151
|
+
/** Constrain movement to screen bounds */
|
|
2152
|
+
readonly constrainToScreen: boolean;
|
|
2153
|
+
/** Screen width for constraining */
|
|
2154
|
+
readonly screenWidth: number;
|
|
2155
|
+
/** Screen height for constraining */
|
|
2156
|
+
readonly screenHeight: number;
|
|
2157
|
+
/** Snap to grid size (0 = no snap) */
|
|
2158
|
+
readonly snapGrid: number;
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Panel movement/resize state.
|
|
2162
|
+
*/
|
|
2163
|
+
interface PanelMoveState {
|
|
2164
|
+
/** Currently moving entity */
|
|
2165
|
+
readonly entity: Entity | undefined;
|
|
2166
|
+
/** Whether a move is in progress */
|
|
2167
|
+
readonly isMoving: boolean;
|
|
2168
|
+
/** Whether a resize is in progress */
|
|
2169
|
+
readonly isResizing: boolean;
|
|
2170
|
+
/** Active resize handle */
|
|
2171
|
+
readonly resizeHandle: ResizeHandle | undefined;
|
|
2172
|
+
/** Starting mouse/cursor position */
|
|
2173
|
+
readonly startX: number;
|
|
2174
|
+
readonly startY: number;
|
|
2175
|
+
/** Starting panel position */
|
|
2176
|
+
readonly panelStartX: number;
|
|
2177
|
+
readonly panelStartY: number;
|
|
2178
|
+
/** Starting panel dimensions */
|
|
2179
|
+
readonly panelStartWidth: number;
|
|
2180
|
+
readonly panelStartHeight: number;
|
|
2181
|
+
/** Whether content layout is deferred (simplified rendering during move) */
|
|
2182
|
+
readonly layoutDeferred: boolean;
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Configuration for panel movement behavior.
|
|
2186
|
+
*/
|
|
2187
|
+
interface PanelMoveConfig {
|
|
2188
|
+
/** Defer content layout during move for performance (default: true) */
|
|
2189
|
+
readonly deferLayout: boolean;
|
|
2190
|
+
/** Show resize outline instead of live resize (default: false) */
|
|
2191
|
+
readonly outlineResize: boolean;
|
|
2192
|
+
/** Number of pixels to move with keyboard (default: 1) */
|
|
2193
|
+
readonly keyboardStep: number;
|
|
2194
|
+
/** Number of pixels to resize with keyboard (default: 1) */
|
|
2195
|
+
readonly keyboardResizeStep: number;
|
|
2196
|
+
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Dirty rectangle representing changed area.
|
|
2199
|
+
*/
|
|
2200
|
+
interface DirtyRect {
|
|
2201
|
+
readonly x: number;
|
|
2202
|
+
readonly y: number;
|
|
2203
|
+
readonly width: number;
|
|
2204
|
+
readonly height: number;
|
|
2205
|
+
}
|
|
2206
|
+
/**
|
|
2207
|
+
* Result of a panel move or resize operation.
|
|
2208
|
+
*/
|
|
2209
|
+
interface MoveResult {
|
|
2210
|
+
/** New position X */
|
|
2211
|
+
readonly x: number;
|
|
2212
|
+
/** New position Y */
|
|
2213
|
+
readonly y: number;
|
|
2214
|
+
/** New width (for resize) */
|
|
2215
|
+
readonly width: number;
|
|
2216
|
+
/** New height (for resize) */
|
|
2217
|
+
readonly height: number;
|
|
2218
|
+
/** Dirty rectangles that need redrawing */
|
|
2219
|
+
readonly dirtyRects: readonly DirtyRect[];
|
|
2220
|
+
/** Whether the operation was clamped by constraints */
|
|
2221
|
+
readonly clamped: boolean;
|
|
2222
|
+
}
|
|
2223
|
+
/**
|
|
2224
|
+
* Creates initial panel move state.
|
|
2225
|
+
*
|
|
2226
|
+
* @returns Fresh move state
|
|
2227
|
+
*
|
|
2228
|
+
* @example
|
|
2229
|
+
* ```typescript
|
|
2230
|
+
* import { createPanelMoveState } from 'blecsd';
|
|
2231
|
+
*
|
|
2232
|
+
* const moveState = createPanelMoveState();
|
|
2233
|
+
* ```
|
|
2234
|
+
*/
|
|
2235
|
+
declare function createPanelMoveState(): PanelMoveState;
|
|
2236
|
+
/**
|
|
2237
|
+
* Creates panel move configuration with defaults.
|
|
2238
|
+
*
|
|
2239
|
+
* @param config - Partial overrides
|
|
2240
|
+
* @returns Full configuration
|
|
2241
|
+
*/
|
|
2242
|
+
declare function createPanelMoveConfig(config?: Partial<PanelMoveConfig>): PanelMoveConfig;
|
|
2243
|
+
/**
|
|
2244
|
+
* Creates panel constraints with defaults.
|
|
2245
|
+
*
|
|
2246
|
+
* @param constraints - Partial overrides
|
|
2247
|
+
* @returns Full constraints
|
|
2248
|
+
*/
|
|
2249
|
+
declare function createPanelConstraints(constraints?: Partial<PanelConstraints>): PanelConstraints;
|
|
2250
|
+
/**
|
|
2251
|
+
* Begins a panel move operation.
|
|
2252
|
+
*
|
|
2253
|
+
* @param state - Current move state
|
|
2254
|
+
* @param entity - Entity to move
|
|
2255
|
+
* @param mouseX - Starting mouse X
|
|
2256
|
+
* @param mouseY - Starting mouse Y
|
|
2257
|
+
* @param panelX - Current panel X position
|
|
2258
|
+
* @param panelY - Current panel Y position
|
|
2259
|
+
* @param panelWidth - Current panel width
|
|
2260
|
+
* @param panelHeight - Current panel height
|
|
2261
|
+
* @param config - Move configuration
|
|
2262
|
+
* @returns Updated state
|
|
2263
|
+
*
|
|
2264
|
+
* @example
|
|
2265
|
+
* ```typescript
|
|
2266
|
+
* import { createPanelMoveState, beginMove } from 'blecsd';
|
|
2267
|
+
*
|
|
2268
|
+
* let state = createPanelMoveState();
|
|
2269
|
+
* state = beginMove(state, eid, mouseX, mouseY, panelX, panelY, 30, 10);
|
|
2270
|
+
* ```
|
|
2271
|
+
*/
|
|
2272
|
+
declare function beginMove(state: PanelMoveState, entity: Entity, mouseX: number, mouseY: number, panelX: number, panelY: number, panelWidth: number, panelHeight: number, config?: Partial<PanelMoveConfig>): PanelMoveState;
|
|
2273
|
+
/**
|
|
2274
|
+
* Begins a panel resize operation.
|
|
2275
|
+
*
|
|
2276
|
+
* @param state - Current move state
|
|
2277
|
+
* @param entity - Entity to resize
|
|
2278
|
+
* @param handle - Resize handle being dragged
|
|
2279
|
+
* @param mouseX - Starting mouse X
|
|
2280
|
+
* @param mouseY - Starting mouse Y
|
|
2281
|
+
* @param panelX - Current panel X
|
|
2282
|
+
* @param panelY - Current panel Y
|
|
2283
|
+
* @param panelWidth - Current panel width
|
|
2284
|
+
* @param panelHeight - Current panel height
|
|
2285
|
+
* @param config - Move configuration
|
|
2286
|
+
* @returns Updated state
|
|
2287
|
+
*/
|
|
2288
|
+
declare function beginResize(state: PanelMoveState, entity: Entity, handle: ResizeHandle, mouseX: number, mouseY: number, panelX: number, panelY: number, panelWidth: number, panelHeight: number, config?: Partial<PanelMoveConfig>): PanelMoveState;
|
|
2289
|
+
/**
|
|
2290
|
+
* Updates a panel move with new cursor position.
|
|
2291
|
+
* Returns the new panel position with constraints applied.
|
|
2292
|
+
*
|
|
2293
|
+
* @param state - Current move state
|
|
2294
|
+
* @param mouseX - Current mouse X
|
|
2295
|
+
* @param mouseY - Current mouse Y
|
|
2296
|
+
* @param constraints - Panel constraints
|
|
2297
|
+
* @returns Move result with new position and dirty rects
|
|
2298
|
+
*
|
|
2299
|
+
* @example
|
|
2300
|
+
* ```typescript
|
|
2301
|
+
* import { updateMove, createPanelConstraints } from 'blecsd';
|
|
2302
|
+
*
|
|
2303
|
+
* const result = updateMove(state, mouseX, mouseY, createPanelConstraints());
|
|
2304
|
+
* setPosition(world, eid, result.x, result.y);
|
|
2305
|
+
* ```
|
|
2306
|
+
*/
|
|
2307
|
+
declare function updateMove(state: PanelMoveState, mouseX: number, mouseY: number, constraints?: Partial<PanelConstraints>): MoveResult;
|
|
2308
|
+
declare function updateResize(state: PanelMoveState, mouseX: number, mouseY: number, constraints?: Partial<PanelConstraints>): MoveResult;
|
|
2309
|
+
/**
|
|
2310
|
+
* Ends the current move or resize operation.
|
|
2311
|
+
*
|
|
2312
|
+
* @param state - Current move state
|
|
2313
|
+
* @returns Reset state
|
|
2314
|
+
*/
|
|
2315
|
+
declare function endMoveOrResize(state: PanelMoveState): PanelMoveState;
|
|
2316
|
+
/**
|
|
2317
|
+
* Cancels the current move or resize, returning to original position.
|
|
2318
|
+
*
|
|
2319
|
+
* @param state - Current move state
|
|
2320
|
+
* @returns Object with original position and reset state
|
|
2321
|
+
*/
|
|
2322
|
+
declare function cancelMoveOrResize(state: PanelMoveState): {
|
|
2323
|
+
state: PanelMoveState;
|
|
2324
|
+
restoreX: number;
|
|
2325
|
+
restoreY: number;
|
|
2326
|
+
restoreWidth: number;
|
|
2327
|
+
restoreHeight: number;
|
|
2328
|
+
};
|
|
2329
|
+
/**
|
|
2330
|
+
* Moves a panel by keyboard step amount.
|
|
2331
|
+
*
|
|
2332
|
+
* @param x - Current X position
|
|
2333
|
+
* @param y - Current Y position
|
|
2334
|
+
* @param width - Panel width
|
|
2335
|
+
* @param height - Panel height
|
|
2336
|
+
* @param direction - Movement direction
|
|
2337
|
+
* @param step - Step amount
|
|
2338
|
+
* @param constraints - Panel constraints
|
|
2339
|
+
* @returns New position
|
|
2340
|
+
*/
|
|
2341
|
+
declare function keyboardMove(x: number, y: number, width: number, height: number, direction: 'up' | 'down' | 'left' | 'right', step: number, constraints?: Partial<PanelConstraints>): {
|
|
2342
|
+
x: number;
|
|
2343
|
+
y: number;
|
|
2344
|
+
};
|
|
2345
|
+
/**
|
|
2346
|
+
* Resizes a panel by keyboard step amount.
|
|
2347
|
+
*
|
|
2348
|
+
* @param width - Current width
|
|
2349
|
+
* @param height - Current height
|
|
2350
|
+
* @param direction - Resize direction
|
|
2351
|
+
* @param step - Step amount
|
|
2352
|
+
* @param constraints - Panel constraints
|
|
2353
|
+
* @returns New dimensions
|
|
2354
|
+
*/
|
|
2355
|
+
declare function keyboardResize(width: number, height: number, direction: 'grow-horizontal' | 'shrink-horizontal' | 'grow-vertical' | 'shrink-vertical', step: number, constraints?: Partial<PanelConstraints>): {
|
|
2356
|
+
width: number;
|
|
2357
|
+
height: number;
|
|
2358
|
+
};
|
|
2359
|
+
/**
|
|
2360
|
+
* Detects which resize handle a click position corresponds to.
|
|
2361
|
+
*
|
|
2362
|
+
* @param clickX - Click X relative to panel
|
|
2363
|
+
* @param clickY - Click Y relative to panel
|
|
2364
|
+
* @param panelWidth - Panel width
|
|
2365
|
+
* @param panelHeight - Panel height
|
|
2366
|
+
* @param borderSize - Size of the resize border area (default: 1)
|
|
2367
|
+
* @returns The resize handle, or undefined if not on a border
|
|
2368
|
+
*/
|
|
2369
|
+
declare function detectResizeHandle(clickX: number, clickY: number, panelWidth: number, panelHeight: number, borderSize?: number): ResizeHandle | undefined;
|
|
2370
|
+
/**
|
|
2371
|
+
* Merges overlapping dirty rectangles for efficient redraw.
|
|
2372
|
+
*
|
|
2373
|
+
* @param rects - Array of dirty rectangles
|
|
2374
|
+
* @returns Merged bounding rectangle
|
|
2375
|
+
*/
|
|
2376
|
+
declare function mergeDirtyRects(rects: readonly DirtyRect[]): DirtyRect | undefined;
|
|
2377
|
+
|
|
2378
|
+
/**
|
|
2379
|
+
* Particle system for spawning, updating, and removing particles.
|
|
2380
|
+
*
|
|
2381
|
+
* Processes emitters (rate-based and burst-based spawning) and
|
|
2382
|
+
* updates particle age, position, and velocity each frame.
|
|
2383
|
+
*
|
|
2384
|
+
* @module systems/particleSystem
|
|
2385
|
+
*/
|
|
2386
|
+
|
|
2387
|
+
/**
|
|
2388
|
+
* Function that provides entity IDs to iterate over.
|
|
2389
|
+
* User supplies this because blECSd doesn't own a global query registry.
|
|
2390
|
+
*/
|
|
2391
|
+
type EntityProvider = (world: World) => ReadonlyArray<Entity>;
|
|
2392
|
+
/**
|
|
2393
|
+
* Configuration for the particle system.
|
|
2394
|
+
*/
|
|
2395
|
+
interface ParticleSystemConfig {
|
|
2396
|
+
/** Provides emitter entities each frame */
|
|
2397
|
+
readonly emitters: EntityProvider;
|
|
2398
|
+
/** Provides particle entities each frame */
|
|
2399
|
+
readonly particles: EntityProvider;
|
|
2400
|
+
/** Maximum concurrent particles (default: 1000) */
|
|
2401
|
+
readonly maxParticles?: number;
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* Spawns a single particle from an emitter at a random angle within the spread.
|
|
2405
|
+
*
|
|
2406
|
+
* @param world - The ECS world
|
|
2407
|
+
* @param emitterId - The emitter entity ID
|
|
2408
|
+
* @param appearance - Visual appearance config
|
|
2409
|
+
* @returns The spawned particle entity ID, or -1 if spawn failed
|
|
2410
|
+
*/
|
|
2411
|
+
declare function spawnParticle(world: World, emitterId: Entity, appearance: EmitterAppearance): Entity;
|
|
2412
|
+
/**
|
|
2413
|
+
* Triggers a burst of particles from an emitter.
|
|
2414
|
+
*
|
|
2415
|
+
* @param world - The ECS world
|
|
2416
|
+
* @param emitterId - The emitter entity ID
|
|
2417
|
+
* @param count - Number of particles to emit (default: emitter's burstCount)
|
|
2418
|
+
* @param maxParticles - Maximum total particles allowed (default: 1000)
|
|
2419
|
+
* @param currentCount - Current total particle count
|
|
2420
|
+
* @returns Array of spawned particle entity IDs
|
|
2421
|
+
*
|
|
2422
|
+
* @example
|
|
2423
|
+
* ```typescript
|
|
2424
|
+
* import { burstParticles } from 'blecsd';
|
|
2425
|
+
*
|
|
2426
|
+
* const particles = burstParticles(world, emitterEntity, 20);
|
|
2427
|
+
* ```
|
|
2428
|
+
*/
|
|
2429
|
+
declare function burstParticles(world: World, emitterId: Entity, count?: number, maxParticles?: number, currentCount?: number): Entity[];
|
|
2430
|
+
/**
|
|
2431
|
+
* Ages a particle and updates its velocity for gravity.
|
|
2432
|
+
*
|
|
2433
|
+
* @param world - The ECS world
|
|
2434
|
+
* @param eid - The particle entity ID
|
|
2435
|
+
* @param delta - Time elapsed in seconds
|
|
2436
|
+
*/
|
|
2437
|
+
declare function ageParticle(world: World, eid: Entity, delta: number): void;
|
|
2438
|
+
/**
|
|
2439
|
+
* Updates a particle's position based on its velocity.
|
|
2440
|
+
*
|
|
2441
|
+
* @param world - The ECS world
|
|
2442
|
+
* @param eid - The particle entity ID
|
|
2443
|
+
* @param delta - Time elapsed in seconds
|
|
2444
|
+
*/
|
|
2445
|
+
declare function moveParticle(world: World, eid: Entity, delta: number): void;
|
|
2446
|
+
/**
|
|
2447
|
+
* Removes a dead particle and cleans up tracking.
|
|
2448
|
+
*
|
|
2449
|
+
* @param world - The ECS world
|
|
2450
|
+
* @param eid - The particle entity ID
|
|
2451
|
+
*/
|
|
2452
|
+
declare function killParticle(world: World, eid: Entity): void;
|
|
2453
|
+
declare function createParticleSystem(config: ParticleSystemConfig): System;
|
|
2454
|
+
|
|
2455
|
+
/**
|
|
2456
|
+
* Render system for drawing entities to the screen buffer.
|
|
2457
|
+
* Runs in the RENDER phase after layout computation.
|
|
2458
|
+
* @module systems/renderSystem
|
|
2459
|
+
*/
|
|
2460
|
+
|
|
2461
|
+
/**
|
|
2462
|
+
* Render context passed to render functions.
|
|
2463
|
+
*/
|
|
2464
|
+
interface RenderContext {
|
|
2465
|
+
/** The ECS world */
|
|
2466
|
+
readonly world: World;
|
|
2467
|
+
/** The screen buffer to render to */
|
|
2468
|
+
readonly buffer: ScreenBufferData;
|
|
2469
|
+
/** The double buffer for dirty tracking */
|
|
2470
|
+
readonly doubleBuffer: DoubleBufferData;
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Computed bounds for an entity.
|
|
2474
|
+
*/
|
|
2475
|
+
interface EntityBounds {
|
|
2476
|
+
readonly x: number;
|
|
2477
|
+
readonly y: number;
|
|
2478
|
+
readonly width: number;
|
|
2479
|
+
readonly height: number;
|
|
2480
|
+
}
|
|
2481
|
+
/**
|
|
2482
|
+
* Renders the background fill for an entity.
|
|
2483
|
+
*
|
|
2484
|
+
* @param ctx - Render context
|
|
2485
|
+
* @param eid - Entity ID
|
|
2486
|
+
* @param bounds - Entity bounds
|
|
2487
|
+
*
|
|
2488
|
+
* @example
|
|
2489
|
+
* ```typescript
|
|
2490
|
+
* import { renderBackground } from 'blecsd';
|
|
2491
|
+
*
|
|
2492
|
+
* renderBackground(ctx, entity, bounds);
|
|
2493
|
+
* ```
|
|
2494
|
+
*/
|
|
2495
|
+
declare function renderBackground(ctx: RenderContext, eid: Entity, bounds: EntityBounds): void;
|
|
2496
|
+
/**
|
|
2497
|
+
* Renders the border for an entity.
|
|
2498
|
+
*
|
|
2499
|
+
* @param ctx - Render context
|
|
2500
|
+
* @param eid - Entity ID
|
|
2501
|
+
* @param bounds - Entity bounds
|
|
2502
|
+
*
|
|
2503
|
+
* @example
|
|
2504
|
+
* ```typescript
|
|
2505
|
+
* import { renderBorder } from 'blecsd';
|
|
2506
|
+
*
|
|
2507
|
+
* renderBorder(ctx, entity, bounds);
|
|
2508
|
+
* ```
|
|
2509
|
+
*/
|
|
2510
|
+
declare function renderBorder(ctx: RenderContext, eid: Entity, bounds: EntityBounds): void;
|
|
2511
|
+
/**
|
|
2512
|
+
* Renders the content area of an entity.
|
|
2513
|
+
* This is a placeholder that can be extended for specific content types.
|
|
2514
|
+
*
|
|
2515
|
+
* @param ctx - Render context
|
|
2516
|
+
* @param eid - Entity ID
|
|
2517
|
+
* @param contentBounds - Content area bounds (inside border)
|
|
2518
|
+
*
|
|
2519
|
+
* @example
|
|
2520
|
+
* ```typescript
|
|
2521
|
+
* import { renderContent } from 'blecsd';
|
|
2522
|
+
*
|
|
2523
|
+
* renderContent(ctx, entity, contentBounds);
|
|
2524
|
+
* ```
|
|
2525
|
+
*/
|
|
2526
|
+
declare function renderContent(_ctx: RenderContext, _eid: Entity, _contentBounds: EntityBounds): void;
|
|
2527
|
+
/**
|
|
2528
|
+
* Renders a scrollbar for an entity.
|
|
2529
|
+
* Currently a placeholder for future scrollable content support.
|
|
2530
|
+
*
|
|
2531
|
+
* @param ctx - Render context
|
|
2532
|
+
* @param eid - Entity ID
|
|
2533
|
+
* @param bounds - Entity bounds
|
|
2534
|
+
*
|
|
2535
|
+
* @example
|
|
2536
|
+
* ```typescript
|
|
2537
|
+
* import { renderScrollbar } from 'blecsd';
|
|
2538
|
+
*
|
|
2539
|
+
* renderScrollbar(ctx, entity, bounds);
|
|
2540
|
+
* ```
|
|
2541
|
+
*/
|
|
2542
|
+
declare function renderScrollbar(_ctx: RenderContext, _eid: Entity, _bounds: EntityBounds): void;
|
|
2543
|
+
/**
|
|
2544
|
+
* Sets the double buffer for the render system.
|
|
2545
|
+
* Must be called before running the render system.
|
|
2546
|
+
*
|
|
2547
|
+
* @param db - The double buffer to render to
|
|
2548
|
+
*
|
|
2549
|
+
* @example
|
|
2550
|
+
* ```typescript
|
|
2551
|
+
* import { setRenderBuffer, createDoubleBuffer } from 'blecsd';
|
|
2552
|
+
*
|
|
2553
|
+
* const db = createDoubleBuffer(80, 24);
|
|
2554
|
+
* setRenderBuffer(db);
|
|
2555
|
+
* ```
|
|
2556
|
+
*/
|
|
2557
|
+
declare function setRenderBuffer(db: DoubleBufferData): void;
|
|
2558
|
+
/**
|
|
2559
|
+
* Gets the current render buffer.
|
|
2560
|
+
*
|
|
2561
|
+
* @returns The current double buffer or null
|
|
2562
|
+
*/
|
|
2563
|
+
declare function getRenderBuffer(): DoubleBufferData | null;
|
|
2564
|
+
/**
|
|
2565
|
+
* Clears the render buffer reference.
|
|
2566
|
+
*/
|
|
2567
|
+
declare function clearRenderBuffer(): void;
|
|
2568
|
+
/**
|
|
2569
|
+
* Render system that draws visible, dirty entities to the screen buffer.
|
|
2570
|
+
* Entities are rendered in z-index order (lower z first, higher z on top).
|
|
2571
|
+
*
|
|
2572
|
+
* The system:
|
|
2573
|
+
* 1. Queries all entities with Position and Renderable
|
|
2574
|
+
* 2. Filters to visible, dirty entities
|
|
2575
|
+
* 3. Sorts by z-index
|
|
2576
|
+
* 4. Renders each entity (background, border, content)
|
|
2577
|
+
* 5. Marks entities as clean
|
|
2578
|
+
*
|
|
2579
|
+
* @param world - The ECS world
|
|
2580
|
+
* @returns The world (unchanged)
|
|
2581
|
+
*
|
|
2582
|
+
* @example
|
|
2583
|
+
* ```typescript
|
|
2584
|
+
* import { renderSystem, setRenderBuffer, createScheduler, LoopPhase } from 'blecsd';
|
|
2585
|
+
*
|
|
2586
|
+
* const scheduler = createScheduler();
|
|
2587
|
+
* scheduler.registerSystem(LoopPhase.RENDER, renderSystem);
|
|
2588
|
+
*
|
|
2589
|
+
* // Before running, set the render buffer
|
|
2590
|
+
* setRenderBuffer(doubleBuffer);
|
|
2591
|
+
* scheduler.run(world, deltaTime);
|
|
2592
|
+
* ```
|
|
2593
|
+
*/
|
|
2594
|
+
declare const renderSystem: System;
|
|
2595
|
+
/**
|
|
2596
|
+
* Creates the render system function.
|
|
2597
|
+
* This is an alternative to using the renderSystem directly for custom configuration.
|
|
2598
|
+
*
|
|
2599
|
+
* @returns A new render system function
|
|
2600
|
+
*
|
|
2601
|
+
* @example
|
|
2602
|
+
* ```typescript
|
|
2603
|
+
* import { createRenderSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
2604
|
+
*
|
|
2605
|
+
* const scheduler = createScheduler();
|
|
2606
|
+
* scheduler.registerSystem(LoopPhase.RENDER, createRenderSystem());
|
|
2607
|
+
* ```
|
|
2608
|
+
*/
|
|
2609
|
+
declare function createRenderSystem(): System;
|
|
2610
|
+
/**
|
|
2611
|
+
* Renders text to a buffer at the specified position.
|
|
2612
|
+
* Utility function for widgets to render text content.
|
|
2613
|
+
*
|
|
2614
|
+
* @param buffer - Screen buffer
|
|
2615
|
+
* @param x - X position
|
|
2616
|
+
* @param y - Y position
|
|
2617
|
+
* @param text - Text to render
|
|
2618
|
+
* @param fg - Foreground color
|
|
2619
|
+
* @param bg - Background color
|
|
2620
|
+
* @param attrs - Text attributes
|
|
2621
|
+
* @returns Number of characters written
|
|
2622
|
+
*
|
|
2623
|
+
* @example
|
|
2624
|
+
* ```typescript
|
|
2625
|
+
* import { renderText, Attr } from 'blecsd';
|
|
2626
|
+
*
|
|
2627
|
+
* renderText(buffer, 10, 5, 'Hello', 0xffffffff, 0x000000ff, Attr.BOLD);
|
|
2628
|
+
* ```
|
|
2629
|
+
*/
|
|
2630
|
+
declare function renderText(buffer: ScreenBufferData, x: number, y: number, text: string, fg: number, bg: number, attrs?: number): number;
|
|
2631
|
+
/**
|
|
2632
|
+
* Renders a filled rectangle to a buffer.
|
|
2633
|
+
* Utility function for widgets.
|
|
2634
|
+
*
|
|
2635
|
+
* @param buffer - Screen buffer
|
|
2636
|
+
* @param x - X position
|
|
2637
|
+
* @param y - Y position
|
|
2638
|
+
* @param width - Rectangle width
|
|
2639
|
+
* @param height - Rectangle height
|
|
2640
|
+
* @param cell - Cell to fill with
|
|
2641
|
+
*
|
|
2642
|
+
* @example
|
|
2643
|
+
* ```typescript
|
|
2644
|
+
* import { renderRect, createCell } from 'blecsd';
|
|
2645
|
+
*
|
|
2646
|
+
* renderRect(buffer, 10, 5, 20, 10, createCell(' ', 0xffffffff, 0x0000ffff));
|
|
2647
|
+
* ```
|
|
2648
|
+
*/
|
|
2649
|
+
declare function renderRect(buffer: ScreenBufferData, x: number, y: number, width: number, height: number, cell: Cell): void;
|
|
2650
|
+
/**
|
|
2651
|
+
* Marks all entities as dirty, forcing a full re-render.
|
|
2652
|
+
*
|
|
2653
|
+
* @param world - The ECS world
|
|
2654
|
+
*
|
|
2655
|
+
* @example
|
|
2656
|
+
* ```typescript
|
|
2657
|
+
* import { markAllDirty } from 'blecsd';
|
|
2658
|
+
*
|
|
2659
|
+
* // Force re-render of all entities
|
|
2660
|
+
* markAllDirty(world);
|
|
2661
|
+
* ```
|
|
2662
|
+
*/
|
|
2663
|
+
declare function markAllDirty(world: World): void;
|
|
2664
|
+
|
|
2665
|
+
/**
|
|
2666
|
+
* Smooth Animated Scrolling
|
|
2667
|
+
*
|
|
2668
|
+
* Provides butter-smooth scroll animations with momentum/inertia physics.
|
|
2669
|
+
* Supports velocity-based scrolling, spring-to-boundary behavior, and
|
|
2670
|
+
* graceful frame skipping under load.
|
|
2671
|
+
*
|
|
2672
|
+
* @module systems/smoothScroll
|
|
2673
|
+
*/
|
|
2674
|
+
|
|
2675
|
+
/**
|
|
2676
|
+
* Scroll physics configuration.
|
|
2677
|
+
*/
|
|
2678
|
+
interface ScrollPhysicsConfig {
|
|
2679
|
+
/** Friction coefficient (0-1, lower = more momentum, default: 0.92) */
|
|
2680
|
+
readonly friction: number;
|
|
2681
|
+
/** Minimum velocity before stopping (default: 0.1) */
|
|
2682
|
+
readonly minVelocity: number;
|
|
2683
|
+
/** Maximum velocity (default: 200) */
|
|
2684
|
+
readonly maxVelocity: number;
|
|
2685
|
+
/** Velocity multiplier for input (default: 1) */
|
|
2686
|
+
readonly sensitivity: number;
|
|
2687
|
+
/** Spring stiffness for overscroll bounce (default: 0.3) */
|
|
2688
|
+
readonly springStiffness: number;
|
|
2689
|
+
/** Spring damping for overscroll bounce (default: 0.8) */
|
|
2690
|
+
readonly springDamping: number;
|
|
2691
|
+
/** Maximum overscroll distance (default: 50) */
|
|
2692
|
+
readonly maxOverscroll: number;
|
|
2693
|
+
/** Whether to enable momentum scrolling (default: true) */
|
|
2694
|
+
readonly enableMomentum: boolean;
|
|
2695
|
+
/** Whether to enable overscroll bounce (default: true) */
|
|
2696
|
+
readonly enableBounce: boolean;
|
|
2697
|
+
}
|
|
2698
|
+
/**
|
|
2699
|
+
* Scroll animation state for a single entity.
|
|
2700
|
+
*/
|
|
2701
|
+
interface ScrollAnimationState {
|
|
2702
|
+
/** Current scroll position */
|
|
2703
|
+
scrollX: number;
|
|
2704
|
+
scrollY: number;
|
|
2705
|
+
/** Current scroll velocity */
|
|
2706
|
+
velocityX: number;
|
|
2707
|
+
velocityY: number;
|
|
2708
|
+
/** Content bounds */
|
|
2709
|
+
contentWidth: number;
|
|
2710
|
+
contentHeight: number;
|
|
2711
|
+
/** Viewport bounds */
|
|
2712
|
+
viewportWidth: number;
|
|
2713
|
+
viewportHeight: number;
|
|
2714
|
+
/** Whether currently animating */
|
|
2715
|
+
isAnimating: boolean;
|
|
2716
|
+
/** Whether user is actively scrolling (input held) */
|
|
2717
|
+
isUserScrolling: boolean;
|
|
2718
|
+
/** Target scroll position (for smooth scrollTo) */
|
|
2719
|
+
targetX: number | null;
|
|
2720
|
+
targetY: number | null;
|
|
2721
|
+
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Scroll event data.
|
|
2724
|
+
*/
|
|
2725
|
+
interface ScrollEvent {
|
|
2726
|
+
/** Entity being scrolled */
|
|
2727
|
+
readonly eid: Entity;
|
|
2728
|
+
/** Scroll delta X */
|
|
2729
|
+
readonly deltaX: number;
|
|
2730
|
+
/** Scroll delta Y */
|
|
2731
|
+
readonly deltaY: number;
|
|
2732
|
+
/** Current scroll position X */
|
|
2733
|
+
readonly scrollX: number;
|
|
2734
|
+
/** Current scroll position Y */
|
|
2735
|
+
readonly scrollY: number;
|
|
2736
|
+
/** Whether momentum is active */
|
|
2737
|
+
readonly isMomentum: boolean;
|
|
2738
|
+
}
|
|
2739
|
+
/**
|
|
2740
|
+
* Creates or gets scroll animation state for an entity.
|
|
2741
|
+
*
|
|
2742
|
+
* @param eid - Entity ID
|
|
2743
|
+
* @param contentWidth - Total content width
|
|
2744
|
+
* @param contentHeight - Total content height
|
|
2745
|
+
* @param viewportWidth - Viewport width
|
|
2746
|
+
* @param viewportHeight - Viewport height
|
|
2747
|
+
* @returns Scroll animation state
|
|
2748
|
+
*
|
|
2749
|
+
* @example
|
|
2750
|
+
* ```typescript
|
|
2751
|
+
* const state = getScrollState(entity, 1000, 5000, 80, 24);
|
|
2752
|
+
* ```
|
|
2753
|
+
*/
|
|
2754
|
+
declare function getScrollState(eid: Entity, contentWidth: number, contentHeight: number, viewportWidth: number, viewportHeight: number): ScrollAnimationState;
|
|
2755
|
+
/**
|
|
2756
|
+
* Removes scroll state for an entity.
|
|
2757
|
+
*
|
|
2758
|
+
* @param eid - Entity ID
|
|
2759
|
+
*/
|
|
2760
|
+
declare function removeScrollState(eid: Entity): void;
|
|
2761
|
+
/**
|
|
2762
|
+
* Clears all scroll states. Used for testing.
|
|
2763
|
+
* @internal
|
|
2764
|
+
*/
|
|
2765
|
+
declare function clearAllScrollStates(): void;
|
|
2766
|
+
/**
|
|
2767
|
+
* Applies a scroll impulse (e.g., from mouse wheel or keyboard).
|
|
2768
|
+
*
|
|
2769
|
+
* @param eid - Entity to scroll
|
|
2770
|
+
* @param deltaX - Horizontal scroll amount
|
|
2771
|
+
* @param deltaY - Vertical scroll amount
|
|
2772
|
+
* @param physics - Physics configuration
|
|
2773
|
+
*
|
|
2774
|
+
* @example
|
|
2775
|
+
* ```typescript
|
|
2776
|
+
* // Mouse wheel scroll
|
|
2777
|
+
* applyScrollImpulse(entity, 0, -3, physicsConfig);
|
|
2778
|
+
*
|
|
2779
|
+
* // Page down
|
|
2780
|
+
* applyScrollImpulse(entity, 0, 24, physicsConfig);
|
|
2781
|
+
* ```
|
|
2782
|
+
*/
|
|
2783
|
+
declare function applyScrollImpulse(eid: Entity, deltaX: number, deltaY: number, physics?: Partial<ScrollPhysicsConfig>): void;
|
|
2784
|
+
/**
|
|
2785
|
+
* Smoothly scrolls to a target position.
|
|
2786
|
+
*
|
|
2787
|
+
* @param eid - Entity to scroll
|
|
2788
|
+
* @param targetX - Target X scroll position (null = don't change)
|
|
2789
|
+
* @param targetY - Target Y scroll position (null = don't change)
|
|
2790
|
+
*
|
|
2791
|
+
* @example
|
|
2792
|
+
* ```typescript
|
|
2793
|
+
* // Scroll to top
|
|
2794
|
+
* smoothScrollTo(entity, null, 0);
|
|
2795
|
+
*
|
|
2796
|
+
* // Scroll to bottom
|
|
2797
|
+
* smoothScrollTo(entity, null, maxScroll);
|
|
2798
|
+
* ```
|
|
2799
|
+
*/
|
|
2800
|
+
declare function smoothScrollTo(eid: Entity, targetX: number | null, targetY: number | null): void;
|
|
2801
|
+
/**
|
|
2802
|
+
* Sets scroll position immediately without animation.
|
|
2803
|
+
*
|
|
2804
|
+
* @param eid - Entity to scroll
|
|
2805
|
+
* @param x - X scroll position
|
|
2806
|
+
* @param y - Y scroll position
|
|
2807
|
+
*/
|
|
2808
|
+
declare function setScrollImmediate(eid: Entity, x: number, y: number): void;
|
|
2809
|
+
/**
|
|
2810
|
+
* Marks the start of user scrolling (e.g., mouse drag).
|
|
2811
|
+
*
|
|
2812
|
+
* @param eid - Entity being scrolled
|
|
2813
|
+
*/
|
|
2814
|
+
declare function startUserScroll(eid: Entity): void;
|
|
2815
|
+
/**
|
|
2816
|
+
* Marks the end of user scrolling, enabling momentum.
|
|
2817
|
+
*
|
|
2818
|
+
* @param eid - Entity being scrolled
|
|
2819
|
+
* @param velocityX - Release velocity X
|
|
2820
|
+
* @param velocityY - Release velocity Y
|
|
2821
|
+
*/
|
|
2822
|
+
declare function endUserScroll(eid: Entity, velocityX: number, velocityY: number): void;
|
|
2823
|
+
declare function updateScrollPhysics(state: ScrollAnimationState, dt: number, physics?: Partial<ScrollPhysicsConfig>): boolean;
|
|
2824
|
+
/**
|
|
2825
|
+
* Checks if an entity has an active scroll animation.
|
|
2826
|
+
*
|
|
2827
|
+
* @param eid - Entity to check
|
|
2828
|
+
* @returns True if the entity is currently scrolling
|
|
2829
|
+
*/
|
|
2830
|
+
declare function isScrolling(eid: Entity): boolean;
|
|
2831
|
+
/**
|
|
2832
|
+
* Gets the current scroll position of an entity.
|
|
2833
|
+
*
|
|
2834
|
+
* @param eid - Entity to query
|
|
2835
|
+
* @returns Scroll position or null if no scroll state
|
|
2836
|
+
*/
|
|
2837
|
+
declare function getScrollPosition(eid: Entity): {
|
|
2838
|
+
x: number;
|
|
2839
|
+
y: number;
|
|
2840
|
+
} | null;
|
|
2841
|
+
/**
|
|
2842
|
+
* Creates a smooth scroll system that updates all active scroll animations.
|
|
2843
|
+
*
|
|
2844
|
+
* @param physics - Physics configuration
|
|
2845
|
+
* @returns System function
|
|
2846
|
+
*
|
|
2847
|
+
* @example
|
|
2848
|
+
* ```typescript
|
|
2849
|
+
* import { createSmoothScrollSystem } from 'blecsd';
|
|
2850
|
+
*
|
|
2851
|
+
* const scrollSystem = createSmoothScrollSystem({
|
|
2852
|
+
* friction: 0.92,
|
|
2853
|
+
* enableMomentum: true,
|
|
2854
|
+
* enableBounce: true,
|
|
2855
|
+
* });
|
|
2856
|
+
*
|
|
2857
|
+
* scheduler.registerSystem(LoopPhase.ANIMATION, scrollSystem);
|
|
2858
|
+
* ```
|
|
2859
|
+
*/
|
|
2860
|
+
declare function createSmoothScrollSystem(physics?: Partial<ScrollPhysicsConfig>): System;
|
|
2861
|
+
|
|
2862
|
+
/**
|
|
2863
|
+
* Spatial hash grid for O(1) collision lookups.
|
|
2864
|
+
*
|
|
2865
|
+
* Partitions 2D space into a uniform grid where each cell tracks
|
|
2866
|
+
* which entities overlap it. Enables efficient broad-phase collision
|
|
2867
|
+
* detection by only checking entities in the same or adjacent cells.
|
|
2868
|
+
*
|
|
2869
|
+
* @module systems/spatialHash
|
|
2870
|
+
*/
|
|
2871
|
+
|
|
2872
|
+
/**
|
|
2873
|
+
* Configuration for the spatial hash grid.
|
|
2874
|
+
*/
|
|
2875
|
+
interface SpatialHashConfig {
|
|
2876
|
+
/** Width of each cell in world units (default: 8) */
|
|
2877
|
+
readonly cellSize: number;
|
|
2878
|
+
/** Initial number of cells in the grid (default: 256) */
|
|
2879
|
+
readonly initialCapacity: number;
|
|
2880
|
+
}
|
|
2881
|
+
/**
|
|
2882
|
+
* A cell coordinate in the spatial hash grid.
|
|
2883
|
+
*/
|
|
2884
|
+
interface CellCoord {
|
|
2885
|
+
readonly cx: number;
|
|
2886
|
+
readonly cy: number;
|
|
2887
|
+
}
|
|
2888
|
+
/**
|
|
2889
|
+
* Spatial hash grid data structure.
|
|
2890
|
+
*/
|
|
2891
|
+
interface SpatialHashGrid {
|
|
2892
|
+
/** Cell size in world units */
|
|
2893
|
+
readonly cellSize: number;
|
|
2894
|
+
/** Map from cell key to set of entity IDs */
|
|
2895
|
+
readonly cells: Map<number, Set<number>>;
|
|
2896
|
+
/** Map from entity ID to set of cell keys it occupies */
|
|
2897
|
+
readonly entityCells: Map<number, Set<number>>;
|
|
2898
|
+
}
|
|
2899
|
+
/**
|
|
2900
|
+
* Statistics about the spatial hash grid.
|
|
2901
|
+
*/
|
|
2902
|
+
interface SpatialHashStats {
|
|
2903
|
+
readonly cellCount: number;
|
|
2904
|
+
readonly entityCount: number;
|
|
2905
|
+
readonly averageEntitiesPerCell: number;
|
|
2906
|
+
readonly maxEntitiesInCell: number;
|
|
2907
|
+
}
|
|
2908
|
+
/** Default cell size */
|
|
2909
|
+
declare const DEFAULT_CELL_SIZE = 8;
|
|
2910
|
+
/**
|
|
2911
|
+
* Creates a new spatial hash grid.
|
|
2912
|
+
*
|
|
2913
|
+
* @param config - Optional configuration
|
|
2914
|
+
* @returns A new spatial hash grid
|
|
2915
|
+
*
|
|
2916
|
+
* @example
|
|
2917
|
+
* ```typescript
|
|
2918
|
+
* import { createSpatialHash } from 'blecsd';
|
|
2919
|
+
*
|
|
2920
|
+
* const grid = createSpatialHash({ cellSize: 4 });
|
|
2921
|
+
* ```
|
|
2922
|
+
*/
|
|
2923
|
+
declare function createSpatialHash(config?: Partial<SpatialHashConfig>): SpatialHashGrid;
|
|
2924
|
+
/**
|
|
2925
|
+
* Gets the cell coordinate for a world position.
|
|
2926
|
+
*
|
|
2927
|
+
* @param grid - The spatial hash grid
|
|
2928
|
+
* @param x - World X coordinate
|
|
2929
|
+
* @param y - World Y coordinate
|
|
2930
|
+
* @returns The cell coordinate
|
|
2931
|
+
*
|
|
2932
|
+
* @example
|
|
2933
|
+
* ```typescript
|
|
2934
|
+
* import { createSpatialHash, worldToCell } from 'blecsd';
|
|
2935
|
+
*
|
|
2936
|
+
* const grid = createSpatialHash({ cellSize: 8 });
|
|
2937
|
+
* const cell = worldToCell(grid, 15, 23);
|
|
2938
|
+
* // cell = { cx: 1, cy: 2 }
|
|
2939
|
+
* ```
|
|
2940
|
+
*/
|
|
2941
|
+
declare function worldToCell(grid: SpatialHashGrid, x: number, y: number): CellCoord;
|
|
2942
|
+
/**
|
|
2943
|
+
* Inserts an entity into the spatial hash at the given position and size.
|
|
2944
|
+
*
|
|
2945
|
+
* @param grid - The spatial hash grid
|
|
2946
|
+
* @param eid - Entity ID
|
|
2947
|
+
* @param x - Entity X position
|
|
2948
|
+
* @param y - Entity Y position
|
|
2949
|
+
* @param width - Entity width (default: 1)
|
|
2950
|
+
* @param height - Entity height (default: 1)
|
|
2951
|
+
*
|
|
2952
|
+
* @example
|
|
2953
|
+
* ```typescript
|
|
2954
|
+
* import { createSpatialHash, insertEntity } from 'blecsd';
|
|
2955
|
+
*
|
|
2956
|
+
* const grid = createSpatialHash();
|
|
2957
|
+
* insertEntity(grid, entity, 10, 20, 2, 3);
|
|
2958
|
+
* ```
|
|
2959
|
+
*/
|
|
2960
|
+
declare function insertEntity(grid: SpatialHashGrid, eid: Entity, x: number, y: number, width?: number, height?: number): void;
|
|
2961
|
+
/**
|
|
2962
|
+
* Removes an entity from the spatial hash.
|
|
2963
|
+
*
|
|
2964
|
+
* @param grid - The spatial hash grid
|
|
2965
|
+
* @param eid - Entity ID to remove
|
|
2966
|
+
*
|
|
2967
|
+
* @example
|
|
2968
|
+
* ```typescript
|
|
2969
|
+
* import { removeEntityFromGrid } from 'blecsd';
|
|
2970
|
+
*
|
|
2971
|
+
* removeEntityFromGrid(grid, entity);
|
|
2972
|
+
* ```
|
|
2973
|
+
*/
|
|
2974
|
+
declare function removeEntityFromGrid(grid: SpatialHashGrid, eid: Entity): void;
|
|
2975
|
+
/**
|
|
2976
|
+
* Gets all entities in the same cell(s) as the given position/area.
|
|
2977
|
+
* This is the core broad-phase query for collision detection.
|
|
2978
|
+
*
|
|
2979
|
+
* @param grid - The spatial hash grid
|
|
2980
|
+
* @param x - Query X position
|
|
2981
|
+
* @param y - Query Y position
|
|
2982
|
+
* @param width - Query width (default: 1)
|
|
2983
|
+
* @param height - Query height (default: 1)
|
|
2984
|
+
* @returns Set of entity IDs that may overlap the query area
|
|
2985
|
+
*
|
|
2986
|
+
* @example
|
|
2987
|
+
* ```typescript
|
|
2988
|
+
* import { createSpatialHash, queryArea } from 'blecsd';
|
|
2989
|
+
*
|
|
2990
|
+
* const nearby = queryArea(grid, playerX, playerY, 2, 2);
|
|
2991
|
+
* for (const eid of nearby) {
|
|
2992
|
+
* // Check narrow-phase collision
|
|
2993
|
+
* }
|
|
2994
|
+
* ```
|
|
2995
|
+
*/
|
|
2996
|
+
declare function queryArea(grid: SpatialHashGrid, x: number, y: number, width?: number, height?: number): ReadonlySet<number>;
|
|
2997
|
+
/**
|
|
2998
|
+
* Gets potential collision candidates for an entity.
|
|
2999
|
+
* Returns all entities in the same cells, excluding the entity itself.
|
|
3000
|
+
*
|
|
3001
|
+
* @param grid - The spatial hash grid
|
|
3002
|
+
* @param eid - Entity to find candidates for
|
|
3003
|
+
* @returns Set of entity IDs that may collide with the given entity
|
|
3004
|
+
*
|
|
3005
|
+
* @example
|
|
3006
|
+
* ```typescript
|
|
3007
|
+
* import { getNearbyEntities } from 'blecsd';
|
|
3008
|
+
*
|
|
3009
|
+
* const candidates = getNearbyEntities(grid, player);
|
|
3010
|
+
* for (const other of candidates) {
|
|
3011
|
+
* // Narrow-phase collision check
|
|
3012
|
+
* }
|
|
3013
|
+
* ```
|
|
3014
|
+
*/
|
|
3015
|
+
declare function getNearbyEntities(grid: SpatialHashGrid, eid: Entity): ReadonlySet<number>;
|
|
3016
|
+
/**
|
|
3017
|
+
* Gets all entities at a specific cell coordinate.
|
|
3018
|
+
*
|
|
3019
|
+
* @param grid - The spatial hash grid
|
|
3020
|
+
* @param cx - Cell X coordinate
|
|
3021
|
+
* @param cy - Cell Y coordinate
|
|
3022
|
+
* @returns Set of entity IDs in that cell
|
|
3023
|
+
*
|
|
3024
|
+
* @example
|
|
3025
|
+
* ```typescript
|
|
3026
|
+
* import { getEntitiesInCell } from 'blecsd';
|
|
3027
|
+
*
|
|
3028
|
+
* const entities = getEntitiesInCell(grid, 3, 5);
|
|
3029
|
+
* ```
|
|
3030
|
+
*/
|
|
3031
|
+
declare function getEntitiesInCell(grid: SpatialHashGrid, cx: number, cy: number): ReadonlySet<number>;
|
|
3032
|
+
/**
|
|
3033
|
+
* Gets all entities at a world position.
|
|
3034
|
+
*
|
|
3035
|
+
* @param grid - The spatial hash grid
|
|
3036
|
+
* @param x - World X coordinate
|
|
3037
|
+
* @param y - World Y coordinate
|
|
3038
|
+
* @returns Set of entity IDs at that position
|
|
3039
|
+
*
|
|
3040
|
+
* @example
|
|
3041
|
+
* ```typescript
|
|
3042
|
+
* import { getEntitiesAtPoint } from 'blecsd';
|
|
3043
|
+
*
|
|
3044
|
+
* const entities = getEntitiesAtPoint(grid, 10, 20);
|
|
3045
|
+
* ```
|
|
3046
|
+
*/
|
|
3047
|
+
declare function getEntitiesAtPoint(grid: SpatialHashGrid, x: number, y: number): ReadonlySet<number>;
|
|
3048
|
+
/**
|
|
3049
|
+
* Clears all entities from the spatial hash grid.
|
|
3050
|
+
*
|
|
3051
|
+
* @param grid - The spatial hash grid to clear
|
|
3052
|
+
*
|
|
3053
|
+
* @example
|
|
3054
|
+
* ```typescript
|
|
3055
|
+
* import { clearSpatialHash } from 'blecsd';
|
|
3056
|
+
*
|
|
3057
|
+
* clearSpatialHash(grid);
|
|
3058
|
+
* ```
|
|
3059
|
+
*/
|
|
3060
|
+
declare function clearSpatialHash(grid: SpatialHashGrid): void;
|
|
3061
|
+
/**
|
|
3062
|
+
* Gets statistics about the spatial hash grid.
|
|
3063
|
+
*
|
|
3064
|
+
* @param grid - The spatial hash grid
|
|
3065
|
+
* @returns Grid statistics
|
|
3066
|
+
*
|
|
3067
|
+
* @example
|
|
3068
|
+
* ```typescript
|
|
3069
|
+
* import { getSpatialHashStats } from 'blecsd';
|
|
3070
|
+
*
|
|
3071
|
+
* const stats = getSpatialHashStats(grid);
|
|
3072
|
+
* console.log(`Cells: ${stats.cellCount}, Entities: ${stats.entityCount}`);
|
|
3073
|
+
* ```
|
|
3074
|
+
*/
|
|
3075
|
+
declare function getSpatialHashStats(grid: SpatialHashGrid): SpatialHashStats;
|
|
3076
|
+
/**
|
|
3077
|
+
* Rebuilds the spatial hash from all entities with Position and Collider components.
|
|
3078
|
+
*
|
|
3079
|
+
* @param grid - The spatial hash grid to rebuild
|
|
3080
|
+
* @param world - The ECS world
|
|
3081
|
+
*
|
|
3082
|
+
* @example
|
|
3083
|
+
* ```typescript
|
|
3084
|
+
* import { createSpatialHash, rebuildSpatialHash } from 'blecsd';
|
|
3085
|
+
*
|
|
3086
|
+
* const grid = createSpatialHash({ cellSize: 4 });
|
|
3087
|
+
* rebuildSpatialHash(grid, world);
|
|
3088
|
+
* ```
|
|
3089
|
+
*/
|
|
3090
|
+
declare function rebuildSpatialHash(grid: SpatialHashGrid, world: World): void;
|
|
3091
|
+
/**
|
|
3092
|
+
* Sets the spatial hash grid for the system to use.
|
|
3093
|
+
*
|
|
3094
|
+
* @param grid - The spatial hash grid
|
|
3095
|
+
*
|
|
3096
|
+
* @example
|
|
3097
|
+
* ```typescript
|
|
3098
|
+
* import { createSpatialHash, setSpatialHashGrid } from 'blecsd';
|
|
3099
|
+
*
|
|
3100
|
+
* const grid = createSpatialHash({ cellSize: 4 });
|
|
3101
|
+
* setSpatialHashGrid(grid);
|
|
3102
|
+
* ```
|
|
3103
|
+
*/
|
|
3104
|
+
declare function setSpatialHashGrid(grid: SpatialHashGrid): void;
|
|
3105
|
+
/**
|
|
3106
|
+
* Gets the current system spatial hash grid.
|
|
3107
|
+
*
|
|
3108
|
+
* @returns The grid, or null if not set
|
|
3109
|
+
*/
|
|
3110
|
+
declare function getSpatialHashGrid(): SpatialHashGrid | null;
|
|
3111
|
+
/**
|
|
3112
|
+
* Spatial hash system that rebuilds the grid each frame.
|
|
3113
|
+
*
|
|
3114
|
+
* Register this in the EARLY_UPDATE phase to ensure collision queries
|
|
3115
|
+
* use up-to-date spatial data.
|
|
3116
|
+
*
|
|
3117
|
+
* @example
|
|
3118
|
+
* ```typescript
|
|
3119
|
+
* import { createSpatialHash, setSpatialHashGrid, spatialHashSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
3120
|
+
*
|
|
3121
|
+
* const grid = createSpatialHash({ cellSize: 4 });
|
|
3122
|
+
* setSpatialHashGrid(grid);
|
|
3123
|
+
*
|
|
3124
|
+
* const scheduler = createScheduler();
|
|
3125
|
+
* scheduler.registerSystem(LoopPhase.EARLY_UPDATE, spatialHashSystem);
|
|
3126
|
+
* ```
|
|
3127
|
+
*/
|
|
3128
|
+
declare const spatialHashSystem: System;
|
|
3129
|
+
/**
|
|
3130
|
+
* Creates a new spatial hash system.
|
|
3131
|
+
*
|
|
3132
|
+
* @returns The system function
|
|
3133
|
+
*/
|
|
3134
|
+
declare function createSpatialHashSystem(): System;
|
|
3135
|
+
|
|
3136
|
+
/**
|
|
3137
|
+
* State machine system for updating entity state age.
|
|
3138
|
+
* Processes all entities with StateMachine component.
|
|
3139
|
+
* @module systems/stateMachineSystem
|
|
3140
|
+
*/
|
|
3141
|
+
|
|
3142
|
+
/**
|
|
3143
|
+
* Query all entities with the StateMachine component.
|
|
3144
|
+
*
|
|
3145
|
+
* @param world - The ECS world
|
|
3146
|
+
* @returns Array of entity IDs with StateMachine component
|
|
3147
|
+
*/
|
|
3148
|
+
declare function queryStateMachine(world: World): number[];
|
|
3149
|
+
/**
|
|
3150
|
+
* Gets the state age store for direct access.
|
|
3151
|
+
* Use with caution; primarily for testing.
|
|
3152
|
+
*
|
|
3153
|
+
* @returns The state age array
|
|
3154
|
+
*/
|
|
3155
|
+
declare function getStateAgeStore(): Float32Array;
|
|
3156
|
+
/**
|
|
3157
|
+
* State machine system that updates the stateAge for all entities
|
|
3158
|
+
* with a StateMachine component.
|
|
3159
|
+
*
|
|
3160
|
+
* This system should be registered in the UPDATE phase of the game loop.
|
|
3161
|
+
* It reads delta time from getDeltaTime() which is set by the scheduler.
|
|
3162
|
+
*
|
|
3163
|
+
* The system updates each entity's stateAge by adding the frame's delta time.
|
|
3164
|
+
* This allows game logic to check how long an entity has been in its current
|
|
3165
|
+
* state for time-based transitions or animations.
|
|
3166
|
+
*
|
|
3167
|
+
* @param world - The ECS world to process
|
|
3168
|
+
* @returns The world (unchanged reference, but stateAge values updated)
|
|
3169
|
+
*
|
|
3170
|
+
* @example
|
|
3171
|
+
* ```typescript
|
|
3172
|
+
* import { createScheduler, LoopPhase, stateMachineSystem } from 'blecsd';
|
|
3173
|
+
*
|
|
3174
|
+
* const scheduler = createScheduler();
|
|
3175
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, stateMachineSystem);
|
|
3176
|
+
*
|
|
3177
|
+
* // In game loop
|
|
3178
|
+
* scheduler.run(world, deltaTime);
|
|
3179
|
+
* ```
|
|
3180
|
+
*/
|
|
3181
|
+
declare const stateMachineSystem: System;
|
|
3182
|
+
/**
|
|
3183
|
+
* Creates a new state machine system.
|
|
3184
|
+
*
|
|
3185
|
+
* Factory function that returns the stateMachineSystem.
|
|
3186
|
+
* Useful for cases where you need a fresh reference or want to
|
|
3187
|
+
* match the factory pattern used elsewhere in the codebase.
|
|
3188
|
+
*
|
|
3189
|
+
* @returns The state machine system function
|
|
3190
|
+
*
|
|
3191
|
+
* @example
|
|
3192
|
+
* ```typescript
|
|
3193
|
+
* import { createStateMachineSystem, createScheduler, LoopPhase } from 'blecsd';
|
|
3194
|
+
*
|
|
3195
|
+
* const scheduler = createScheduler();
|
|
3196
|
+
* const system = createStateMachineSystem();
|
|
3197
|
+
* scheduler.registerSystem(LoopPhase.UPDATE, system);
|
|
3198
|
+
* ```
|
|
3199
|
+
*/
|
|
3200
|
+
declare function createStateMachineSystem(): System;
|
|
3201
|
+
/**
|
|
3202
|
+
* Registers the state machine system with a scheduler.
|
|
3203
|
+
*
|
|
3204
|
+
* Convenience function that registers stateMachineSystem in the UPDATE phase.
|
|
3205
|
+
*
|
|
3206
|
+
* @param scheduler - The scheduler to register with
|
|
3207
|
+
* @param priority - Optional priority within the UPDATE phase (default: 0)
|
|
3208
|
+
*
|
|
3209
|
+
* @example
|
|
3210
|
+
* ```typescript
|
|
3211
|
+
* import { createScheduler, registerStateMachineSystem } from 'blecsd';
|
|
3212
|
+
*
|
|
3213
|
+
* const scheduler = createScheduler();
|
|
3214
|
+
* registerStateMachineSystem(scheduler);
|
|
3215
|
+
*
|
|
3216
|
+
* // State machine updates will now happen in UPDATE phase
|
|
3217
|
+
* scheduler.run(world, deltaTime);
|
|
3218
|
+
* ```
|
|
3219
|
+
*/
|
|
3220
|
+
declare function registerStateMachineSystem(scheduler: Scheduler, priority?: number): void;
|
|
3221
|
+
/**
|
|
3222
|
+
* Manually update state age for specific entities.
|
|
3223
|
+
*
|
|
3224
|
+
* Useful when you need to update state age outside of the system,
|
|
3225
|
+
* such as in tests or custom update loops.
|
|
3226
|
+
*
|
|
3227
|
+
* @param entities - Array of entity IDs to update
|
|
3228
|
+
* @param deltaTime - Time elapsed in seconds
|
|
3229
|
+
*
|
|
3230
|
+
* @example
|
|
3231
|
+
* ```typescript
|
|
3232
|
+
* import { updateStateAges, queryStateMachine } from 'blecsd';
|
|
3233
|
+
*
|
|
3234
|
+
* // Manual update (typically use the system instead)
|
|
3235
|
+
* const entities = queryStateMachine(world);
|
|
3236
|
+
* updateStateAges(entities, 0.016); // ~60fps frame
|
|
3237
|
+
* ```
|
|
3238
|
+
*/
|
|
3239
|
+
declare function updateStateAges(entities: readonly number[], deltaTime: number): void;
|
|
3240
|
+
/**
|
|
3241
|
+
* Resets the state age for an entity to zero.
|
|
3242
|
+
*
|
|
3243
|
+
* Typically called when a state transition occurs (handled by
|
|
3244
|
+
* sendEvent in components/stateMachine.ts), but can be called
|
|
3245
|
+
* manually for custom state management.
|
|
3246
|
+
*
|
|
3247
|
+
* @param eid - Entity ID to reset
|
|
3248
|
+
*
|
|
3249
|
+
* @example
|
|
3250
|
+
* ```typescript
|
|
3251
|
+
* import { resetStateAge } from 'blecsd';
|
|
3252
|
+
*
|
|
3253
|
+
* // After a manual state transition
|
|
3254
|
+
* resetStateAge(entityId);
|
|
3255
|
+
* ```
|
|
3256
|
+
*/
|
|
3257
|
+
declare function resetStateAge(eid: number): void;
|
|
3258
|
+
/**
|
|
3259
|
+
* Gets the state age for an entity from the system store.
|
|
3260
|
+
*
|
|
3261
|
+
* @param eid - Entity ID to query
|
|
3262
|
+
* @returns Time in seconds the entity has been in current state
|
|
3263
|
+
*
|
|
3264
|
+
* @example
|
|
3265
|
+
* ```typescript
|
|
3266
|
+
* import { getSystemStateAge } from 'blecsd';
|
|
3267
|
+
*
|
|
3268
|
+
* const age = getSystemStateAge(entityId);
|
|
3269
|
+
* if (age > 5.0) {
|
|
3270
|
+
* // Entity has been in state for over 5 seconds
|
|
3271
|
+
* }
|
|
3272
|
+
* ```
|
|
3273
|
+
*/
|
|
3274
|
+
declare function getSystemStateAge(eid: number): number;
|
|
3275
|
+
|
|
3276
|
+
/**
|
|
3277
|
+
* TileMap rendering system for rendering tile maps to a buffer.
|
|
3278
|
+
*
|
|
3279
|
+
* Queries entities with TileMap and Position components, then renders
|
|
3280
|
+
* visible tiles to a 2D buffer. Supports camera offset for scrolling
|
|
3281
|
+
* and dirty region tracking for efficient updates.
|
|
3282
|
+
*
|
|
3283
|
+
* @module systems/tilemapRenderer
|
|
3284
|
+
*/
|
|
3285
|
+
|
|
3286
|
+
/**
|
|
3287
|
+
* A rendered tile map buffer.
|
|
3288
|
+
* Stores the final composited output from all tile map entities.
|
|
3289
|
+
*/
|
|
3290
|
+
interface TileMapBuffer {
|
|
3291
|
+
/** Buffer width in cells */
|
|
3292
|
+
readonly width: number;
|
|
3293
|
+
/** Buffer height in cells */
|
|
3294
|
+
readonly height: number;
|
|
3295
|
+
/** 2D array of rendered cells (row-major: [y][x]) */
|
|
3296
|
+
readonly cells: RenderedTileCell[][];
|
|
3297
|
+
}
|
|
3298
|
+
/**
|
|
3299
|
+
* Camera offset for tile map rendering.
|
|
3300
|
+
*/
|
|
3301
|
+
interface TileMapCamera {
|
|
3302
|
+
/** Camera X offset in world units (pixels/cells) */
|
|
3303
|
+
x: number;
|
|
3304
|
+
/** Camera Y offset in world units (pixels/cells) */
|
|
3305
|
+
y: number;
|
|
3306
|
+
}
|
|
3307
|
+
/**
|
|
3308
|
+
* Configuration for the tile map renderer.
|
|
3309
|
+
*/
|
|
3310
|
+
interface TileMapRendererConfig {
|
|
3311
|
+
/** Viewport width in cells */
|
|
3312
|
+
viewportWidth: number;
|
|
3313
|
+
/** Viewport height in cells */
|
|
3314
|
+
viewportHeight: number;
|
|
3315
|
+
/** Camera offset */
|
|
3316
|
+
camera: TileMapCamera;
|
|
3317
|
+
}
|
|
3318
|
+
/**
|
|
3319
|
+
* Sets the tile map renderer configuration.
|
|
3320
|
+
*
|
|
3321
|
+
* @param config - The renderer configuration
|
|
3322
|
+
*
|
|
3323
|
+
* @example
|
|
3324
|
+
* ```typescript
|
|
3325
|
+
* import { setTileMapRendererConfig } from 'blecsd';
|
|
3326
|
+
*
|
|
3327
|
+
* setTileMapRendererConfig({
|
|
3328
|
+
* viewportWidth: 80,
|
|
3329
|
+
* viewportHeight: 24,
|
|
3330
|
+
* camera: { x: 0, y: 0 },
|
|
3331
|
+
* });
|
|
3332
|
+
* ```
|
|
3333
|
+
*/
|
|
3334
|
+
declare function setTileMapRendererConfig(config: TileMapRendererConfig): void;
|
|
3335
|
+
/**
|
|
3336
|
+
* Gets the current tile map renderer configuration.
|
|
3337
|
+
*
|
|
3338
|
+
* @returns The renderer config or null if not set
|
|
3339
|
+
*/
|
|
3340
|
+
declare function getTileMapRendererConfig(): TileMapRendererConfig | null;
|
|
3341
|
+
/**
|
|
3342
|
+
* Gets the current render buffer.
|
|
3343
|
+
*
|
|
3344
|
+
* @returns The render buffer or null if not rendered yet
|
|
3345
|
+
*
|
|
3346
|
+
* @example
|
|
3347
|
+
* ```typescript
|
|
3348
|
+
* import { getTileMapRenderBuffer } from 'blecsd';
|
|
3349
|
+
*
|
|
3350
|
+
* const buffer = getTileMapRenderBuffer();
|
|
3351
|
+
* if (buffer) {
|
|
3352
|
+
* for (let y = 0; y < buffer.height; y++) {
|
|
3353
|
+
* for (let x = 0; x < buffer.width; x++) {
|
|
3354
|
+
* const cell = buffer.cells[y][x];
|
|
3355
|
+
* // Use cell.char, cell.fg, cell.bg
|
|
3356
|
+
* }
|
|
3357
|
+
* }
|
|
3358
|
+
* }
|
|
3359
|
+
* ```
|
|
3360
|
+
*/
|
|
3361
|
+
declare function getTileMapRenderBuffer(): TileMapBuffer | null;
|
|
3362
|
+
/**
|
|
3363
|
+
* Clears the render buffer.
|
|
3364
|
+
*/
|
|
3365
|
+
declare function clearTileMapRenderBuffer(): void;
|
|
3366
|
+
/**
|
|
3367
|
+
* Resets the tile map renderer state (config and buffer).
|
|
3368
|
+
* Useful for testing.
|
|
3369
|
+
*
|
|
3370
|
+
* @example
|
|
3371
|
+
* ```typescript
|
|
3372
|
+
* import { resetTileMapRenderer } from 'blecsd';
|
|
3373
|
+
*
|
|
3374
|
+
* resetTileMapRenderer();
|
|
3375
|
+
* ```
|
|
3376
|
+
*/
|
|
3377
|
+
declare function resetTileMapRenderer(): void;
|
|
3378
|
+
/**
|
|
3379
|
+
* Creates an empty tile map buffer filled with empty cells.
|
|
3380
|
+
*
|
|
3381
|
+
* @param width - Buffer width in cells
|
|
3382
|
+
* @param height - Buffer height in cells
|
|
3383
|
+
* @returns A new empty buffer
|
|
3384
|
+
*/
|
|
3385
|
+
declare function createEmptyBuffer(width: number, height: number): TileMapBuffer;
|
|
3386
|
+
/**
|
|
3387
|
+
* Renders a single tile map entity into a buffer.
|
|
3388
|
+
* Takes into account entity position and camera offset.
|
|
3389
|
+
*
|
|
3390
|
+
* @param buffer - The target buffer
|
|
3391
|
+
* @param eid - The entity ID
|
|
3392
|
+
* @param cameraX - Camera X offset in world units
|
|
3393
|
+
* @param cameraY - Camera Y offset in world units
|
|
3394
|
+
*
|
|
3395
|
+
* @example
|
|
3396
|
+
* ```typescript
|
|
3397
|
+
* import { createEmptyBuffer, renderTileMapToBuffer } from 'blecsd';
|
|
3398
|
+
*
|
|
3399
|
+
* const buffer = createEmptyBuffer(80, 24);
|
|
3400
|
+
* renderTileMapToBuffer(buffer, mapEntity, 0, 0);
|
|
3401
|
+
* ```
|
|
3402
|
+
*/
|
|
3403
|
+
declare function renderTileMapToBuffer(buffer: TileMapBuffer, eid: Entity, cameraX: number, cameraY: number): void;
|
|
3404
|
+
/**
|
|
3405
|
+
* Renders all tile map entities in the world to the render buffer.
|
|
3406
|
+
* Uses the configured viewport and camera offset.
|
|
3407
|
+
*
|
|
3408
|
+
* @param world - The ECS world
|
|
3409
|
+
* @returns The render buffer
|
|
3410
|
+
*
|
|
3411
|
+
* @example
|
|
3412
|
+
* ```typescript
|
|
3413
|
+
* import { setTileMapRendererConfig, renderAllTileMaps } from 'blecsd';
|
|
3414
|
+
*
|
|
3415
|
+
* setTileMapRendererConfig({
|
|
3416
|
+
* viewportWidth: 80,
|
|
3417
|
+
* viewportHeight: 24,
|
|
3418
|
+
* camera: { x: 0, y: 0 },
|
|
3419
|
+
* });
|
|
3420
|
+
*
|
|
3421
|
+
* const buffer = renderAllTileMaps(world);
|
|
3422
|
+
* ```
|
|
3423
|
+
*/
|
|
3424
|
+
declare function renderAllTileMaps(world: World): TileMapBuffer | null;
|
|
3425
|
+
/**
|
|
3426
|
+
* TileMap rendering system that renders all tile maps each frame.
|
|
3427
|
+
*
|
|
3428
|
+
* Requires renderer config to be set via setTileMapRendererConfig()
|
|
3429
|
+
* before the system runs. Queries all entities with TileMap and Position
|
|
3430
|
+
* components and composites them into a single render buffer.
|
|
3431
|
+
*
|
|
3432
|
+
* Register this in the RENDER phase.
|
|
3433
|
+
*
|
|
3434
|
+
* @example
|
|
3435
|
+
* ```typescript
|
|
3436
|
+
* import {
|
|
3437
|
+
* setTileMapRendererConfig,
|
|
3438
|
+
* tilemapRenderSystem,
|
|
3439
|
+
* createScheduler,
|
|
3440
|
+
* LoopPhase,
|
|
3441
|
+
* } from 'blecsd';
|
|
3442
|
+
*
|
|
3443
|
+
* setTileMapRendererConfig({
|
|
3444
|
+
* viewportWidth: 80,
|
|
3445
|
+
* viewportHeight: 24,
|
|
3446
|
+
* camera: { x: 0, y: 0 },
|
|
3447
|
+
* });
|
|
3448
|
+
*
|
|
3449
|
+
* const scheduler = createScheduler();
|
|
3450
|
+
* scheduler.registerSystem(LoopPhase.RENDER, tilemapRenderSystem);
|
|
3451
|
+
* ```
|
|
3452
|
+
*/
|
|
3453
|
+
declare const tilemapRenderSystem: System;
|
|
3454
|
+
/**
|
|
3455
|
+
* Creates a new tilemap render system.
|
|
3456
|
+
*
|
|
3457
|
+
* @returns The system function
|
|
3458
|
+
*/
|
|
3459
|
+
declare function createTilemapRenderSystem(): System;
|
|
3460
|
+
|
|
3461
|
+
/**
|
|
3462
|
+
* Virtualized Render System for Large Content
|
|
3463
|
+
*
|
|
3464
|
+
* Renders only visible lines from VirtualViewport-enabled entities.
|
|
3465
|
+
* Achieves 60fps scroll performance with 10M+ lines by skipping off-screen content.
|
|
3466
|
+
*
|
|
3467
|
+
* @module systems/virtualizedRenderSystem
|
|
3468
|
+
*
|
|
3469
|
+
* @example
|
|
3470
|
+
* ```typescript
|
|
3471
|
+
* import {
|
|
3472
|
+
* virtualizedRenderSystem,
|
|
3473
|
+
* setVirtualizedRenderBuffer,
|
|
3474
|
+
* registerLineStore,
|
|
3475
|
+
* } from 'blecsd';
|
|
3476
|
+
*
|
|
3477
|
+
* // Set up the render buffer
|
|
3478
|
+
* setVirtualizedRenderBuffer(doubleBuffer);
|
|
3479
|
+
*
|
|
3480
|
+
* // Associate a line store with an entity
|
|
3481
|
+
* registerLineStore(entity, lineStore);
|
|
3482
|
+
*
|
|
3483
|
+
* // Run the system
|
|
3484
|
+
* virtualizedRenderSystem(world);
|
|
3485
|
+
* ```
|
|
3486
|
+
*/
|
|
3487
|
+
|
|
3488
|
+
/**
|
|
3489
|
+
* Schema for line render configuration with defaults (for full config).
|
|
3490
|
+
*
|
|
3491
|
+
* @example
|
|
3492
|
+
* ```typescript
|
|
3493
|
+
* import { LineRenderConfigSchema } from 'blecsd';
|
|
3494
|
+
*
|
|
3495
|
+
* const config = LineRenderConfigSchema.parse({
|
|
3496
|
+
* fg: 0xffffffff,
|
|
3497
|
+
* bg: 0x000000ff,
|
|
3498
|
+
* showLineNumbers: true,
|
|
3499
|
+
* lineNumberWidth: 5,
|
|
3500
|
+
* });
|
|
3501
|
+
* ```
|
|
3502
|
+
*/
|
|
3503
|
+
declare const LineRenderConfigSchema: z.ZodObject<{
|
|
3504
|
+
fg: z.ZodDefault<z.ZodNumber>;
|
|
3505
|
+
bg: z.ZodDefault<z.ZodNumber>;
|
|
3506
|
+
selectedFg: z.ZodDefault<z.ZodNumber>;
|
|
3507
|
+
selectedBg: z.ZodDefault<z.ZodNumber>;
|
|
3508
|
+
cursorFg: z.ZodDefault<z.ZodNumber>;
|
|
3509
|
+
cursorBg: z.ZodDefault<z.ZodNumber>;
|
|
3510
|
+
showLineNumbers: z.ZodDefault<z.ZodBoolean>;
|
|
3511
|
+
lineNumberWidth: z.ZodDefault<z.ZodNumber>;
|
|
3512
|
+
attrs: z.ZodDefault<z.ZodNumber>;
|
|
3513
|
+
}, z.core.$strip>;
|
|
3514
|
+
/**
|
|
3515
|
+
* Render context for virtualized rendering.
|
|
3516
|
+
*/
|
|
3517
|
+
interface VirtualizedRenderContext {
|
|
3518
|
+
/** The ECS world */
|
|
3519
|
+
readonly world: World;
|
|
3520
|
+
/** The screen buffer to render to */
|
|
3521
|
+
readonly buffer: ScreenBufferData;
|
|
3522
|
+
/** The double buffer for dirty tracking */
|
|
3523
|
+
readonly doubleBuffer: DoubleBufferData;
|
|
3524
|
+
}
|
|
3525
|
+
/**
|
|
3526
|
+
* Line render configuration.
|
|
3527
|
+
*/
|
|
3528
|
+
interface LineRenderConfig {
|
|
3529
|
+
/** Foreground color for normal lines */
|
|
3530
|
+
readonly fg: number;
|
|
3531
|
+
/** Background color for normal lines */
|
|
3532
|
+
readonly bg: number;
|
|
3533
|
+
/** Foreground color for selected line */
|
|
3534
|
+
readonly selectedFg: number;
|
|
3535
|
+
/** Background color for selected line */
|
|
3536
|
+
readonly selectedBg: number;
|
|
3537
|
+
/** Foreground color for cursor line */
|
|
3538
|
+
readonly cursorFg: number;
|
|
3539
|
+
/** Background color for cursor line */
|
|
3540
|
+
readonly cursorBg: number;
|
|
3541
|
+
/** Whether to show line numbers */
|
|
3542
|
+
readonly showLineNumbers: boolean;
|
|
3543
|
+
/** Width reserved for line numbers (0 if not shown) */
|
|
3544
|
+
readonly lineNumberWidth: number;
|
|
3545
|
+
/** Attributes for text */
|
|
3546
|
+
readonly attrs: number;
|
|
3547
|
+
}
|
|
3548
|
+
/**
|
|
3549
|
+
* Sets the double buffer for the virtualized render system.
|
|
3550
|
+
*
|
|
3551
|
+
* @param db - The double buffer to render to
|
|
3552
|
+
*
|
|
3553
|
+
* @example
|
|
3554
|
+
* ```typescript
|
|
3555
|
+
* import { setVirtualizedRenderBuffer, createDoubleBuffer } from 'blecsd';
|
|
3556
|
+
*
|
|
3557
|
+
* const db = createDoubleBuffer(80, 24);
|
|
3558
|
+
* setVirtualizedRenderBuffer(db);
|
|
3559
|
+
* ```
|
|
3560
|
+
*/
|
|
3561
|
+
declare function setVirtualizedRenderBuffer(db: DoubleBufferData): void;
|
|
3562
|
+
/**
|
|
3563
|
+
* Gets the current virtualized render buffer.
|
|
3564
|
+
*
|
|
3565
|
+
* @returns The current double buffer or null
|
|
3566
|
+
*/
|
|
3567
|
+
declare function getVirtualizedRenderBuffer(): DoubleBufferData | null;
|
|
3568
|
+
/**
|
|
3569
|
+
* Clears the virtualized render buffer reference.
|
|
3570
|
+
*/
|
|
3571
|
+
declare function clearVirtualizedRenderBuffer(): void;
|
|
3572
|
+
/**
|
|
3573
|
+
* Registers a line store for an entity.
|
|
3574
|
+
* The virtualized render system will use this store to get content.
|
|
3575
|
+
*
|
|
3576
|
+
* @param eid - Entity ID
|
|
3577
|
+
* @param store - The line store containing content
|
|
3578
|
+
*
|
|
3579
|
+
* @example
|
|
3580
|
+
* ```typescript
|
|
3581
|
+
* import { registerLineStore, createLineStore } from 'blecsd';
|
|
3582
|
+
*
|
|
3583
|
+
* const store = createLineStore(largeContent);
|
|
3584
|
+
* registerLineStore(entity, store);
|
|
3585
|
+
* ```
|
|
3586
|
+
*/
|
|
3587
|
+
declare function registerLineStore(eid: Entity, store: VirtualizedLineStore): void;
|
|
3588
|
+
/**
|
|
3589
|
+
* Gets the line store for an entity.
|
|
3590
|
+
*
|
|
3591
|
+
* @param eid - Entity ID
|
|
3592
|
+
* @returns The line store or undefined
|
|
3593
|
+
*/
|
|
3594
|
+
declare function getLineStore(eid: Entity): VirtualizedLineStore | undefined;
|
|
3595
|
+
/**
|
|
3596
|
+
* Unregisters a line store for an entity.
|
|
3597
|
+
*
|
|
3598
|
+
* @param eid - Entity ID
|
|
3599
|
+
*/
|
|
3600
|
+
declare function unregisterLineStore(eid: Entity): void;
|
|
3601
|
+
/**
|
|
3602
|
+
* Updates the line store for an entity.
|
|
3603
|
+
* Use this when content changes (e.g., streaming append).
|
|
3604
|
+
*
|
|
3605
|
+
* @param eid - Entity ID
|
|
3606
|
+
* @param store - The new line store
|
|
3607
|
+
*/
|
|
3608
|
+
declare function updateLineStore(eid: Entity, store: VirtualizedLineStore): void;
|
|
3609
|
+
/**
|
|
3610
|
+
* Sets the line render configuration for an entity.
|
|
3611
|
+
* Input is validated against LineRenderConfigSchema.
|
|
3612
|
+
*
|
|
3613
|
+
* @param eid - Entity ID
|
|
3614
|
+
* @param config - Partial config (merged with defaults)
|
|
3615
|
+
* @throws {z.ZodError} If config values are invalid
|
|
3616
|
+
*
|
|
3617
|
+
* @example
|
|
3618
|
+
* ```typescript
|
|
3619
|
+
* import { setLineRenderConfig } from 'blecsd';
|
|
3620
|
+
*
|
|
3621
|
+
* setLineRenderConfig(entity, {
|
|
3622
|
+
* showLineNumbers: true,
|
|
3623
|
+
* lineNumberWidth: 5,
|
|
3624
|
+
* selectedBg: 0x0000ffff, // Blue selection
|
|
3625
|
+
* });
|
|
3626
|
+
* ```
|
|
3627
|
+
*/
|
|
3628
|
+
declare function setLineRenderConfig(eid: Entity, config: Partial<LineRenderConfig>): void;
|
|
3629
|
+
/**
|
|
3630
|
+
* Gets the line render configuration for an entity.
|
|
3631
|
+
*
|
|
3632
|
+
* @param eid - Entity ID
|
|
3633
|
+
* @returns The line render config
|
|
3634
|
+
*/
|
|
3635
|
+
declare function getLineRenderConfig(eid: Entity): LineRenderConfig;
|
|
3636
|
+
/**
|
|
3637
|
+
* Clears the line render configuration for an entity.
|
|
3638
|
+
*
|
|
3639
|
+
* @param eid - Entity ID
|
|
3640
|
+
*/
|
|
3641
|
+
declare function clearLineRenderConfig(eid: Entity): void;
|
|
3642
|
+
/**
|
|
3643
|
+
* Virtualized render system that only renders visible lines.
|
|
3644
|
+
*
|
|
3645
|
+
* The system:
|
|
3646
|
+
* 1. Queries all entities with VirtualViewport
|
|
3647
|
+
* 2. Filters to visible, dirty entities
|
|
3648
|
+
* 3. Gets visible line range from viewport
|
|
3649
|
+
* 4. Retrieves only visible lines from line store
|
|
3650
|
+
* 5. Renders to screen buffer
|
|
3651
|
+
* 6. Marks entities as clean
|
|
3652
|
+
*
|
|
3653
|
+
* @param world - The ECS world
|
|
3654
|
+
* @returns The world (unchanged)
|
|
3655
|
+
*
|
|
3656
|
+
* @example
|
|
3657
|
+
* ```typescript
|
|
3658
|
+
* import {
|
|
3659
|
+
* virtualizedRenderSystem,
|
|
3660
|
+
* setVirtualizedRenderBuffer,
|
|
3661
|
+
* registerLineStore,
|
|
3662
|
+
* createScheduler,
|
|
3663
|
+
* LoopPhase,
|
|
3664
|
+
* } from 'blecsd';
|
|
3665
|
+
*
|
|
3666
|
+
* // Set up
|
|
3667
|
+
* setVirtualizedRenderBuffer(doubleBuffer);
|
|
3668
|
+
* registerLineStore(entity, lineStore);
|
|
3669
|
+
*
|
|
3670
|
+
* // Register system
|
|
3671
|
+
* const scheduler = createScheduler();
|
|
3672
|
+
* scheduler.registerSystem(LoopPhase.RENDER, virtualizedRenderSystem);
|
|
3673
|
+
*
|
|
3674
|
+
* // Run
|
|
3675
|
+
* scheduler.run(world, deltaTime);
|
|
3676
|
+
* ```
|
|
3677
|
+
*/
|
|
3678
|
+
declare const virtualizedRenderSystem: System;
|
|
3679
|
+
/**
|
|
3680
|
+
* Creates a new virtualized render system.
|
|
3681
|
+
*
|
|
3682
|
+
* @returns A new render system function
|
|
3683
|
+
*/
|
|
3684
|
+
declare function createVirtualizedRenderSystem(): System;
|
|
3685
|
+
/**
|
|
3686
|
+
* Cleans up all resources for the virtualized render system.
|
|
3687
|
+
* Call this when shutting down.
|
|
3688
|
+
*/
|
|
3689
|
+
declare function cleanupVirtualizedRenderSystem(): void;
|
|
3690
|
+
/**
|
|
3691
|
+
* Cleans up resources for a specific entity.
|
|
3692
|
+
*
|
|
3693
|
+
* @param eid - Entity ID
|
|
3694
|
+
*/
|
|
3695
|
+
declare function cleanupEntityResources(eid: Entity): void;
|
|
3696
|
+
|
|
3697
|
+
/**
|
|
3698
|
+
* Visibility Culling: Efficient entity visibility determination using spatial indexing
|
|
3699
|
+
*
|
|
3700
|
+
* Uses the spatial hash grid for O(1) visibility queries, determining which
|
|
3701
|
+
* entities overlap the current viewport. Supports incremental updates for
|
|
3702
|
+
* moving entities.
|
|
3703
|
+
*
|
|
3704
|
+
* @module systems/visibilityCulling
|
|
3705
|
+
*/
|
|
3706
|
+
|
|
3707
|
+
/**
|
|
3708
|
+
* Viewport definition for culling.
|
|
3709
|
+
*/
|
|
3710
|
+
interface Viewport {
|
|
3711
|
+
/** Viewport left edge */
|
|
3712
|
+
readonly x: number;
|
|
3713
|
+
/** Viewport top edge */
|
|
3714
|
+
readonly y: number;
|
|
3715
|
+
/** Viewport width */
|
|
3716
|
+
readonly width: number;
|
|
3717
|
+
/** Viewport height */
|
|
3718
|
+
readonly height: number;
|
|
3719
|
+
}
|
|
3720
|
+
/**
|
|
3721
|
+
* Visibility culling result.
|
|
3722
|
+
*/
|
|
3723
|
+
interface CullingResult {
|
|
3724
|
+
/** Entities visible in the viewport */
|
|
3725
|
+
readonly visible: readonly Entity[];
|
|
3726
|
+
/** Total entities considered */
|
|
3727
|
+
readonly total: number;
|
|
3728
|
+
/** Number of entities culled (not visible) */
|
|
3729
|
+
readonly culled: number;
|
|
3730
|
+
}
|
|
3731
|
+
/**
|
|
3732
|
+
* Entity position cache for incremental updates.
|
|
3733
|
+
*/
|
|
3734
|
+
interface PositionCache {
|
|
3735
|
+
/** Previous x position per entity */
|
|
3736
|
+
readonly prevX: Map<number, number>;
|
|
3737
|
+
/** Previous y position per entity */
|
|
3738
|
+
readonly prevY: Map<number, number>;
|
|
3739
|
+
/** Previous width per entity */
|
|
3740
|
+
readonly prevW: Map<number, number>;
|
|
3741
|
+
/** Previous height per entity */
|
|
3742
|
+
readonly prevH: Map<number, number>;
|
|
3743
|
+
}
|
|
3744
|
+
/**
|
|
3745
|
+
* Creates a position cache for tracking entity movement.
|
|
3746
|
+
*
|
|
3747
|
+
* @returns Empty position cache
|
|
3748
|
+
*
|
|
3749
|
+
* @example
|
|
3750
|
+
* ```typescript
|
|
3751
|
+
* import { createPositionCache } from 'blecsd';
|
|
3752
|
+
*
|
|
3753
|
+
* const cache = createPositionCache();
|
|
3754
|
+
* ```
|
|
3755
|
+
*/
|
|
3756
|
+
declare function createPositionCache(): PositionCache;
|
|
3757
|
+
/**
|
|
3758
|
+
* Updates a single entity in the spatial hash only if it has moved.
|
|
3759
|
+
* Returns true if the entity was updated.
|
|
3760
|
+
*
|
|
3761
|
+
* @param grid - Spatial hash grid
|
|
3762
|
+
* @param cache - Position cache
|
|
3763
|
+
* @param eid - Entity to check
|
|
3764
|
+
* @param x - Current x position
|
|
3765
|
+
* @param y - Current y position
|
|
3766
|
+
* @param w - Current width
|
|
3767
|
+
* @param h - Current height
|
|
3768
|
+
* @returns True if entity was updated in the grid
|
|
3769
|
+
*/
|
|
3770
|
+
declare function updateEntityIfMoved(grid: SpatialHashGrid, cache: PositionCache, eid: Entity, x: number, y: number, w: number, h: number): boolean;
|
|
3771
|
+
/**
|
|
3772
|
+
* Removes an entity from the position cache.
|
|
3773
|
+
*
|
|
3774
|
+
* @param cache - Position cache
|
|
3775
|
+
* @param eid - Entity to remove
|
|
3776
|
+
*/
|
|
3777
|
+
declare function removeFromCache(cache: PositionCache, eid: Entity): void;
|
|
3778
|
+
/**
|
|
3779
|
+
* Clears the entire position cache.
|
|
3780
|
+
*
|
|
3781
|
+
* @param cache - Position cache to clear
|
|
3782
|
+
*/
|
|
3783
|
+
declare function clearPositionCache(cache: PositionCache): void;
|
|
3784
|
+
/**
|
|
3785
|
+
* Queries which entities are visible within the given viewport.
|
|
3786
|
+
*
|
|
3787
|
+
* @param grid - Spatial hash grid with entities inserted
|
|
3788
|
+
* @param viewport - Viewport to check visibility against
|
|
3789
|
+
* @returns Set of entity IDs visible in the viewport
|
|
3790
|
+
*
|
|
3791
|
+
* @example
|
|
3792
|
+
* ```typescript
|
|
3793
|
+
* import { createSpatialHash, queryVisibleEntities } from 'blecsd';
|
|
3794
|
+
*
|
|
3795
|
+
* const grid = createSpatialHash({ cellSize: 8 });
|
|
3796
|
+
* // ... insert entities ...
|
|
3797
|
+
*
|
|
3798
|
+
* const visible = queryVisibleEntities(grid, {
|
|
3799
|
+
* x: 0, y: 0, width: 80, height: 24,
|
|
3800
|
+
* });
|
|
3801
|
+
* ```
|
|
3802
|
+
*/
|
|
3803
|
+
declare function queryVisibleEntities(grid: SpatialHashGrid, viewport: Viewport): ReadonlySet<number>;
|
|
3804
|
+
/**
|
|
3805
|
+
* Performs full visibility culling: queries the spatial hash and returns
|
|
3806
|
+
* a categorized result of visible vs culled entities.
|
|
3807
|
+
*
|
|
3808
|
+
* @param grid - Spatial hash grid
|
|
3809
|
+
* @param viewport - Current viewport
|
|
3810
|
+
* @param totalEntities - Total entity count for stats
|
|
3811
|
+
* @returns Culling result with visible entities and statistics
|
|
3812
|
+
*
|
|
3813
|
+
* @example
|
|
3814
|
+
* ```typescript
|
|
3815
|
+
* const result = performCulling(grid, viewport, 10000);
|
|
3816
|
+
* console.log(`Visible: ${result.visible.length}, Culled: ${result.culled}`);
|
|
3817
|
+
* ```
|
|
3818
|
+
*/
|
|
3819
|
+
declare function performCulling(grid: SpatialHashGrid, viewport: Viewport, totalEntities: number): CullingResult;
|
|
3820
|
+
/**
|
|
3821
|
+
* Creates an incremental spatial hash update system.
|
|
3822
|
+
*
|
|
3823
|
+
* Instead of rebuilding the entire grid each frame, this system only
|
|
3824
|
+
* updates entities that have moved. Much faster for scenes where most
|
|
3825
|
+
* entities are static.
|
|
3826
|
+
*
|
|
3827
|
+
* @param grid - Spatial hash grid to update
|
|
3828
|
+
* @param cache - Position cache for change detection
|
|
3829
|
+
* @returns System function
|
|
3830
|
+
*
|
|
3831
|
+
* @example
|
|
3832
|
+
* ```typescript
|
|
3833
|
+
* import { createSpatialHash, createPositionCache, createIncrementalSpatialSystem } from 'blecsd';
|
|
3834
|
+
*
|
|
3835
|
+
* const grid = createSpatialHash({ cellSize: 4 });
|
|
3836
|
+
* const cache = createPositionCache();
|
|
3837
|
+
* const system = createIncrementalSpatialSystem(grid, cache);
|
|
3838
|
+
*
|
|
3839
|
+
* // Register in scheduler
|
|
3840
|
+
* scheduler.registerSystem(LoopPhase.EARLY_UPDATE, system);
|
|
3841
|
+
* ```
|
|
3842
|
+
*/
|
|
3843
|
+
declare function createIncrementalSpatialSystem(grid: SpatialHashGrid, cache: PositionCache): System;
|
|
3844
|
+
/**
|
|
3845
|
+
* Creates a visibility culling system that marks entities as visible/not visible.
|
|
3846
|
+
*
|
|
3847
|
+
* @param grid - Spatial hash grid
|
|
3848
|
+
* @param getViewport - Function to get the current viewport
|
|
3849
|
+
* @returns System function
|
|
3850
|
+
*
|
|
3851
|
+
* @example
|
|
3852
|
+
* ```typescript
|
|
3853
|
+
* const cullSystem = createVisibilityCullingSystem(grid, () => ({
|
|
3854
|
+
* x: scrollX, y: scrollY,
|
|
3855
|
+
* width: terminalCols, height: terminalRows,
|
|
3856
|
+
* }));
|
|
3857
|
+
* ```
|
|
3858
|
+
*/
|
|
3859
|
+
declare function createVisibilityCullingSystem(grid: SpatialHashGrid, getViewport: () => Viewport): System;
|
|
3860
|
+
|
|
3861
|
+
/**
|
|
3862
|
+
* Concurrent rendering with worker thread pool.
|
|
3863
|
+
*
|
|
3864
|
+
* Provides a lightweight worker pool abstraction for offloading
|
|
3865
|
+
* heavy text processing (syntax highlighting, search, diffing)
|
|
3866
|
+
* to background threads. Gracefully degrades on single-core systems
|
|
3867
|
+
* or environments without worker support.
|
|
3868
|
+
*
|
|
3869
|
+
* @module systems/workerPool
|
|
3870
|
+
*/
|
|
3871
|
+
/**
|
|
3872
|
+
* Configuration for the worker pool.
|
|
3873
|
+
*/
|
|
3874
|
+
interface WorkerPoolConfig {
|
|
3875
|
+
/** Maximum number of worker threads (default: navigator.hardwareConcurrency - 1 or 2) */
|
|
3876
|
+
readonly maxWorkers: number;
|
|
3877
|
+
/** Task timeout in milliseconds (default: 5000) */
|
|
3878
|
+
readonly taskTimeout: number;
|
|
3879
|
+
/** Whether to enable the pool (false = run everything synchronously) */
|
|
3880
|
+
readonly enabled: boolean;
|
|
3881
|
+
}
|
|
3882
|
+
/**
|
|
3883
|
+
* Priority levels for tasks.
|
|
3884
|
+
*/
|
|
3885
|
+
type TaskPriority = 'high' | 'normal' | 'low';
|
|
3886
|
+
/**
|
|
3887
|
+
* A task to be executed in the pool.
|
|
3888
|
+
*/
|
|
3889
|
+
interface PoolTask<TInput = unknown> {
|
|
3890
|
+
/** Unique task ID */
|
|
3891
|
+
readonly id: string;
|
|
3892
|
+
/** Task type identifier */
|
|
3893
|
+
readonly type: string;
|
|
3894
|
+
/** Input data for the task */
|
|
3895
|
+
readonly input: TInput;
|
|
3896
|
+
/** Task priority */
|
|
3897
|
+
readonly priority: TaskPriority;
|
|
3898
|
+
/** Timestamp when task was queued */
|
|
3899
|
+
readonly queuedAt: number;
|
|
3900
|
+
}
|
|
3901
|
+
/**
|
|
3902
|
+
* Result of a completed pool task.
|
|
3903
|
+
*/
|
|
3904
|
+
interface TaskResult<TOutput = unknown> {
|
|
3905
|
+
/** Task ID */
|
|
3906
|
+
readonly id: string;
|
|
3907
|
+
/** Task type */
|
|
3908
|
+
readonly type: string;
|
|
3909
|
+
/** Output data (undefined if cancelled or failed) */
|
|
3910
|
+
readonly output: TOutput | undefined;
|
|
3911
|
+
/** Whether the task was cancelled */
|
|
3912
|
+
readonly cancelled: boolean;
|
|
3913
|
+
/** Error message if failed */
|
|
3914
|
+
readonly error: string | undefined;
|
|
3915
|
+
/** Execution time in milliseconds */
|
|
3916
|
+
readonly durationMs: number;
|
|
3917
|
+
}
|
|
3918
|
+
/**
|
|
3919
|
+
* Worker pool statistics.
|
|
3920
|
+
*/
|
|
3921
|
+
interface PoolStats {
|
|
3922
|
+
/** Number of active workers */
|
|
3923
|
+
readonly activeWorkers: number;
|
|
3924
|
+
/** Number of idle workers */
|
|
3925
|
+
readonly idleWorkers: number;
|
|
3926
|
+
/** Tasks currently queued */
|
|
3927
|
+
readonly queuedTasks: number;
|
|
3928
|
+
/** Tasks currently running */
|
|
3929
|
+
readonly runningTasks: number;
|
|
3930
|
+
/** Total tasks completed */
|
|
3931
|
+
readonly completedTasks: number;
|
|
3932
|
+
/** Total tasks cancelled */
|
|
3933
|
+
readonly cancelledTasks: number;
|
|
3934
|
+
/** Total tasks failed */
|
|
3935
|
+
readonly failedTasks: number;
|
|
3936
|
+
/** Average task duration in ms */
|
|
3937
|
+
readonly avgDurationMs: number;
|
|
3938
|
+
/** Whether the pool is enabled */
|
|
3939
|
+
readonly enabled: boolean;
|
|
3940
|
+
}
|
|
3941
|
+
/**
|
|
3942
|
+
* A synchronous task handler for fallback execution.
|
|
3943
|
+
*/
|
|
3944
|
+
type SyncHandler<TInput = unknown, TOutput = unknown> = (input: TInput) => TOutput;
|
|
3945
|
+
/**
|
|
3946
|
+
* Worker pool state object.
|
|
3947
|
+
*/
|
|
3948
|
+
interface WorkerPoolState {
|
|
3949
|
+
/** Pool configuration */
|
|
3950
|
+
readonly config: WorkerPoolConfig;
|
|
3951
|
+
/** Current pool statistics */
|
|
3952
|
+
readonly stats: PoolStats;
|
|
3953
|
+
}
|
|
3954
|
+
/**
|
|
3955
|
+
* Creates and initializes the worker pool.
|
|
3956
|
+
*
|
|
3957
|
+
* In this implementation, the pool uses synchronous fallback handlers
|
|
3958
|
+
* running on the main thread with a priority queue. True worker thread
|
|
3959
|
+
* support can be added when node:worker_threads integration is needed.
|
|
3960
|
+
*
|
|
3961
|
+
* @param config - Optional pool configuration
|
|
3962
|
+
* @returns Pool state
|
|
3963
|
+
*
|
|
3964
|
+
* @example
|
|
3965
|
+
* ```typescript
|
|
3966
|
+
* import { createWorkerPool, registerTaskHandler, submitTask } from 'blecsd';
|
|
3967
|
+
*
|
|
3968
|
+
* createWorkerPool({ maxWorkers: 4 });
|
|
3969
|
+
* registerTaskHandler('highlight', (input) => highlightSync(input));
|
|
3970
|
+
* const result = await submitTask('highlight', sourceCode);
|
|
3971
|
+
* ```
|
|
3972
|
+
*/
|
|
3973
|
+
declare function createWorkerPool(config?: Partial<WorkerPoolConfig>): WorkerPoolState;
|
|
3974
|
+
/**
|
|
3975
|
+
* Registers a synchronous handler for a task type.
|
|
3976
|
+
* This handler will be used to process tasks of the given type.
|
|
3977
|
+
*
|
|
3978
|
+
* @param type - Task type identifier
|
|
3979
|
+
* @param handler - Synchronous processing function
|
|
3980
|
+
*
|
|
3981
|
+
* @example
|
|
3982
|
+
* ```typescript
|
|
3983
|
+
* import { registerTaskHandler } from 'blecsd';
|
|
3984
|
+
*
|
|
3985
|
+
* registerTaskHandler('search', (input: { query: string; text: string }) => {
|
|
3986
|
+
* return input.text.indexOf(input.query);
|
|
3987
|
+
* });
|
|
3988
|
+
* ```
|
|
3989
|
+
*/
|
|
3990
|
+
declare function registerTaskHandler<TInput = unknown, TOutput = unknown>(type: string, handler: SyncHandler<TInput, TOutput>): void;
|
|
3991
|
+
/**
|
|
3992
|
+
* Submits a task to the worker pool.
|
|
3993
|
+
* Returns a promise that resolves when the task completes.
|
|
3994
|
+
*
|
|
3995
|
+
* @param type - Task type (must have a registered handler)
|
|
3996
|
+
* @param input - Input data for the task
|
|
3997
|
+
* @param priority - Task priority (default: 'normal')
|
|
3998
|
+
* @returns Promise resolving to the task result
|
|
3999
|
+
*
|
|
4000
|
+
* @example
|
|
4001
|
+
* ```typescript
|
|
4002
|
+
* import { submitTask } from 'blecsd';
|
|
4003
|
+
*
|
|
4004
|
+
* const result = await submitTask('highlight', { code: 'const x = 1;', lang: 'js' });
|
|
4005
|
+
* if (!result.cancelled && !result.error) {
|
|
4006
|
+
* console.log(result.output);
|
|
4007
|
+
* }
|
|
4008
|
+
* ```
|
|
4009
|
+
*/
|
|
4010
|
+
declare function submitTask<TInput = unknown, TOutput = unknown>(type: string, input: TInput, priority?: TaskPriority): Promise<TaskResult<TOutput>>;
|
|
4011
|
+
/**
|
|
4012
|
+
* Cancels a pending task by ID.
|
|
4013
|
+
*
|
|
4014
|
+
* @param taskId - ID of the task to cancel
|
|
4015
|
+
* @returns Whether the task was found and cancelled
|
|
4016
|
+
*/
|
|
4017
|
+
declare function cancelTask(taskId: string): boolean;
|
|
4018
|
+
/**
|
|
4019
|
+
* Cancels all pending tasks of a given type.
|
|
4020
|
+
*
|
|
4021
|
+
* @param type - Task type to cancel
|
|
4022
|
+
* @returns Number of tasks cancelled
|
|
4023
|
+
*/
|
|
4024
|
+
declare function cancelAllOfType(type: string): number;
|
|
4025
|
+
/**
|
|
4026
|
+
* Gets the current worker pool state and statistics.
|
|
4027
|
+
*
|
|
4028
|
+
* @returns Current pool state
|
|
4029
|
+
*/
|
|
4030
|
+
declare function getWorkerPoolState(): WorkerPoolState;
|
|
4031
|
+
/**
|
|
4032
|
+
* Destroys the worker pool and cancels all pending tasks.
|
|
4033
|
+
*/
|
|
4034
|
+
declare function destroyWorkerPool(): void;
|
|
4035
|
+
|
|
4036
|
+
export { type BehaviorSystemConfig, type BudgetAlert, type CellCoord, type CollisionEventData, type CollisionEventMap, type CollisionSystemState, ComputedLayout, type ComputedLayoutData, type CullingResult, DEFAULT_CELL_SIZE, type DirtyRect, type DragConstraints, type DragEndEvent, type DragEventMap, type DragMoveEvent, type DragStartEvent, type DragState, type DragVerifyCallback, type DropEvent, type EntityProvider, type FocusEventData, type FocusEventMap, type FocusEventType, type FrameBudgetConfig, type FrameBudgetManager, type FrameStats, type HitTestResult, type InputEventType, type InputSystemState, type LineRenderConfig, LineRenderConfigSchema, type MoveResult, type MovementApplier, type OutputState, type PanelConstraints, type PanelMoveConfig, type PanelMoveState, type ParticleSystemConfig, type PoolStats, type PoolTask, type PositionCache, type PositionResolver, type QueuedInputEvent, type QueuedKeyEvent, type QueuedMouseEvent, type RenderContext, type ResizeHandle, type ScrollAnimationState, type ScrollEvent, type ScrollPhysicsConfig, type SpatialHashConfig, type SpatialHashGrid, type SpatialHashStats, type SyncHandler, type SystemTiming, type TaskPriority, type TaskResult, type TileMapBuffer, type TileMapCamera, type TileMapRendererConfig, type Viewport, type VirtualizedRenderContext, type WorkerPoolConfig, type WorkerPoolState, ageParticle, animationSystem, applyScrollImpulse, areColliding, beginMove, beginResize, blurAll, burstParticles, cameraSystem, cancelAllOfType, cancelMoveOrResize, cancelTask, captureMouseTo, cleanup, cleanupEntityResources, cleanupVirtualizedRenderSystem, clearAllScrollStates, clearDragConstraints, clearEntityInput, clearEventQueue, clearFocusStack, clearLineRenderConfig, clearOutputBuffer, clearOutputStream, clearPositionCache, clearRenderBuffer, clearScreen, clearSpatialHash, clearTileMapRenderBuffer, clearVirtualizedRenderBuffer, collisionSystem, computeLayoutNow, createAnimationSystem, createBehaviorSystem, createCameraSystem, createCollisionSystem, createDragSystem, createEmptyBuffer, createFocusSystem, createFrameBudgetManager, createIncrementalSpatialSystem, createInputSystem, createLayoutSystem, createMovementSystem, createOutputState, createOutputSystem, createPanelConstraints, createPanelMoveConfig, createPanelMoveState, createParticleSystem, createPositionCache, createRenderSystem, createSmoothScrollSystem, createSpatialHash, createSpatialHashSystem, createStateMachineSystem, createTilemapRenderSystem, createVirtualizedRenderSystem, createVisibilityCullingSystem, createWorkerPool, cursorHome, destroyFrameBudgetManager, destroyWorkerPool, detectCollisions, detectResizeHandle, endMoveOrResize, endUserScroll, enterAlternateScreen, exportFrameBudgetMetrics, focusEntity, focusFirst, focusLast, focusNext, focusOffset, focusPop, focusPrev, focusPush, focusSystem, generateOutput, getActiveCollisions, getActiveTriggers, getCollidingEntities, getCollisionEventBus, getComputedBounds, getComputedLayout, getDragConstraints, getDragVerifyCallback, getEntitiesAtPoint, getEntitiesInCell, getEventQueue, getFocusEventBus, getFocusStackDepth, getFocusableEntities, getFocused, getFrameBudgetStats, getInputEventBus, getInteractiveEntityAt, getLineRenderConfig, getLineStore, getMouseCaptureEntity, getNearbyEntities, getOutputBuffer, getOutputState, getOutputStream, getRenderBuffer, getScrollPosition, getScrollState, getSpatialHashGrid, getSpatialHashStats, getStateAgeStore, getSystemStateAge, getTileMapRenderBuffer, getTileMapRendererConfig, getTriggerZones, getVirtualizedRenderBuffer, getWorkerPoolState, hasAnimationSystem, hasComputedLayout, hasMovementSystem, hideCursor, hitTest, inputState, inputSystem, insertEntity, invalidateAllLayouts, invalidateLayout, isColliding, isInTrigger, isMouseCaptured, isScrolling, keyboardMove, keyboardResize, killParticle, layoutSystem, leaveAlternateScreen, markAllDirty, mergeDirtyRects, moveParticle, movementSystem, onBudgetAlert, outputSystem, peekFocusStack, performCulling, pointInEntity, profiledSystem, queryAnimation, queryArea, queryCameras, queryColliders, queryInputReceivers, queryMovement, queryStateMachine, queryVisibleEntities, queueKeyEvent, queueMouseEvent, rebuildSpatialHash, recordFrameBudgetSystemTime, recordFrameTime, recordPhaseTime, registerAnimationSystem, registerCameraSystem, registerCollisionSystem, registerInputSystem, registerLineStore, registerMovementSystem, registerStateMachineSystem, registerTaskHandler, releaseMouse, removeEntityFromGrid, removeFromCache, removeScrollState, renderAllTileMaps, renderBackground, renderBorder, renderContent, renderRect, renderScrollbar, renderSystem, renderText, renderTileMapToBuffer, resetAttributes, resetCollisionState, resetDragStores, resetFocusEventBus, resetFrameBudget, resetInputState, resetOutputState, resetStateAge, resetTileMapRenderer, restoreFocus, rewindFocus, saveFocus, setDragConstraints, setDragVerifyCallback, setLineRenderConfig, setOutputBuffer, setOutputStream, setRenderBuffer, setScrollImmediate, setSpatialHashGrid, setTileMapRendererConfig, setVirtualizedRenderBuffer, showCursor, smoothScrollTo, spatialHashSystem, spawnParticle, startUserScroll, stateMachineSystem, submitTask, tilemapRenderSystem, unregisterLineStore, updateAnimations, updateCameras, updateEntityIfMoved, updateLineStore, updateMove, updateMovements, updateResize, updateScrollPhysics, updateStateAges, virtualizedRenderSystem, worldToCell, writeRaw };
|