blecsd 0.3.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -147
- package/dist/{border-Jb7TrMob.d.ts → border-Br-Jc027.d.ts} +2 -2
- package/dist/{cell-DwIu2ryP.d.ts → cell-5Ty_3yMs.d.ts} +1 -1
- package/dist/cellRenderer-D0-DJXWl.d.ts +374 -0
- package/dist/chunk-4N7IFBRQ.js +4 -0
- package/dist/{chunk-DNRXW56C.js → chunk-4XCFTNGN.js} +1 -1
- package/dist/chunk-5YWRP2KG.js +3 -0
- package/dist/chunk-6PX5R326.js +1 -0
- package/dist/chunk-73Y45MLV.js +12 -0
- package/dist/chunk-7ZFQO3OQ.js +1 -0
- package/dist/chunk-A3GSH6MV.js +1 -0
- package/dist/chunk-A5B2BGUM.js +1 -0
- package/dist/chunk-AM6IDSXI.js +1 -0
- package/dist/chunk-EHYOVHRL.js +2 -0
- package/dist/chunk-EMZA6G2M.js +4 -0
- package/dist/chunk-EOFT3PNU.js +1 -0
- package/dist/chunk-ETFDYZVJ.js +1 -0
- package/dist/chunk-FUW7OD3H.js +1 -0
- package/dist/chunk-GRMSEMU7.js +1 -0
- package/dist/chunk-I7AUKTXE.js +1 -0
- package/dist/chunk-IANAVH2A.js +1 -0
- package/dist/chunk-JN2OGNK3.js +1 -0
- package/dist/chunk-JVMNMAHX.js +1 -0
- package/dist/chunk-K2QWNDXV.js +1 -0
- package/dist/chunk-KYNS3GBJ.js +2 -0
- package/dist/chunk-LI3ZYXUT.js +1 -0
- package/dist/chunk-LNEISTXM.js +1 -0
- package/dist/chunk-QABNK7IA.js +1 -0
- package/dist/chunk-QS5QXZNJ.js +1 -0
- package/dist/chunk-QTDRFJG2.js +1 -0
- package/dist/chunk-RJULLVTH.js +1 -0
- package/dist/chunk-SVHITP3F.js +2 -0
- package/dist/chunk-UKVY43V3.js +1 -0
- package/dist/chunk-VIT4KE6Q.js +1 -0
- package/dist/chunk-XG5PVDOP.js +1 -0
- package/dist/chunk-XH5GTWCV.js +1 -0
- package/dist/chunk-XYMPBCYW.js +1 -0
- package/dist/chunk-YRSSCEAS.js +1 -0
- package/dist/chunk-ZL46COQF.js +1 -0
- package/dist/cli/init.js +1 -1
- package/dist/{componentStorage-CJTh-TPO.d.ts → componentStorage-CXJvx4Lt.d.ts} +2 -2
- package/dist/components/index.d.ts +7209 -6691
- package/dist/components/index.js +5 -1
- package/dist/core/index.d.ts +2501 -1262
- package/dist/core/index.js +1 -1
- package/dist/debug/index.d.ts +310 -84
- package/dist/debug/index.js +8 -1
- package/dist/{dirtyTracking-C4v8MmM9.d.ts → dirtyTracking-kCS9-NVF.d.ts} +2 -2
- package/dist/{doubleBuffer-CKQFmlPN.d.ts → doubleBuffer-CWASihKh.d.ts} +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/{inputActions-CRsUtTHM.d.ts → factories-vW7bn_He.d.ts} +21 -786
- package/dist/{gameLoop-C-Ez_i54.d.ts → gameLoop-C1AyRWyP.d.ts} +3 -3
- package/dist/index.d.ts +25 -500
- package/dist/index.js +1 -3
- package/dist/input/index.d.ts +1 -1
- package/dist/input/index.js +1 -1
- package/dist/inputStream-COARA4CP.d.ts +1182 -0
- package/dist/interactiveSystem-h92W9W4n.d.ts +1977 -0
- package/dist/{keyParser-BnHbg2iD.d.ts → keyParser-DReXe2j-.d.ts} +41 -41
- package/dist/{events-9ForpTfM.d.ts → mouseParser-CCqSEUVN.d.ts} +177 -2
- package/dist/{packedStore-BgvnEdE7.d.ts → packedStore-480t2X74.d.ts} +1 -1
- package/dist/panelMovement-DGzIQ8Ll.d.ts +1908 -0
- package/dist/{parser-iMHmQuUh.d.ts → parser-Q1YLXYpF.d.ts} +1 -1
- package/dist/positioning-DiUivJXa.d.ts +917 -0
- package/dist/{renderable-CwqGwrEV.d.ts → renderable-IbSJao5y.d.ts} +2 -2
- package/dist/{scheduler-CMcYew9Z.d.ts → scheduler-NbHT3-D2.d.ts} +3 -1
- package/dist/schemas/index.d.ts +6 -6
- package/dist/schemas/index.js +1 -1
- package/dist/systems/index.d.ts +1057 -1807
- package/dist/systems/index.js +1 -1
- package/dist/terminal/index.d.ts +7207 -2709
- package/dist/terminal/index.js +1 -1
- package/dist/terminalBuffer-BbUz27qM.d.ts +691 -0
- package/dist/{terminus-14-bold-HWSPRLJD.js → terminus-14-bold-ZS4IH465.js} +1 -1
- package/dist/{terminus-14-normal-T3SWMH4D.js → terminus-14-normal-HD5N7F5W.js} +1 -1
- package/dist/text/index.d.ts +263 -0
- package/dist/text/index.js +3 -0
- package/dist/textWrap-Ct2J8gO6.d.ts +761 -0
- package/dist/{tilemap-BirMJdbu.d.ts → tilemap-ByvTsepD.d.ts} +5 -5
- package/dist/{types-CPB4CpbH.d.ts → types-B8LmNkzG.d.ts} +1 -1
- package/dist/utils/index.d.ts +827 -780
- package/dist/utils/index.js +32 -1
- package/dist/{virtualScrollback-D9uLFe8l.d.ts → virtualScrollback-CiooIebp.d.ts} +4 -4
- package/dist/virtualViewport-fIlbIGPt.d.ts +657 -0
- package/dist/{virtualizedLineStore-DwPEvPkk.d.ts → virtualizedLineStore-DfyhojPZ.d.ts} +1 -1
- package/dist/widgets/bigText.d.ts +13 -13
- package/dist/widgets/bigText.js +1 -1
- package/dist/widgets/fonts/index.d.ts +1 -1
- package/dist/widgets/fonts/index.js +1 -1
- package/dist/widgets/index.d.ts +2933 -1102
- package/dist/widgets/index.js +24 -1
- package/package.json +9 -22
- package/dist/3d/index.d.ts +0 -5
- package/dist/3d/index.js +0 -1
- package/dist/audio/index.d.ts +0 -177
- package/dist/audio/index.js +0 -1
- package/dist/chunk-2IEMMRUO.js +0 -1
- package/dist/chunk-35LCBY6P.js +0 -1
- package/dist/chunk-3AV52GY5.js +0 -1
- package/dist/chunk-3LHLSY3Y.js +0 -1
- package/dist/chunk-3O4TQHGK.js +0 -4
- package/dist/chunk-3UJWZ5ZN.js +0 -1
- package/dist/chunk-5PELJRUQ.js +0 -1
- package/dist/chunk-6M2J5QUA.js +0 -1
- package/dist/chunk-7IQEUVGF.js +0 -1
- package/dist/chunk-A6M6TFBL.js +0 -1
- package/dist/chunk-CIK4AMUA.js +0 -1
- package/dist/chunk-CUEUJAHK.js +0 -3
- package/dist/chunk-D42Q2KKR.js +0 -1
- package/dist/chunk-DYEXOFUU.js +0 -2
- package/dist/chunk-DYU72XLL.js +0 -1
- package/dist/chunk-E4CJRSND.js +0 -1
- package/dist/chunk-EAY7B5GL.js +0 -1
- package/dist/chunk-FCMTWFSE.js +0 -1
- package/dist/chunk-FGHEFXLK.js +0 -1
- package/dist/chunk-FL56THSI.js +0 -25
- package/dist/chunk-G437VE43.js +0 -1
- package/dist/chunk-G7GIWWLE.js +0 -1
- package/dist/chunk-GGXNWT36.js +0 -8
- package/dist/chunk-HLFORKXS.js +0 -1
- package/dist/chunk-J7MBKEBY.js +0 -1
- package/dist/chunk-K3SX2LY5.js +0 -1
- package/dist/chunk-LDAFEXN5.js +0 -1
- package/dist/chunk-LYSK5S63.js +0 -1
- package/dist/chunk-MKMFUXLB.js +0 -33
- package/dist/chunk-MQWPHPUM.js +0 -1
- package/dist/chunk-MTI376CU.js +0 -5
- package/dist/chunk-MTV2RJZD.js +0 -1
- package/dist/chunk-NZ55KBM6.js +0 -1
- package/dist/chunk-OB66FB4F.js +0 -1
- package/dist/chunk-OMMJ7B5P.js +0 -1
- package/dist/chunk-OR3BZY7C.js +0 -1
- package/dist/chunk-PXXGH3BV.js +0 -1
- package/dist/chunk-R7AICVRN.js +0 -2
- package/dist/chunk-RZ7FGVI6.js +0 -1
- package/dist/chunk-SHUC6JWA.js +0 -1
- package/dist/chunk-TWSWTBYL.js +0 -1
- package/dist/chunk-UMGTXSQB.js +0 -11
- package/dist/chunk-X3Q3T2SS.js +0 -4
- package/dist/chunk-XZJRWFOS.js +0 -1
- package/dist/chunk-ZAHG7Y3X.js +0 -1
- package/dist/game/index.d.ts +0 -486
- package/dist/game/index.js +0 -1
- package/dist/index-DBS5Uefn.d.ts +0 -3156
- package/dist/mouseParser-Cfrbn3AX.d.ts +0 -177
- package/dist/viewport3d-xI33-_wq.d.ts +0 -182
- package/dist/virtualViewport-Bpv6jlKt.d.ts +0 -1856
package/dist/core/index.d.ts
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { W as World, E as Entity, L as LoopPhase, S as System } from '../types-
|
|
2
|
-
export { U as Unsubscribe } from '../types-
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
export {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
export { A as ActionBinding, h as ActionBindingSchema, i as ActionCallback, j as ActionPresets, k as ActionState, l as BoxConfigSchema, m as ButtonConfigSchema, n as CheckboxConfigSchema, o as FormConfigSchema, p as InputActionManager, q as InputBufferStats, r as InputConfigSchema, I as InputEventBufferData, s as InputEventBufferOptions, t as InputLatencyStats, a as InputState, u as InputStateConfig, v as InputStateStats, K as KeyState, w as ListConfigSchema, M as MouseButtonState, x as MouseState, y as ProgressBarConfigSchema, z as RadioButtonConfigSchema, D as RadioSetConfigSchema, G as ScreenConfigSchema, H as SelectConfigSchema, J as SerializedBindings, N as SerializedBindingsSchema, O as SliderConfigSchema, Q as TextConfigSchema, U as TextareaConfigSchema, V as TextboxConfigSchema, W as TimestampedInputEvent, X as TimestampedKeyEvent, Y as TimestampedMouseEvent, Z as beginFrame, aq as clearBuffer, _ as createInputActionManager, $ as createInputEventBuffer, a0 as createInputState, a1 as drainAllEvents, a2 as drainKeys, a3 as drainMouse, a4 as endFrame, a5 as getLatencyStats, a6 as getMovementDirection, a7 as getPendingCount, a8 as getPendingKeyCount, a9 as getPendingMouseCount, ar as getStats, aa as globalInputBuffer, ab as hasPendingEvents, ac as isAllKeysDown, ad as isAnyKeyDown, ae as isAnyKeyPressed, af as isLatencyAcceptable, ag as isProcessingTimeAcceptable, ah as peekEvents, ai as peekKeys, aj as peekMouse, ak as pushKeyEvent, al as pushMouseEvent, am as recordLatency, an as recordLatencyBatch, ao as resetLatencyStats, ap as resetStats } from '../inputActions-CRsUtTHM.js';
|
|
11
|
-
import { c as EventMap, G as GetEntityEventBus, a as EventBus } from '../events-9ForpTfM.js';
|
|
12
|
-
export { E as EntityEventBusStore, b as EventHandler, S as ScreenEventMap, U as UIEventMap, d as createEntityEventBusStore, e as createEventBus } from '../events-9ForpTfM.js';
|
|
1
|
+
import { W as World, E as Entity, L as LoopPhase, S as System } from '../types-B8LmNkzG.js';
|
|
2
|
+
export { U as Unsubscribe } from '../types-B8LmNkzG.js';
|
|
3
|
+
import { C as ComponentStore } from '../componentStorage-CXJvx4Lt.js';
|
|
4
|
+
export { D as DirtyRect, a as DirtyTracker, c as clearDirtyTracking, b as createDirtyTracker, f as forceFullRedraw, g as getDirtyRegions, d as getDirtyTrackingStats, h as hasDirtyRegions, i as isCellDirty, m as markCellDirty, e as markEntityDirty, j as markRegionDirty, r as removeEntityFromTracking } from '../dirtyTracking-kCS9-NVF.js';
|
|
5
|
+
export { C as CleanupCallback, g as ClickableCache, D as DestroyOptions, i as HitTestOptions, H as HitTestResult, P as PositionValue, a as PositionValueSchema, b as addComponent, c as addEntity, j as centerPosition, k as clampPosition, l as clearCleanupCallbacks, m as clearDestroyQueue, n as createClickableCache, d as createWorld, o as destroyAllChildren, p as destroyEntity, e as destroyWorld, q as entityExists, s as flushDestroyQueue, t as getAllClickablesAt, u as getAllEntities, v as getAllHoverablesAt, w as getClickableAt, x as getClickableCount, y as getClickableEntities, z as getDestroyQueueSize, A as getHoverableAt, B as hasClickableAt, h as hasComponent, E as hasHoverableAt, f as hitTest, F as hitTestAll, G as hitTestDetailed, I as invalidateClickableCache, J as isCacheDirty, K as isKeywordPosition, L as isMarkedForDestruction, M as isPercentagePosition, N as parsePosition, O as parsePositionWithNegative, Q as percentOffsetPosition, R as percentPosition, S as query, T as registerCleanupCallback, U as registerComponent, V as removeComponent, r as removeEntity, W as resetDisposalState, X as resetWorld, Y as resolvePosition, Z as resolvePositionClamped, _ as updateClickableCache, $ as withStore } from '../positioning-DiUivJXa.js';
|
|
6
|
+
import { S as StyleData } from '../renderable-IbSJao5y.js';
|
|
7
|
+
export { B as BoxConfig, a as BoxConfigSchema, k as ButtonConfig, l as ButtonConfigSchema, C as CheckboxConfig, m as CheckboxConfigSchema, F as FormConfig, n as FormConfigSchema, I as InputConfig, o as InputConfigSchema, L as ListConfig, p as ListConfigSchema, P as ProgressBarConfig, q as ProgressBarConfigSchema, R as RadioButtonConfig, r as RadioButtonConfigSchema, s as RadioSetConfig, t as RadioSetConfigSchema, S as ScreenConfig, u as ScreenConfigSchema, v as SelectConfig, w as SelectConfigSchema, x as SliderConfig, y as SliderConfigSchema, T as TextConfig, b as TextConfigSchema, z as TextareaConfig, A as TextareaConfigSchema, D as TextboxConfig, E as TextboxConfigSchema, c as createBoxEntity, d as createButtonEntity, e as createCheckboxEntity, G as createFormEntity, f as createInputEntity, g as createListEntity, H as createProgressBarEntity, J as createRadioButtonEntity, K as createRadioSetEntity, h as createScreenEntity, i as createSelectEntity, M as createSliderEntity, j as createTextEntity, N as createTextareaEntity, O as createTextboxEntity } from '../factories-vW7bn_He.js';
|
|
8
|
+
import { E as EventMap, G as GetEntityEventBus, M as MouseEvent, a as MouseButton, b as EventBus } from '../mouseParser-CCqSEUVN.js';
|
|
9
|
+
export { c as EntityEventBusStore, d as EventHandler, S as ScreenEventMap, U as UIEventMap, e as createEntityEventBusStore, f as createEventBus } from '../mouseParser-CCqSEUVN.js';
|
|
13
10
|
import { z } from 'zod';
|
|
14
|
-
export { F as FixedTimestepConfig, a as FixedUpdateHook, G as GameLoop, b as GameLoopHooks, c as GameLoopOptions, I as InterpolateHook,
|
|
15
|
-
import { K as
|
|
11
|
+
export { F as FixedTimestepConfig, a as FixedUpdateHook, G as GameLoop, b as GameLoopHooks, c as GameLoopOptions, I as InterpolateHook, L as LoopHook, d as LoopState, e as LoopStats, f as createGameLoop, i as isLoopPaused, g as isLoopRunning } from '../gameLoop-C1AyRWyP.js';
|
|
12
|
+
import { K as KeyEvent, a as KeyName } from '../keyParser-DReXe2j-.js';
|
|
16
13
|
import { K as KeyEvent$1 } from '../program-BZaKqDKH.js';
|
|
17
|
-
|
|
18
|
-
export {
|
|
19
|
-
|
|
20
|
-
import '
|
|
14
|
+
import { S as Scheduler } from '../scheduler-NbHT3-D2.js';
|
|
15
|
+
export { A as AdaptiveFrameBudgetConfig, a as AdaptiveFrameBudgetStatus, F as FrameTelemetry, P as PhaseTimingData, T as TelemetryConfig, c as createScheduler, g as getDeltaTime } from '../scheduler-NbHT3-D2.js';
|
|
16
|
+
export { P as PackedHandle, a as PackedStore, b as addToStore, c as clearStore, d as createPackedStore, f as forEachInStore, g as getFromStore, e as getStoreCapacity, h as getStoreData, i as getStoreSize, j as isValidHandle, m as mapStore, r as removeFromStore, s as setInStore } from '../packedStore-480t2X74.js';
|
|
17
|
+
import { ComponentRef, QueryTerm } from 'bitecs';
|
|
18
|
+
export { ComponentRef, QueryResult, QueryTerm } from 'bitecs';
|
|
19
|
+
import '../border-Br-Jc027.js';
|
|
21
20
|
import 'node:stream';
|
|
22
21
|
|
|
23
22
|
/**
|
|
@@ -1242,6 +1241,445 @@ declare function isPointInEntity(world: World, eid: Entity, x: number, y: number
|
|
|
1242
1241
|
*/
|
|
1243
1242
|
declare function isPointInInnerBounds(world: World, eid: Entity, x: number, y: number): boolean;
|
|
1244
1243
|
|
|
1244
|
+
/**
|
|
1245
|
+
* Signal primitives for reactive state management.
|
|
1246
|
+
* Provides automatic dependency tracking and efficient recomputation.
|
|
1247
|
+
* @module core/signals
|
|
1248
|
+
*/
|
|
1249
|
+
|
|
1250
|
+
/**
|
|
1251
|
+
* Signal getter function.
|
|
1252
|
+
* Returns the current value of the signal.
|
|
1253
|
+
*/
|
|
1254
|
+
type SignalGetter<T> = () => T;
|
|
1255
|
+
/**
|
|
1256
|
+
* Signal setter function.
|
|
1257
|
+
* Updates the signal value and notifies dependents.
|
|
1258
|
+
*/
|
|
1259
|
+
type SignalSetter<T> = (value: T | ((prev: T) => T)) => void;
|
|
1260
|
+
/**
|
|
1261
|
+
* A signal is a tuple of [getter, setter].
|
|
1262
|
+
*/
|
|
1263
|
+
type Signal<T> = readonly [SignalGetter<T>, SignalSetter<T>];
|
|
1264
|
+
/**
|
|
1265
|
+
* Computed signal getter.
|
|
1266
|
+
* Returns the current computed value.
|
|
1267
|
+
*/
|
|
1268
|
+
type ComputedGetter<T> = SignalGetter<T>;
|
|
1269
|
+
/**
|
|
1270
|
+
* Alias for computed signal getter used by reactive sources.
|
|
1271
|
+
*/
|
|
1272
|
+
type ComputedSignal<T> = SignalGetter<T>;
|
|
1273
|
+
/**
|
|
1274
|
+
* Creates a reactive signal with automatic dependency tracking.
|
|
1275
|
+
*
|
|
1276
|
+
* Returns a tuple of [getter, setter]. The getter returns the current value
|
|
1277
|
+
* and tracks dependencies. The setter updates the value and notifies dependents.
|
|
1278
|
+
*
|
|
1279
|
+
* @param initialValue - Initial value of the signal
|
|
1280
|
+
* @returns Tuple of [getter, setter]
|
|
1281
|
+
*
|
|
1282
|
+
* @example
|
|
1283
|
+
* ```typescript
|
|
1284
|
+
* import { createSignal } from 'blecsd';
|
|
1285
|
+
*
|
|
1286
|
+
* const [count, setCount] = createSignal(0);
|
|
1287
|
+
* console.log(count()); // 0
|
|
1288
|
+
* setCount(1);
|
|
1289
|
+
* console.log(count()); // 1
|
|
1290
|
+
*
|
|
1291
|
+
* // Functional update
|
|
1292
|
+
* setCount(prev => prev + 1);
|
|
1293
|
+
* console.log(count()); // 2
|
|
1294
|
+
* ```
|
|
1295
|
+
*/
|
|
1296
|
+
declare function createSignal<T>(initialValue: T): Signal<T>;
|
|
1297
|
+
/**
|
|
1298
|
+
* Creates a computed signal that automatically tracks dependencies.
|
|
1299
|
+
*
|
|
1300
|
+
* The function is executed once immediately, and any signals read during
|
|
1301
|
+
* execution become dependencies. The computed value is cached and only
|
|
1302
|
+
* recomputed when dependencies change.
|
|
1303
|
+
*
|
|
1304
|
+
* Handles diamond dependencies correctly (A depends on B and C, both depend on D -
|
|
1305
|
+
* when D changes, A recomputes only once).
|
|
1306
|
+
*
|
|
1307
|
+
* @param fn - Function that computes the value
|
|
1308
|
+
* @returns Getter function for the computed value
|
|
1309
|
+
*
|
|
1310
|
+
* @example
|
|
1311
|
+
* ```typescript
|
|
1312
|
+
* import { createSignal, createComputed } from 'blecsd';
|
|
1313
|
+
*
|
|
1314
|
+
* const [count, setCount] = createSignal(0);
|
|
1315
|
+
* const doubled = createComputed(() => count() * 2);
|
|
1316
|
+
*
|
|
1317
|
+
* console.log(doubled()); // 0
|
|
1318
|
+
* setCount(5);
|
|
1319
|
+
* console.log(doubled()); // 10
|
|
1320
|
+
* ```
|
|
1321
|
+
*/
|
|
1322
|
+
declare function createComputed<T>(fn: () => T): ComputedGetter<T>;
|
|
1323
|
+
/**
|
|
1324
|
+
* Batches multiple signal updates together.
|
|
1325
|
+
*
|
|
1326
|
+
* All signal updates within the batch function are deferred, and
|
|
1327
|
+
* computed signals only recompute once after all updates complete.
|
|
1328
|
+
*
|
|
1329
|
+
* @param fn - Function containing batched updates
|
|
1330
|
+
*
|
|
1331
|
+
* @example
|
|
1332
|
+
* ```typescript
|
|
1333
|
+
* import { createSignal, createComputed, createBatch } from 'blecsd';
|
|
1334
|
+
*
|
|
1335
|
+
* const [a, setA] = createSignal(0);
|
|
1336
|
+
* const [b, setB] = createSignal(0);
|
|
1337
|
+
* const sum = createComputed(() => a() + b());
|
|
1338
|
+
*
|
|
1339
|
+
* createBatch(() => {
|
|
1340
|
+
* setA(1);
|
|
1341
|
+
* setB(2);
|
|
1342
|
+
* });
|
|
1343
|
+
* // sum recomputes only once, not twice
|
|
1344
|
+
* console.log(sum()); // 3
|
|
1345
|
+
* ```
|
|
1346
|
+
*/
|
|
1347
|
+
declare function createBatch(fn: () => void): void;
|
|
1348
|
+
/**
|
|
1349
|
+
* Creates an entity-scoped signal that automatically marks the entity dirty.
|
|
1350
|
+
*
|
|
1351
|
+
* When the signal changes, `markDirty(world, eid)` is called automatically,
|
|
1352
|
+
* integrating with the rendering system's dirty tracking.
|
|
1353
|
+
*
|
|
1354
|
+
* @param world - The ECS world
|
|
1355
|
+
* @param eid - The entity ID
|
|
1356
|
+
* @param initialValue - Initial value of the signal
|
|
1357
|
+
* @returns Tuple of [getter, setter]
|
|
1358
|
+
*
|
|
1359
|
+
* @example
|
|
1360
|
+
* ```typescript
|
|
1361
|
+
* import { createEntitySignal } from 'blecsd';
|
|
1362
|
+
*
|
|
1363
|
+
* const [health, setHealth] = createEntitySignal(world, playerEntity, 100);
|
|
1364
|
+
* setHealth(80); // Automatically marks playerEntity as dirty
|
|
1365
|
+
* ```
|
|
1366
|
+
*/
|
|
1367
|
+
declare function createEntitySignal<T>(world: World, eid: Entity, initialValue: T): Signal<T>;
|
|
1368
|
+
/**
|
|
1369
|
+
* Disposes a signal or computed, removing all subscriptions.
|
|
1370
|
+
*
|
|
1371
|
+
* For computed signals, this unsubscribes from all dependencies.
|
|
1372
|
+
* Call this when a signal is no longer needed to prevent memory leaks.
|
|
1373
|
+
*
|
|
1374
|
+
* Note: This takes a getter function, not the full signal tuple.
|
|
1375
|
+
*
|
|
1376
|
+
* @param getter - Signal or computed getter function
|
|
1377
|
+
*
|
|
1378
|
+
* @example
|
|
1379
|
+
* ```typescript
|
|
1380
|
+
* import { createSignal, createComputed, disposeSignal } from 'blecsd';
|
|
1381
|
+
*
|
|
1382
|
+
* const [count] = createSignal(0);
|
|
1383
|
+
* const doubled = createComputed(() => count() * 2);
|
|
1384
|
+
*
|
|
1385
|
+
* // When done with the computed
|
|
1386
|
+
* disposeSignal(doubled);
|
|
1387
|
+
* ```
|
|
1388
|
+
*/
|
|
1389
|
+
declare function disposeSignal<T>(getter: SignalGetter<T>): void;
|
|
1390
|
+
/**
|
|
1391
|
+
* Runs a function while tracking signal dependencies.
|
|
1392
|
+
* When any tracked signal changes, the callback is invoked.
|
|
1393
|
+
*
|
|
1394
|
+
* Used internally by the effect system.
|
|
1395
|
+
*
|
|
1396
|
+
* @param fn - Function to run while tracking reads
|
|
1397
|
+
* @param onDependencyChange - Called when any tracked signal changes
|
|
1398
|
+
* @returns Cleanup function that stops tracking
|
|
1399
|
+
* @internal
|
|
1400
|
+
*/
|
|
1401
|
+
declare function trackDependencies(fn: () => void, onDependencyChange: () => void): () => void;
|
|
1402
|
+
|
|
1403
|
+
/**
|
|
1404
|
+
* Declarative widget composition API.
|
|
1405
|
+
*
|
|
1406
|
+
* Instead of imperative entity creation and component attachment,
|
|
1407
|
+
* this module lets users describe UI structure as functional composition.
|
|
1408
|
+
* Reactive signal bindings are set up automatically.
|
|
1409
|
+
*
|
|
1410
|
+
* @module core/declarative
|
|
1411
|
+
*
|
|
1412
|
+
* @example
|
|
1413
|
+
* ```typescript
|
|
1414
|
+
* import { createSignal, el, mount, vbox } from 'blecsd';
|
|
1415
|
+
*
|
|
1416
|
+
* const [title, setTitle] = createSignal('Dashboard');
|
|
1417
|
+
* const [cpu, setCpu] = createSignal(42);
|
|
1418
|
+
*
|
|
1419
|
+
* const tree = mount(world, vbox({}, [
|
|
1420
|
+
* el('text', { content: title }),
|
|
1421
|
+
* el('gauge', { value: cpu, label: 'CPU' }),
|
|
1422
|
+
* ]));
|
|
1423
|
+
*
|
|
1424
|
+
* setTitle('Updated!'); // text widget re-renders automatically
|
|
1425
|
+
* setCpu(87); // gauge widget re-renders automatically
|
|
1426
|
+
*
|
|
1427
|
+
* tree.dispose(); // cleanup all entities and reactive bindings
|
|
1428
|
+
* ```
|
|
1429
|
+
*/
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* Supported widget types for declarative composition.
|
|
1433
|
+
*/
|
|
1434
|
+
type WidgetType = 'box' | 'text' | 'gauge' | 'list' | 'progressbar';
|
|
1435
|
+
/**
|
|
1436
|
+
* A value that may be reactive (a signal getter) or static.
|
|
1437
|
+
*/
|
|
1438
|
+
type ReactiveProp<T> = T | SignalGetter<T>;
|
|
1439
|
+
/**
|
|
1440
|
+
* Configuration for a declarative widget.
|
|
1441
|
+
* Any property can be a static value or a reactive signal getter.
|
|
1442
|
+
*/
|
|
1443
|
+
interface ReactiveConfig {
|
|
1444
|
+
readonly [key: string]: ReactiveProp<unknown>;
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Describes a widget to be created in the UI tree.
|
|
1448
|
+
*/
|
|
1449
|
+
interface WidgetDescriptor {
|
|
1450
|
+
readonly type: WidgetType;
|
|
1451
|
+
readonly config: ReactiveConfig;
|
|
1452
|
+
readonly children: readonly WidgetDescriptor[];
|
|
1453
|
+
readonly ref?: (eid: Entity) => void;
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Result of mounting a descriptor tree into actual entities.
|
|
1457
|
+
*/
|
|
1458
|
+
interface MountedTree {
|
|
1459
|
+
readonly root: Entity;
|
|
1460
|
+
readonly entities: readonly Entity[];
|
|
1461
|
+
readonly dispose: () => void;
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Cleanup handle from a reactive binding.
|
|
1465
|
+
*/
|
|
1466
|
+
interface BindingCleanup {
|
|
1467
|
+
readonly dispose: () => void;
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Factory function type for creating entities from config.
|
|
1471
|
+
*/
|
|
1472
|
+
type WidgetFactory = (world: World, config: Record<string, unknown>) => Entity;
|
|
1473
|
+
/**
|
|
1474
|
+
* Registry of property setters for widget types.
|
|
1475
|
+
* Maps (widgetType, propName) to a setter function.
|
|
1476
|
+
*/
|
|
1477
|
+
type PropSetter = (world: World, eid: Entity, value: unknown) => void;
|
|
1478
|
+
/**
|
|
1479
|
+
* Registers a widget factory for declarative composition.
|
|
1480
|
+
*
|
|
1481
|
+
* @param type - Widget type name
|
|
1482
|
+
* @param factory - Factory function that creates an entity from config
|
|
1483
|
+
*
|
|
1484
|
+
* @example
|
|
1485
|
+
* ```typescript
|
|
1486
|
+
* import { registerWidgetFactory, createBoxEntity } from 'blecsd';
|
|
1487
|
+
*
|
|
1488
|
+
* registerWidgetFactory('box', (world, config) => createBoxEntity(world, config));
|
|
1489
|
+
* ```
|
|
1490
|
+
*/
|
|
1491
|
+
declare function registerWidgetFactory(type: WidgetType, factory: WidgetFactory): void;
|
|
1492
|
+
/**
|
|
1493
|
+
* Registers a property setter for a widget type.
|
|
1494
|
+
* Used to update a specific property on an entity when a reactive value changes.
|
|
1495
|
+
*
|
|
1496
|
+
* @param type - Widget type name
|
|
1497
|
+
* @param prop - Property name
|
|
1498
|
+
* @param setter - Function that applies the property value to an entity
|
|
1499
|
+
*
|
|
1500
|
+
* @example
|
|
1501
|
+
* ```typescript
|
|
1502
|
+
* import { registerPropSetter, setContent } from 'blecsd';
|
|
1503
|
+
*
|
|
1504
|
+
* registerPropSetter('text', 'content', (world, eid, value) => {
|
|
1505
|
+
* setContent(world, eid, value as string);
|
|
1506
|
+
* });
|
|
1507
|
+
* ```
|
|
1508
|
+
*/
|
|
1509
|
+
declare function registerPropSetter(type: WidgetType, prop: string, setter: PropSetter): void;
|
|
1510
|
+
/**
|
|
1511
|
+
* Creates a widget descriptor for declarative composition.
|
|
1512
|
+
*
|
|
1513
|
+
* @param type - Widget type ('box', 'text', 'gauge', etc.)
|
|
1514
|
+
* @param config - Configuration object; values can be static or signal getters
|
|
1515
|
+
* @param children - Optional child descriptors
|
|
1516
|
+
* @returns Widget descriptor
|
|
1517
|
+
*
|
|
1518
|
+
* @example
|
|
1519
|
+
* ```typescript
|
|
1520
|
+
* import { el, createSignal } from 'blecsd';
|
|
1521
|
+
*
|
|
1522
|
+
* const [count, setCount] = createSignal(0);
|
|
1523
|
+
*
|
|
1524
|
+
* const desc = el('text', { content: count });
|
|
1525
|
+
* ```
|
|
1526
|
+
*/
|
|
1527
|
+
declare function el(type: WidgetType, config?: ReactiveConfig, children?: WidgetDescriptor[]): WidgetDescriptor;
|
|
1528
|
+
/**
|
|
1529
|
+
* Creates a widget descriptor with a ref callback.
|
|
1530
|
+
*
|
|
1531
|
+
* @param type - Widget type
|
|
1532
|
+
* @param config - Configuration object
|
|
1533
|
+
* @param ref - Callback receiving the created entity ID
|
|
1534
|
+
* @param children - Optional child descriptors
|
|
1535
|
+
* @returns Widget descriptor
|
|
1536
|
+
*
|
|
1537
|
+
* @example
|
|
1538
|
+
* ```typescript
|
|
1539
|
+
* import { elRef } from 'blecsd';
|
|
1540
|
+
*
|
|
1541
|
+
* let myEntity: Entity;
|
|
1542
|
+
* const desc = elRef('box', { width: 20 }, (eid) => { myEntity = eid; });
|
|
1543
|
+
* ```
|
|
1544
|
+
*/
|
|
1545
|
+
declare function elRef(type: WidgetType, config: ReactiveConfig, ref: (eid: Entity) => void, children?: WidgetDescriptor[]): WidgetDescriptor;
|
|
1546
|
+
/**
|
|
1547
|
+
* Creates a vertical box layout descriptor.
|
|
1548
|
+
*
|
|
1549
|
+
* @param config - Box configuration
|
|
1550
|
+
* @param children - Child widget descriptors
|
|
1551
|
+
* @returns Box descriptor with vertical layout
|
|
1552
|
+
*
|
|
1553
|
+
* @example
|
|
1554
|
+
* ```typescript
|
|
1555
|
+
* import { vbox, el } from 'blecsd';
|
|
1556
|
+
*
|
|
1557
|
+
* const layout = vbox({}, [
|
|
1558
|
+
* el('text', { content: 'Header' }),
|
|
1559
|
+
* el('text', { content: 'Body' }),
|
|
1560
|
+
* ]);
|
|
1561
|
+
* ```
|
|
1562
|
+
*/
|
|
1563
|
+
declare function vbox(config?: ReactiveConfig, children?: WidgetDescriptor[]): WidgetDescriptor;
|
|
1564
|
+
/**
|
|
1565
|
+
* Creates a horizontal box layout descriptor.
|
|
1566
|
+
*
|
|
1567
|
+
* @param config - Box configuration
|
|
1568
|
+
* @param children - Child widget descriptors
|
|
1569
|
+
* @returns Box descriptor with horizontal layout
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```typescript
|
|
1573
|
+
* import { hbox, el } from 'blecsd';
|
|
1574
|
+
*
|
|
1575
|
+
* const layout = hbox({}, [
|
|
1576
|
+
* el('text', { content: 'Left' }),
|
|
1577
|
+
* el('text', { content: 'Right' }),
|
|
1578
|
+
* ]);
|
|
1579
|
+
* ```
|
|
1580
|
+
*/
|
|
1581
|
+
declare function hbox(config?: ReactiveConfig, children?: WidgetDescriptor[]): WidgetDescriptor;
|
|
1582
|
+
/**
|
|
1583
|
+
* Mounts a widget descriptor tree, creating entities and setting up reactive bindings.
|
|
1584
|
+
*
|
|
1585
|
+
* For each descriptor node:
|
|
1586
|
+
* 1. Creates the entity using the registered factory
|
|
1587
|
+
* 2. Sets static properties immediately
|
|
1588
|
+
* 3. Creates reactive effects for signal-backed properties
|
|
1589
|
+
* 4. Recursively mounts children and establishes parent-child relationships
|
|
1590
|
+
*
|
|
1591
|
+
* @param world - The ECS world
|
|
1592
|
+
* @param descriptor - Root widget descriptor
|
|
1593
|
+
* @param parent - Optional parent entity
|
|
1594
|
+
* @returns Mounted tree with root entity, all entities, and dispose function
|
|
1595
|
+
*
|
|
1596
|
+
* @example
|
|
1597
|
+
* ```typescript
|
|
1598
|
+
* import { mount, el, createSignal } from 'blecsd';
|
|
1599
|
+
*
|
|
1600
|
+
* const [status, setStatus] = createSignal('Ready');
|
|
1601
|
+
*
|
|
1602
|
+
* const tree = mount(world, el('text', { content: status }));
|
|
1603
|
+
* setStatus('Running'); // widget updates automatically
|
|
1604
|
+
*
|
|
1605
|
+
* tree.dispose(); // cleanup
|
|
1606
|
+
* ```
|
|
1607
|
+
*/
|
|
1608
|
+
declare function mount(world: World, descriptor: WidgetDescriptor, parent?: Entity): MountedTree;
|
|
1609
|
+
/**
|
|
1610
|
+
* Convenience function to unmount a tree.
|
|
1611
|
+
* Disposes all reactive bindings. Entity cleanup should be done
|
|
1612
|
+
* separately using the entity disposal system.
|
|
1613
|
+
*
|
|
1614
|
+
* @param tree - The mounted tree to unmount
|
|
1615
|
+
*
|
|
1616
|
+
* @example
|
|
1617
|
+
* ```typescript
|
|
1618
|
+
* import { mount, unmount, el } from 'blecsd';
|
|
1619
|
+
*
|
|
1620
|
+
* const tree = mount(world, el('box', {}));
|
|
1621
|
+
* // ... later ...
|
|
1622
|
+
* unmount(tree); // clean up reactive bindings
|
|
1623
|
+
* ```
|
|
1624
|
+
*/
|
|
1625
|
+
declare function unmount(tree: MountedTree): void;
|
|
1626
|
+
/**
|
|
1627
|
+
* Creates a reactive binding between a signal and an entity property.
|
|
1628
|
+
* The setter is called immediately with the current value, and again
|
|
1629
|
+
* whenever the signal changes.
|
|
1630
|
+
*
|
|
1631
|
+
* @param world - The ECS world
|
|
1632
|
+
* @param eid - The entity to bind to
|
|
1633
|
+
* @param signal - Signal getter providing the value
|
|
1634
|
+
* @param setter - Function that applies the value to the entity
|
|
1635
|
+
* @returns Cleanup handle
|
|
1636
|
+
*
|
|
1637
|
+
* @example
|
|
1638
|
+
* ```typescript
|
|
1639
|
+
* import { bind, createSignal, setContent } from 'blecsd';
|
|
1640
|
+
*
|
|
1641
|
+
* const [text, setText] = createSignal('Hello');
|
|
1642
|
+
*
|
|
1643
|
+
* const cleanup = bind(world, myEntity, text, (world, eid, value) => {
|
|
1644
|
+
* setContent(world, eid, value);
|
|
1645
|
+
* });
|
|
1646
|
+
*
|
|
1647
|
+
* setText('World'); // entity content updates automatically
|
|
1648
|
+
* cleanup.dispose(); // stop watching
|
|
1649
|
+
* ```
|
|
1650
|
+
*/
|
|
1651
|
+
declare function bind<T>(world: World, eid: Entity, signal: SignalGetter<T>, setter: (world: World, eid: Entity, value: T) => void): BindingCleanup;
|
|
1652
|
+
/**
|
|
1653
|
+
* Registers the default property setters for common widget properties.
|
|
1654
|
+
* Call this once during application setup to enable reactive bindings
|
|
1655
|
+
* for standard properties like content, width, height.
|
|
1656
|
+
*
|
|
1657
|
+
* @param deps - Dependencies injected to avoid circular imports
|
|
1658
|
+
*
|
|
1659
|
+
* @example
|
|
1660
|
+
* ```typescript
|
|
1661
|
+
* import { registerDefaultPropSetters, setContent } from 'blecsd';
|
|
1662
|
+
*
|
|
1663
|
+
* registerDefaultPropSetters({
|
|
1664
|
+
* setContent: (world, eid, value) => setContent(world, eid, value as string),
|
|
1665
|
+
* setWidth: (world, eid, value) => setDimensions(world, eid, { width: value as number }),
|
|
1666
|
+
* setHeight: (world, eid, value) => setDimensions(world, eid, { height: value as number }),
|
|
1667
|
+
* });
|
|
1668
|
+
* ```
|
|
1669
|
+
*/
|
|
1670
|
+
declare function registerDefaultPropSetters(deps: {
|
|
1671
|
+
readonly setContent: PropSetter;
|
|
1672
|
+
readonly setWidth: PropSetter;
|
|
1673
|
+
readonly setHeight: PropSetter;
|
|
1674
|
+
}): void;
|
|
1675
|
+
/**
|
|
1676
|
+
* Clears all widget factory and prop setter registrations.
|
|
1677
|
+
* Used for testing.
|
|
1678
|
+
*
|
|
1679
|
+
* @internal
|
|
1680
|
+
*/
|
|
1681
|
+
declare function resetDeclarativeRegistrations(): void;
|
|
1682
|
+
|
|
1245
1683
|
/**
|
|
1246
1684
|
* Dirty Rectangle Tracking System
|
|
1247
1685
|
*
|
|
@@ -1548,447 +1986,34 @@ declare function regionIntersectsDirty(tracker: DirtyTrackerData, x: number, y:
|
|
|
1548
1986
|
declare function getDirtyRegionsInViewport(tracker: DirtyTrackerData, viewX: number, viewY: number, viewWidth: number, viewHeight: number): DirtyRect[];
|
|
1549
1987
|
|
|
1550
1988
|
/**
|
|
1551
|
-
*
|
|
1552
|
-
*
|
|
1553
|
-
*
|
|
1554
|
-
* - Deferred destruction (mark for destruction, process at frame end)
|
|
1555
|
-
* - Hierarchy cleanup (remove from parent, destroy children)
|
|
1556
|
-
* - Lifecycle event emission
|
|
1557
|
-
* - Store cleanup
|
|
1558
|
-
* - Entity recycling
|
|
1559
|
-
*
|
|
1560
|
-
* @module core/disposal
|
|
1561
|
-
*
|
|
1562
|
-
* @example
|
|
1563
|
-
* ```typescript
|
|
1564
|
-
* import { destroyEntity, destroyAllChildren, flushDestroyQueue } from 'blecsd';
|
|
1565
|
-
*
|
|
1566
|
-
* // Mark entity for destruction (deferred)
|
|
1567
|
-
* destroyEntity(world, entity);
|
|
1568
|
-
*
|
|
1569
|
-
* // At end of frame, process all pending destructions
|
|
1570
|
-
* flushDestroyQueue(world);
|
|
1571
|
-
*
|
|
1572
|
-
* // Or destroy immediately
|
|
1573
|
-
* destroyEntity(world, entity, { immediate: true });
|
|
1574
|
-
* ```
|
|
1989
|
+
* Focus and hover effects system for dynamic styling.
|
|
1990
|
+
* Manages effect application, removal, and style restoration.
|
|
1991
|
+
* @module core/effects
|
|
1575
1992
|
*/
|
|
1576
1993
|
|
|
1577
1994
|
/**
|
|
1578
|
-
*
|
|
1579
|
-
*/
|
|
1580
|
-
interface DestroyOptions {
|
|
1581
|
-
/**
|
|
1582
|
-
* If true, destroy immediately instead of deferring to end of frame.
|
|
1583
|
-
* Use with caution as this may cause issues during iteration.
|
|
1584
|
-
*/
|
|
1585
|
-
immediate?: boolean;
|
|
1586
|
-
/**
|
|
1587
|
-
* If true, also destroy all children recursively.
|
|
1588
|
-
* Defaults to true.
|
|
1589
|
-
*/
|
|
1590
|
-
destroyChildren?: boolean;
|
|
1591
|
-
/**
|
|
1592
|
-
* If true, emit destroy event before cleanup.
|
|
1593
|
-
* Defaults to true.
|
|
1594
|
-
*/
|
|
1595
|
-
emitEvent?: boolean;
|
|
1596
|
-
}
|
|
1597
|
-
/**
|
|
1598
|
-
* Callback for custom cleanup when an entity is destroyed.
|
|
1995
|
+
* A style value that can be static or computed dynamically.
|
|
1599
1996
|
*/
|
|
1600
|
-
type
|
|
1997
|
+
type DynamicValue<T> = T | ((world: World, entity: Entity) => T);
|
|
1601
1998
|
/**
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
* Use this to register store cleanup functions.
|
|
1605
|
-
*
|
|
1606
|
-
* @param callback - Function to call during entity cleanup
|
|
1607
|
-
* @returns Function to unregister the callback
|
|
1999
|
+
* Effect configuration with support for dynamic values.
|
|
2000
|
+
* Values can be static or functions that compute the value at render time.
|
|
1608
2001
|
*
|
|
1609
2002
|
* @example
|
|
1610
2003
|
* ```typescript
|
|
1611
|
-
* import {
|
|
2004
|
+
* import { EffectConfig } from 'blecsd';
|
|
1612
2005
|
*
|
|
1613
|
-
* //
|
|
1614
|
-
* const
|
|
1615
|
-
*
|
|
1616
|
-
*
|
|
2006
|
+
* // Static effect
|
|
2007
|
+
* const staticEffect: EffectConfig = {
|
|
2008
|
+
* fg: 0xff0000ff,
|
|
2009
|
+
* bold: true,
|
|
2010
|
+
* };
|
|
1617
2011
|
*
|
|
1618
|
-
* //
|
|
1619
|
-
*
|
|
1620
|
-
*
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
/**
|
|
1624
|
-
* Clears all registered cleanup callbacks.
|
|
1625
|
-
* Primarily for testing.
|
|
1626
|
-
*/
|
|
1627
|
-
declare function clearCleanupCallbacks(): void;
|
|
1628
|
-
/**
|
|
1629
|
-
* Marks an entity for destruction.
|
|
1630
|
-
*
|
|
1631
|
-
* By default, destruction is deferred to the end of the frame via
|
|
1632
|
-
* `flushDestroyQueue()`. This prevents issues when destroying entities
|
|
1633
|
-
* during iteration.
|
|
1634
|
-
*
|
|
1635
|
-
* @param world - The ECS world
|
|
1636
|
-
* @param entity - The entity to destroy
|
|
1637
|
-
* @param options - Destruction options
|
|
1638
|
-
*
|
|
1639
|
-
* @example
|
|
1640
|
-
* ```typescript
|
|
1641
|
-
* import { destroyEntity } from 'blecsd';
|
|
1642
|
-
*
|
|
1643
|
-
* // Deferred destruction (recommended)
|
|
1644
|
-
* destroyEntity(world, entity);
|
|
1645
|
-
*
|
|
1646
|
-
* // Immediate destruction
|
|
1647
|
-
* destroyEntity(world, entity, { immediate: true });
|
|
1648
|
-
*
|
|
1649
|
-
* // Don't destroy children
|
|
1650
|
-
* destroyEntity(world, entity, { destroyChildren: false });
|
|
1651
|
-
* ```
|
|
1652
|
-
*/
|
|
1653
|
-
declare function destroyEntity(world: World, entity: Entity, options?: DestroyOptions): void;
|
|
1654
|
-
/**
|
|
1655
|
-
* Destroys all children of an entity without destroying the parent.
|
|
1656
|
-
*
|
|
1657
|
-
* @param world - The ECS world
|
|
1658
|
-
* @param parent - The parent entity
|
|
1659
|
-
* @param options - Destruction options (immediate applies to all children)
|
|
1660
|
-
*
|
|
1661
|
-
* @example
|
|
1662
|
-
* ```typescript
|
|
1663
|
-
* import { destroyAllChildren } from 'blecsd';
|
|
1664
|
-
*
|
|
1665
|
-
* // Clear all children from a container
|
|
1666
|
-
* destroyAllChildren(world, container);
|
|
1667
|
-
* ```
|
|
1668
|
-
*/
|
|
1669
|
-
declare function destroyAllChildren(world: World, parent: Entity, options?: DestroyOptions): void;
|
|
1670
|
-
/**
|
|
1671
|
-
* Checks if an entity is marked for destruction.
|
|
1672
|
-
*
|
|
1673
|
-
* @param entity - The entity to check
|
|
1674
|
-
* @returns true if entity is queued for destruction
|
|
1675
|
-
*/
|
|
1676
|
-
declare function isMarkedForDestruction(entity: Entity): boolean;
|
|
1677
|
-
/**
|
|
1678
|
-
* Processes all entities marked for destruction.
|
|
1679
|
-
*
|
|
1680
|
-
* Should be called at the end of each frame, typically in POST_RENDER phase.
|
|
1681
|
-
*
|
|
1682
|
-
* @param world - The ECS world
|
|
1683
|
-
* @returns Number of entities destroyed
|
|
1684
|
-
*
|
|
1685
|
-
* @example
|
|
1686
|
-
* ```typescript
|
|
1687
|
-
* import { flushDestroyQueue } from 'blecsd';
|
|
1688
|
-
*
|
|
1689
|
-
* // In your game loop's post-render phase:
|
|
1690
|
-
* const destroyed = flushDestroyQueue(world);
|
|
1691
|
-
* ```
|
|
1692
|
-
*/
|
|
1693
|
-
declare function flushDestroyQueue(world: World): number;
|
|
1694
|
-
/**
|
|
1695
|
-
* Destroys all entities in a world.
|
|
1696
|
-
*
|
|
1697
|
-
* This performs immediate destruction of all entities.
|
|
1698
|
-
*
|
|
1699
|
-
* @param world - The ECS world to clear
|
|
1700
|
-
*
|
|
1701
|
-
* @example
|
|
1702
|
-
* ```typescript
|
|
1703
|
-
* import { destroyWorld } from 'blecsd';
|
|
1704
|
-
*
|
|
1705
|
-
* // Clean up everything before resetting
|
|
1706
|
-
* destroyWorld(world);
|
|
1707
|
-
* ```
|
|
1708
|
-
*/
|
|
1709
|
-
declare function destroyWorld(world: World): void;
|
|
1710
|
-
/**
|
|
1711
|
-
* Gets the number of entities currently queued for destruction.
|
|
1712
|
-
*
|
|
1713
|
-
* @param world - Optional world to check (if not provided, returns global count)
|
|
1714
|
-
* @returns Number of entities in destroy queue
|
|
1715
|
-
*/
|
|
1716
|
-
declare function getDestroyQueueSize(world?: World): number;
|
|
1717
|
-
/**
|
|
1718
|
-
* Clears the destruction queue without destroying entities.
|
|
1719
|
-
*
|
|
1720
|
-
* Use with caution - entities will remain but won't be destroyed.
|
|
1721
|
-
*
|
|
1722
|
-
* @param world - The ECS world
|
|
1723
|
-
*/
|
|
1724
|
-
declare function clearDestroyQueue(world: World): void;
|
|
1725
|
-
/**
|
|
1726
|
-
* Resets all disposal state.
|
|
1727
|
-
* Primarily for testing.
|
|
1728
|
-
*/
|
|
1729
|
-
declare function resetDisposalState(): void;
|
|
1730
|
-
|
|
1731
|
-
/**
|
|
1732
|
-
* ECS World creation and management
|
|
1733
|
-
* @module core/world
|
|
1734
|
-
*/
|
|
1735
|
-
|
|
1736
|
-
/**
|
|
1737
|
-
* Creates a new ECS world for the game.
|
|
1738
|
-
*
|
|
1739
|
-
* @returns A new World instance
|
|
1740
|
-
*
|
|
1741
|
-
* @example
|
|
1742
|
-
* ```typescript
|
|
1743
|
-
* import { createWorld } from 'blecsd';
|
|
1744
|
-
*
|
|
1745
|
-
* const world = createWorld();
|
|
1746
|
-
* ```
|
|
1747
|
-
*/
|
|
1748
|
-
declare function createWorld(): World;
|
|
1749
|
-
/**
|
|
1750
|
-
* Resets an existing world, removing all entities and resetting component data.
|
|
1751
|
-
* Useful for level reloading or game restart.
|
|
1752
|
-
*
|
|
1753
|
-
* @param world - The world to reset
|
|
1754
|
-
*
|
|
1755
|
-
* @example
|
|
1756
|
-
* ```typescript
|
|
1757
|
-
* import { createWorld, resetWorld } from 'blecsd';
|
|
1758
|
-
*
|
|
1759
|
-
* const world = createWorld();
|
|
1760
|
-
* // ... game runs ...
|
|
1761
|
-
* resetWorld(world); // Clear everything for new game
|
|
1762
|
-
* ```
|
|
1763
|
-
*/
|
|
1764
|
-
declare function resetWorld(world: World): void;
|
|
1765
|
-
|
|
1766
|
-
/**
|
|
1767
|
-
* Creates a new entity in the world.
|
|
1768
|
-
*
|
|
1769
|
-
* @param world - The ECS world to add the entity to
|
|
1770
|
-
* @returns The newly created entity ID
|
|
1771
|
-
*
|
|
1772
|
-
* @example
|
|
1773
|
-
* ```typescript
|
|
1774
|
-
* import { createWorld, addEntity } from 'blecsd';
|
|
1775
|
-
*
|
|
1776
|
-
* const world = createWorld();
|
|
1777
|
-
* const player = addEntity(world);
|
|
1778
|
-
* const enemy = addEntity(world);
|
|
1779
|
-
* ```
|
|
1780
|
-
*/
|
|
1781
|
-
declare function addEntity(world: World): Entity;
|
|
1782
|
-
/**
|
|
1783
|
-
* Removes an entity and all its components from the world.
|
|
1784
|
-
*
|
|
1785
|
-
* @param world - The ECS world containing the entity
|
|
1786
|
-
* @param eid - The entity ID to remove
|
|
1787
|
-
*
|
|
1788
|
-
* @example
|
|
1789
|
-
* ```typescript
|
|
1790
|
-
* import { createWorld, addEntity, removeEntity } from 'blecsd';
|
|
1791
|
-
*
|
|
1792
|
-
* const world = createWorld();
|
|
1793
|
-
* const entity = addEntity(world);
|
|
1794
|
-
* // ... use entity ...
|
|
1795
|
-
* removeEntity(world, entity); // Clean up when done
|
|
1796
|
-
* ```
|
|
1797
|
-
*/
|
|
1798
|
-
declare function removeEntity(world: World, eid: Entity): void;
|
|
1799
|
-
/**
|
|
1800
|
-
* Checks if an entity exists in the world.
|
|
1801
|
-
*
|
|
1802
|
-
* @param world - The ECS world to check
|
|
1803
|
-
* @param eid - The entity ID to check
|
|
1804
|
-
* @returns True if the entity exists, false otherwise
|
|
1805
|
-
*
|
|
1806
|
-
* @example
|
|
1807
|
-
* ```typescript
|
|
1808
|
-
* import { createWorld, addEntity, removeEntity, entityExists } from 'blecsd';
|
|
1809
|
-
*
|
|
1810
|
-
* const world = createWorld();
|
|
1811
|
-
* const entity = addEntity(world);
|
|
1812
|
-
*
|
|
1813
|
-
* console.log(entityExists(world, entity)); // true
|
|
1814
|
-
* removeEntity(world, entity);
|
|
1815
|
-
* console.log(entityExists(world, entity)); // false
|
|
1816
|
-
* ```
|
|
1817
|
-
*/
|
|
1818
|
-
declare function entityExists(world: World, eid: Entity): boolean;
|
|
1819
|
-
/**
|
|
1820
|
-
* Gets all entity IDs currently in the world.
|
|
1821
|
-
*
|
|
1822
|
-
* @param world - The ECS world to query
|
|
1823
|
-
* @returns Array of all entity IDs in the world
|
|
1824
|
-
*
|
|
1825
|
-
* @example
|
|
1826
|
-
* ```typescript
|
|
1827
|
-
* import { createWorld, addEntity, getAllEntities } from 'blecsd';
|
|
1828
|
-
*
|
|
1829
|
-
* const world = createWorld();
|
|
1830
|
-
* addEntity(world);
|
|
1831
|
-
* addEntity(world);
|
|
1832
|
-
* addEntity(world);
|
|
1833
|
-
*
|
|
1834
|
-
* const entities = getAllEntities(world);
|
|
1835
|
-
* console.log(entities.length); // 3
|
|
1836
|
-
* ```
|
|
1837
|
-
*/
|
|
1838
|
-
declare function getAllEntities(world: World): readonly Entity[];
|
|
1839
|
-
/**
|
|
1840
|
-
* Adds a component to an entity.
|
|
1841
|
-
*
|
|
1842
|
-
* @param world - The ECS world
|
|
1843
|
-
* @param eid - The entity to add the component to
|
|
1844
|
-
* @param component - The component to add
|
|
1845
|
-
*
|
|
1846
|
-
* @example
|
|
1847
|
-
* ```typescript
|
|
1848
|
-
* import { createWorld, addEntity, addComponent, Position } from 'blecsd';
|
|
1849
|
-
*
|
|
1850
|
-
* const world = createWorld();
|
|
1851
|
-
* const entity = addEntity(world);
|
|
1852
|
-
* addComponent(world, entity, Position);
|
|
1853
|
-
* Position.x[entity] = 100;
|
|
1854
|
-
* Position.y[entity] = 50;
|
|
1855
|
-
* ```
|
|
1856
|
-
*/
|
|
1857
|
-
declare function addComponent(world: World, eid: Entity, component: ComponentRef): void;
|
|
1858
|
-
/**
|
|
1859
|
-
* Checks if an entity has a specific component.
|
|
1860
|
-
*
|
|
1861
|
-
* @param world - The ECS world
|
|
1862
|
-
* @param eid - The entity to check
|
|
1863
|
-
* @param component - The component to check for
|
|
1864
|
-
* @returns True if the entity has the component, false otherwise
|
|
1865
|
-
*
|
|
1866
|
-
* @example
|
|
1867
|
-
* ```typescript
|
|
1868
|
-
* import { createWorld, addEntity, addComponent, hasComponent, Position } from 'blecsd';
|
|
1869
|
-
*
|
|
1870
|
-
* const world = createWorld();
|
|
1871
|
-
* const entity = addEntity(world);
|
|
1872
|
-
*
|
|
1873
|
-
* console.log(hasComponent(world, entity, Position)); // false
|
|
1874
|
-
* addComponent(world, entity, Position);
|
|
1875
|
-
* console.log(hasComponent(world, entity, Position)); // true
|
|
1876
|
-
* ```
|
|
1877
|
-
*/
|
|
1878
|
-
declare function hasComponent(world: World, eid: Entity, component: ComponentRef): boolean;
|
|
1879
|
-
/**
|
|
1880
|
-
* Removes a component from an entity.
|
|
1881
|
-
*
|
|
1882
|
-
* @param world - The ECS world
|
|
1883
|
-
* @param eid - The entity to remove the component from
|
|
1884
|
-
* @param component - The component to remove
|
|
1885
|
-
*
|
|
1886
|
-
* @example
|
|
1887
|
-
* ```typescript
|
|
1888
|
-
* import { createWorld, addEntity, addComponent, removeComponent, hasComponent, Position } from 'blecsd';
|
|
1889
|
-
*
|
|
1890
|
-
* const world = createWorld();
|
|
1891
|
-
* const entity = addEntity(world);
|
|
1892
|
-
* addComponent(world, entity, Position);
|
|
1893
|
-
*
|
|
1894
|
-
* console.log(hasComponent(world, entity, Position)); // true
|
|
1895
|
-
* removeComponent(world, entity, Position);
|
|
1896
|
-
* console.log(hasComponent(world, entity, Position)); // false
|
|
1897
|
-
* ```
|
|
1898
|
-
*/
|
|
1899
|
-
declare function removeComponent(world: World, eid: Entity, component: ComponentRef): void;
|
|
1900
|
-
/**
|
|
1901
|
-
* Queries the world for entities that have all specified components.
|
|
1902
|
-
*
|
|
1903
|
-
* @param world - The ECS world to query
|
|
1904
|
-
* @param components - Array of components that entities must have
|
|
1905
|
-
* @returns Array of entity IDs that match the query
|
|
1906
|
-
*
|
|
1907
|
-
* @example
|
|
1908
|
-
* ```typescript
|
|
1909
|
-
* import { createWorld, addEntity, addComponent, query, Position, Velocity } from 'blecsd';
|
|
1910
|
-
*
|
|
1911
|
-
* const world = createWorld();
|
|
1912
|
-
*
|
|
1913
|
-
* // Create entities with different component combinations
|
|
1914
|
-
* const staticEntity = addEntity(world);
|
|
1915
|
-
* addComponent(world, staticEntity, Position);
|
|
1916
|
-
*
|
|
1917
|
-
* const movingEntity = addEntity(world);
|
|
1918
|
-
* addComponent(world, movingEntity, Position);
|
|
1919
|
-
* addComponent(world, movingEntity, Velocity);
|
|
1920
|
-
*
|
|
1921
|
-
* // Query for entities with both Position and Velocity
|
|
1922
|
-
* const movingEntities = query(world, [Position, Velocity]);
|
|
1923
|
-
* console.log(movingEntities.length); // 1 (only movingEntity)
|
|
1924
|
-
* ```
|
|
1925
|
-
*/
|
|
1926
|
-
declare function query(world: World, components: QueryTerm[]): QueryResult;
|
|
1927
|
-
/**
|
|
1928
|
-
* Registers a component with the world. This is typically called automatically
|
|
1929
|
-
* when components are first used, but can be useful for advanced scenarios.
|
|
1930
|
-
*
|
|
1931
|
-
* @param world - The ECS world
|
|
1932
|
-
* @param component - The component to register
|
|
1933
|
-
*
|
|
1934
|
-
* @example
|
|
1935
|
-
* ```typescript
|
|
1936
|
-
* import { createWorld, registerComponent, Position } from 'blecsd';
|
|
1937
|
-
*
|
|
1938
|
-
* const world = createWorld();
|
|
1939
|
-
* registerComponent(world, Position);
|
|
1940
|
-
* ```
|
|
1941
|
-
*/
|
|
1942
|
-
declare const registerComponent: (world: bitecs.World, component: ComponentRef) => bitecs.ComponentData;
|
|
1943
|
-
/**
|
|
1944
|
-
* Creates a component with a custom backing store. Useful for components that
|
|
1945
|
-
* need special memory layouts or interop with external systems.
|
|
1946
|
-
*
|
|
1947
|
-
* @param store - Custom store object with typed arrays
|
|
1948
|
-
* @returns A component that uses the provided store
|
|
1949
|
-
*
|
|
1950
|
-
* @example
|
|
1951
|
-
* ```typescript
|
|
1952
|
-
* import { withStore } from 'blecsd';
|
|
1953
|
-
*
|
|
1954
|
-
* // Create a component backed by custom Float32Arrays
|
|
1955
|
-
* const CustomPosition = withStore({
|
|
1956
|
-
* x: new Float32Array(10000),
|
|
1957
|
-
* y: new Float32Array(10000),
|
|
1958
|
-
* });
|
|
1959
|
-
* ```
|
|
1960
|
-
*/
|
|
1961
|
-
declare const withStore: <T>(createStore: (eid: bitecs.EntityId) => T) => (relation: bitecs.Relation<T>) => bitecs.Relation<T>;
|
|
1962
|
-
|
|
1963
|
-
/**
|
|
1964
|
-
* Focus and hover effects system for dynamic styling.
|
|
1965
|
-
* Manages effect application, removal, and style restoration.
|
|
1966
|
-
* @module core/effects
|
|
1967
|
-
*/
|
|
1968
|
-
|
|
1969
|
-
/**
|
|
1970
|
-
* A style value that can be static or computed dynamically.
|
|
1971
|
-
*/
|
|
1972
|
-
type DynamicValue<T> = T | ((world: World, entity: Entity) => T);
|
|
1973
|
-
/**
|
|
1974
|
-
* Effect configuration with support for dynamic values.
|
|
1975
|
-
* Values can be static or functions that compute the value at render time.
|
|
1976
|
-
*
|
|
1977
|
-
* @example
|
|
1978
|
-
* ```typescript
|
|
1979
|
-
* import { EffectConfig } from 'blecsd';
|
|
1980
|
-
*
|
|
1981
|
-
* // Static effect
|
|
1982
|
-
* const staticEffect: EffectConfig = {
|
|
1983
|
-
* fg: 0xff0000ff,
|
|
1984
|
-
* bold: true,
|
|
1985
|
-
* };
|
|
1986
|
-
*
|
|
1987
|
-
* // Dynamic effect based on entity state
|
|
1988
|
-
* const dynamicEffect: EffectConfig = {
|
|
1989
|
-
* fg: (world, eid) => isActive(world, eid) ? 0x00ff00ff : 0xff0000ff,
|
|
1990
|
-
* bold: (world, eid) => hasHighPriority(world, eid),
|
|
1991
|
-
* };
|
|
2012
|
+
* // Dynamic effect based on entity state
|
|
2013
|
+
* const dynamicEffect: EffectConfig = {
|
|
2014
|
+
* fg: (world, eid) => isActive(world, eid) ? 0x00ff00ff : 0xff0000ff,
|
|
2015
|
+
* bold: (world, eid) => hasHighPriority(world, eid),
|
|
2016
|
+
* };
|
|
1992
2017
|
* ```
|
|
1993
2018
|
*/
|
|
1994
2019
|
interface EffectConfig {
|
|
@@ -2053,21 +2078,21 @@ declare function resolveEffectConfig(world: World, eid: Entity, config: EffectCo
|
|
|
2053
2078
|
* @param eid - The entity ID
|
|
2054
2079
|
* @returns Stored style data or undefined
|
|
2055
2080
|
*/
|
|
2056
|
-
declare function getStoredStyle(eid: Entity): StoredStyle | undefined;
|
|
2081
|
+
declare function getStoredStyle(_world: World, eid: Entity): StoredStyle | undefined;
|
|
2057
2082
|
/**
|
|
2058
2083
|
* Checks if an entity has stored style data.
|
|
2059
2084
|
*
|
|
2060
2085
|
* @param eid - The entity ID
|
|
2061
2086
|
* @returns true if entity has stored style
|
|
2062
2087
|
*/
|
|
2063
|
-
declare function hasStoredStyle(eid: Entity): boolean;
|
|
2088
|
+
declare function hasStoredStyle(_world: World, eid: Entity): boolean;
|
|
2064
2089
|
/**
|
|
2065
2090
|
* Clears stored style for an entity.
|
|
2066
2091
|
* Call this when an entity is destroyed.
|
|
2067
2092
|
*
|
|
2068
2093
|
* @param eid - The entity ID
|
|
2069
2094
|
*/
|
|
2070
|
-
declare function clearStoredStyle(eid: Entity): void;
|
|
2095
|
+
declare function clearStoredStyle(_world: World, eid: Entity): void;
|
|
2071
2096
|
/**
|
|
2072
2097
|
* Clears all stored styles.
|
|
2073
2098
|
* Primarily for testing.
|
|
@@ -2121,7 +2146,7 @@ declare function removeFocusEffect(world: World, eid: Entity): void;
|
|
|
2121
2146
|
* @param eid - The entity ID
|
|
2122
2147
|
* @returns true if focus effect is applied
|
|
2123
2148
|
*/
|
|
2124
|
-
declare function hasFocusEffectApplied(eid: Entity): boolean;
|
|
2149
|
+
declare function hasFocusEffectApplied(_world: World, eid: Entity): boolean;
|
|
2125
2150
|
/**
|
|
2126
2151
|
* Applies hover effect to an entity.
|
|
2127
2152
|
* Uses the entity's hoverEffectFg and hoverEffectBg from the Interactive component.
|
|
@@ -2170,7 +2195,7 @@ declare function removeHoverEffect(world: World, eid: Entity): void;
|
|
|
2170
2195
|
* @param eid - The entity ID
|
|
2171
2196
|
* @returns true if hover effect is applied
|
|
2172
2197
|
*/
|
|
2173
|
-
declare function hasHoverEffectApplied(eid: Entity): boolean;
|
|
2198
|
+
declare function hasHoverEffectApplied(_world: World, eid: Entity): boolean;
|
|
2174
2199
|
/**
|
|
2175
2200
|
* Applies a custom effect configuration to an entity.
|
|
2176
2201
|
* Stores the original style for later restoration.
|
|
@@ -2311,7 +2336,7 @@ declare function setEffects(world: World, eid: Entity, config: EffectsConfig): v
|
|
|
2311
2336
|
* @param eid - The entity ID
|
|
2312
2337
|
* @returns The effects configuration or undefined
|
|
2313
2338
|
*/
|
|
2314
|
-
declare function getEffects(eid: Entity): EffectsConfig | undefined;
|
|
2339
|
+
declare function getEffects(_world: World, eid: Entity): EffectsConfig | undefined;
|
|
2315
2340
|
/**
|
|
2316
2341
|
* Clears the effects configuration for an entity.
|
|
2317
2342
|
*
|
|
@@ -2379,28 +2404,28 @@ declare function removeDisabledEffect(world: World, eid: Entity): void;
|
|
|
2379
2404
|
* @param eid - The entity ID
|
|
2380
2405
|
* @returns true if press effect is applied
|
|
2381
2406
|
*/
|
|
2382
|
-
declare function hasPressEffectApplied(eid: Entity): boolean;
|
|
2407
|
+
declare function hasPressEffectApplied(_world: World, eid: Entity): boolean;
|
|
2383
2408
|
/**
|
|
2384
2409
|
* Checks if disabled effect is currently applied.
|
|
2385
2410
|
*
|
|
2386
2411
|
* @param eid - The entity ID
|
|
2387
2412
|
* @returns true if disabled effect is applied
|
|
2388
2413
|
*/
|
|
2389
|
-
declare function hasDisabledEffectApplied(eid: Entity): boolean;
|
|
2414
|
+
declare function hasDisabledEffectApplied(_world: World, eid: Entity): boolean;
|
|
2390
2415
|
/**
|
|
2391
2416
|
* Checks if any effect is currently applied to an entity.
|
|
2392
2417
|
*
|
|
2393
2418
|
* @param eid - The entity ID
|
|
2394
2419
|
* @returns true if any effect is active
|
|
2395
2420
|
*/
|
|
2396
|
-
declare function hasAnyEffectApplied(eid: Entity): boolean;
|
|
2421
|
+
declare function hasAnyEffectApplied(_world: World, eid: Entity): boolean;
|
|
2397
2422
|
/**
|
|
2398
2423
|
* Gets the current effect state for an entity.
|
|
2399
2424
|
*
|
|
2400
2425
|
* @param eid - The entity ID
|
|
2401
2426
|
* @returns Object describing which effects are applied
|
|
2402
2427
|
*/
|
|
2403
|
-
declare function getEffectState(eid: Entity): {
|
|
2428
|
+
declare function getEffectState(_world: World, eid: Entity): {
|
|
2404
2429
|
focus: boolean;
|
|
2405
2430
|
hover: boolean;
|
|
2406
2431
|
press: boolean;
|
|
@@ -2412,35 +2437,13 @@ declare function getEffectState(eid: Entity): {
|
|
|
2412
2437
|
*
|
|
2413
2438
|
* @param eid - The entity ID
|
|
2414
2439
|
*/
|
|
2415
|
-
declare function clearEffectState(eid: Entity): void;
|
|
2440
|
+
declare function clearEffectState(_world: World, eid: Entity): void;
|
|
2416
2441
|
/**
|
|
2417
2442
|
* Clears all effect configs.
|
|
2418
2443
|
* Primarily for testing.
|
|
2419
2444
|
*/
|
|
2420
2445
|
declare function clearAllEffectConfigs(): void;
|
|
2421
2446
|
|
|
2422
|
-
/**
|
|
2423
|
-
* Entity factory functions for creating common entity types.
|
|
2424
|
-
* These factories combine components and helpers to create fully-configured entities.
|
|
2425
|
-
* @module core/entities/factories
|
|
2426
|
-
*/
|
|
2427
|
-
|
|
2428
|
-
declare function createBoxEntity(world: World, config?: BoxConfig): Entity;
|
|
2429
|
-
declare function createTextEntity(world: World, config?: TextConfig): Entity;
|
|
2430
|
-
declare function createButtonEntity(world: World, config?: ButtonConfig): Entity;
|
|
2431
|
-
declare function createScreenEntity(world: World, config: ScreenConfig): Entity;
|
|
2432
|
-
declare function createInputEntity(world: World, config?: InputConfig): Entity;
|
|
2433
|
-
declare function createListEntity(world: World, config?: ListConfig): Entity;
|
|
2434
|
-
declare function createCheckboxEntity(world: World, config?: CheckboxConfig): Entity;
|
|
2435
|
-
declare function createTextboxEntity(world: World, config?: TextboxConfig): Entity;
|
|
2436
|
-
declare function createTextareaEntity(world: World, config?: TextareaConfig): Entity;
|
|
2437
|
-
declare function createSelectEntity(world: World, config?: SelectConfig): Entity;
|
|
2438
|
-
declare function createSliderEntity(world: World, config?: SliderConfig): Entity;
|
|
2439
|
-
declare function createFormEntity(world: World, config?: FormConfig): Entity;
|
|
2440
|
-
declare function createProgressBarEntity(world: World, config?: ProgressBarConfig): Entity;
|
|
2441
|
-
declare function createRadioSetEntity(world: World, config?: RadioSetConfig): Entity;
|
|
2442
|
-
declare function createRadioButtonEntity(world: World, config?: RadioButtonConfig): Entity;
|
|
2443
|
-
|
|
2444
2447
|
/**
|
|
2445
2448
|
* Entity data storage for arbitrary key-value pairs.
|
|
2446
2449
|
*
|
|
@@ -2482,7 +2485,7 @@ type EntityDataMap = Map<string, DataValue>;
|
|
|
2482
2485
|
* console.log(health); // 100 (default, since not set)
|
|
2483
2486
|
* ```
|
|
2484
2487
|
*/
|
|
2485
|
-
declare function getEntityData<T = DataValue>(eid: Entity, key: string, defaultValue?: T): T;
|
|
2488
|
+
declare function getEntityData<T = DataValue>(_world: World, eid: Entity, key: string, defaultValue?: T): T;
|
|
2486
2489
|
/**
|
|
2487
2490
|
* Sets a value on an entity.
|
|
2488
2491
|
*
|
|
@@ -2506,7 +2509,7 @@ declare function getEntityData<T = DataValue>(eid: Entity, key: string, defaultV
|
|
|
2506
2509
|
* setEntityData(entity, 'onDeath', () => console.log('Game over'));
|
|
2507
2510
|
* ```
|
|
2508
2511
|
*/
|
|
2509
|
-
declare function setEntityData(eid: Entity, key: string, value: DataValue): void;
|
|
2512
|
+
declare function setEntityData(_world: World, eid: Entity, key: string, value: DataValue): void;
|
|
2510
2513
|
/**
|
|
2511
2514
|
* Checks if an entity has data stored for a specific key.
|
|
2512
2515
|
*
|
|
@@ -2524,7 +2527,7 @@ declare function setEntityData(eid: Entity, key: string, value: DataValue): void
|
|
|
2524
2527
|
* }
|
|
2525
2528
|
* ```
|
|
2526
2529
|
*/
|
|
2527
|
-
declare function hasEntityData(eid: Entity, key: string): boolean;
|
|
2530
|
+
declare function hasEntityData(_world: World, eid: Entity, key: string): boolean;
|
|
2528
2531
|
/**
|
|
2529
2532
|
* Deletes a specific key from an entity's data.
|
|
2530
2533
|
*
|
|
@@ -2541,7 +2544,7 @@ declare function hasEntityData(eid: Entity, key: string): boolean;
|
|
|
2541
2544
|
* deleteEntityData(entity, 'temporaryBuff');
|
|
2542
2545
|
* ```
|
|
2543
2546
|
*/
|
|
2544
|
-
declare function deleteEntityData(eid: Entity, key: string): boolean;
|
|
2547
|
+
declare function deleteEntityData(_world: World, eid: Entity, key: string): boolean;
|
|
2545
2548
|
/**
|
|
2546
2549
|
* Gets all keys stored on an entity.
|
|
2547
2550
|
*
|
|
@@ -2559,7 +2562,7 @@ declare function deleteEntityData(eid: Entity, key: string): boolean;
|
|
|
2559
2562
|
* console.log(keys); // ['name', 'score']
|
|
2560
2563
|
* ```
|
|
2561
2564
|
*/
|
|
2562
|
-
declare function getEntityDataKeys(eid: Entity): string[];
|
|
2565
|
+
declare function getEntityDataKeys(_world: World, eid: Entity): string[];
|
|
2563
2566
|
/**
|
|
2564
2567
|
* Gets all data stored on an entity as a plain object.
|
|
2565
2568
|
*
|
|
@@ -2577,7 +2580,7 @@ declare function getEntityDataKeys(eid: Entity): string[];
|
|
|
2577
2580
|
* console.log(allData); // { name: 'Player', score: 100 }
|
|
2578
2581
|
* ```
|
|
2579
2582
|
*/
|
|
2580
|
-
declare function getAllEntityData(eid: Entity): Record<string, DataValue>;
|
|
2583
|
+
declare function getAllEntityData(_world: World, eid: Entity): Record<string, DataValue>;
|
|
2581
2584
|
/**
|
|
2582
2585
|
* Sets multiple values on an entity at once.
|
|
2583
2586
|
*
|
|
@@ -2596,7 +2599,7 @@ declare function getAllEntityData(eid: Entity): Record<string, DataValue>;
|
|
|
2596
2599
|
* });
|
|
2597
2600
|
* ```
|
|
2598
2601
|
*/
|
|
2599
|
-
declare function setEntityDataBulk(eid: Entity, data: Record<string, DataValue>): void;
|
|
2602
|
+
declare function setEntityDataBulk(_world: World, eid: Entity, data: Record<string, DataValue>): void;
|
|
2600
2603
|
/**
|
|
2601
2604
|
* Clears all data stored on an entity.
|
|
2602
2605
|
*
|
|
@@ -2610,7 +2613,7 @@ declare function setEntityDataBulk(eid: Entity, data: Record<string, DataValue>)
|
|
|
2610
2613
|
* clearEntityData(entity);
|
|
2611
2614
|
* ```
|
|
2612
2615
|
*/
|
|
2613
|
-
declare function clearEntityData(eid: Entity): void;
|
|
2616
|
+
declare function clearEntityData(_world: World, eid: Entity): void;
|
|
2614
2617
|
/**
|
|
2615
2618
|
* Clears all entity data from the store.
|
|
2616
2619
|
* Useful for testing or resetting game state.
|
|
@@ -2652,7 +2655,7 @@ declare function getEntityDataCount(): number;
|
|
|
2652
2655
|
* }
|
|
2653
2656
|
* ```
|
|
2654
2657
|
*/
|
|
2655
|
-
declare function hasAnyEntityData(eid: Entity): boolean;
|
|
2658
|
+
declare function hasAnyEntityData(_world: World, eid: Entity): boolean;
|
|
2656
2659
|
/**
|
|
2657
2660
|
* Updates a value on an entity using a transform function.
|
|
2658
2661
|
* If the key doesn't exist, the transform receives undefined.
|
|
@@ -2677,7 +2680,7 @@ declare function hasAnyEntityData(eid: Entity): boolean;
|
|
|
2677
2680
|
* updateEntityData(entity, 'items', (current) => [...(current ?? []), newItem]);
|
|
2678
2681
|
* ```
|
|
2679
2682
|
*/
|
|
2680
|
-
declare function updateEntityData<T = DataValue>(eid: Entity, key: string, transform: (current: T | undefined) => T): void;
|
|
2683
|
+
declare function updateEntityData<T = DataValue>(_world: World, eid: Entity, key: string, transform: (current: T | undefined) => T): void;
|
|
2681
2684
|
|
|
2682
2685
|
/**
|
|
2683
2686
|
* Event bubbling system for hierarchical event propagation.
|
|
@@ -2916,263 +2919,790 @@ declare const EmitDescendantsOptionsSchema: z.ZodObject<{
|
|
|
2916
2919
|
declare function emitDescendants<T extends EventMap, K extends keyof T>(world: World, eid: Entity, eventName: K, eventData: T[K], getEventBus: GetEntityEventBus<T>, options?: EmitDescendantsOptions): EmitDescendantsResult;
|
|
2917
2920
|
|
|
2918
2921
|
/**
|
|
2919
|
-
*
|
|
2920
|
-
*
|
|
2921
|
-
* Provides efficient hit testing for mouse interactions, sorting clickable
|
|
2922
|
-
* elements by z-index so the topmost element receives events first.
|
|
2923
|
-
*
|
|
2924
|
-
* @module core/hitTest
|
|
2925
|
-
*
|
|
2926
|
-
* @example
|
|
2927
|
-
* ```typescript
|
|
2928
|
-
* import {
|
|
2929
|
-
* createClickableCache,
|
|
2930
|
-
* hitTest,
|
|
2931
|
-
* hitTestAll,
|
|
2932
|
-
* invalidateClickableCache,
|
|
2933
|
-
* } from 'blecsd';
|
|
2922
|
+
* Input event buffer for frame-independent input handling.
|
|
2934
2923
|
*
|
|
2935
|
-
*
|
|
2936
|
-
*
|
|
2924
|
+
* Buffers keyboard and mouse events between frames so no input is lost.
|
|
2925
|
+
* Events are collected asynchronously from stdin and drained synchronously
|
|
2926
|
+
* each frame by the game loop.
|
|
2937
2927
|
*
|
|
2938
|
-
*
|
|
2939
|
-
* const topEntity = hitTest(world, mouseX, mouseY, cache);
|
|
2928
|
+
* HARD REQUIREMENT: No input events should ever be lost or delayed.
|
|
2940
2929
|
*
|
|
2941
|
-
*
|
|
2942
|
-
* const allEntities = hitTestAll(world, mouseX, mouseY, cache);
|
|
2943
|
-
*
|
|
2944
|
-
* // Invalidate cache when hierarchy changes
|
|
2945
|
-
* invalidateClickableCache(cache);
|
|
2946
|
-
* ```
|
|
2930
|
+
* @module core/inputEventBuffer
|
|
2947
2931
|
*/
|
|
2948
2932
|
|
|
2949
2933
|
/**
|
|
2950
|
-
*
|
|
2951
|
-
*
|
|
2952
|
-
* Maintains a sorted list of clickable/hoverable entities for efficient
|
|
2953
|
-
* hit testing. The cache is invalidated when the hierarchy changes.
|
|
2934
|
+
* A timestamped keyboard event.
|
|
2954
2935
|
*/
|
|
2955
|
-
interface
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
dirty: boolean;
|
|
2960
|
-
/** Last known count for quick dirty check */
|
|
2961
|
-
lastCount: number;
|
|
2936
|
+
interface TimestampedKeyEvent {
|
|
2937
|
+
readonly type: 'key';
|
|
2938
|
+
readonly event: KeyEvent;
|
|
2939
|
+
readonly timestamp: number;
|
|
2962
2940
|
}
|
|
2963
2941
|
/**
|
|
2964
|
-
*
|
|
2942
|
+
* A timestamped mouse event.
|
|
2965
2943
|
*/
|
|
2966
|
-
interface
|
|
2967
|
-
|
|
2968
|
-
readonly
|
|
2969
|
-
|
|
2970
|
-
readonly zIndex: number;
|
|
2944
|
+
interface TimestampedMouseEvent {
|
|
2945
|
+
readonly type: 'mouse';
|
|
2946
|
+
readonly event: MouseEvent;
|
|
2947
|
+
readonly timestamp: number;
|
|
2971
2948
|
}
|
|
2972
2949
|
/**
|
|
2973
|
-
*
|
|
2974
|
-
*/
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
/**
|
|
2981
|
-
|
|
2982
|
-
/**
|
|
2983
|
-
|
|
2950
|
+
* Union of all timestamped input events.
|
|
2951
|
+
*/
|
|
2952
|
+
type TimestampedInputEvent = TimestampedKeyEvent | TimestampedMouseEvent;
|
|
2953
|
+
/**
|
|
2954
|
+
* Statistics about the input buffer.
|
|
2955
|
+
*/
|
|
2956
|
+
interface InputBufferStats {
|
|
2957
|
+
/** Total key events pushed since creation/reset */
|
|
2958
|
+
readonly totalKeyEvents: number;
|
|
2959
|
+
/** Total mouse events pushed since creation/reset */
|
|
2960
|
+
readonly totalMouseEvents: number;
|
|
2961
|
+
/** Current key events in buffer */
|
|
2962
|
+
readonly pendingKeyEvents: number;
|
|
2963
|
+
/** Current mouse events in buffer */
|
|
2964
|
+
readonly pendingMouseEvents: number;
|
|
2965
|
+
/** Number of events dropped due to overflow */
|
|
2966
|
+
readonly droppedEvents: number;
|
|
2967
|
+
/** Maximum buffer size */
|
|
2968
|
+
readonly maxBufferSize: number;
|
|
2984
2969
|
}
|
|
2985
2970
|
/**
|
|
2986
|
-
*
|
|
2987
|
-
*
|
|
2988
|
-
|
|
2989
|
-
|
|
2971
|
+
* Latency statistics for input processing.
|
|
2972
|
+
* All values in milliseconds.
|
|
2973
|
+
*/
|
|
2974
|
+
interface InputLatencyStats {
|
|
2975
|
+
/** Minimum latency observed */
|
|
2976
|
+
readonly min: number;
|
|
2977
|
+
/** Maximum latency observed */
|
|
2978
|
+
readonly max: number;
|
|
2979
|
+
/** Average latency */
|
|
2980
|
+
readonly avg: number;
|
|
2981
|
+
/** 95th percentile latency */
|
|
2982
|
+
readonly p95: number;
|
|
2983
|
+
/** 99th percentile latency */
|
|
2984
|
+
readonly p99: number;
|
|
2985
|
+
/** Number of samples in the window */
|
|
2986
|
+
readonly sampleCount: number;
|
|
2987
|
+
/** Last frame processing time in ms */
|
|
2988
|
+
readonly lastFrameProcessingTime: number;
|
|
2989
|
+
/** Average frame processing time */
|
|
2990
|
+
readonly avgFrameProcessingTime: number;
|
|
2991
|
+
}
|
|
2992
|
+
/**
|
|
2993
|
+
* Configuration options for the input event buffer.
|
|
2994
|
+
*/
|
|
2995
|
+
interface InputEventBufferOptions {
|
|
2996
|
+
/**
|
|
2997
|
+
* Maximum number of events to buffer before dropping oldest.
|
|
2998
|
+
* Set to 0 for unlimited (not recommended).
|
|
2999
|
+
* @default 1000
|
|
3000
|
+
*/
|
|
3001
|
+
readonly maxBufferSize?: number;
|
|
3002
|
+
/**
|
|
3003
|
+
* Whether to emit a warning when buffer overflows.
|
|
3004
|
+
* @default true
|
|
3005
|
+
*/
|
|
3006
|
+
readonly warnOnOverflow?: boolean;
|
|
3007
|
+
/**
|
|
3008
|
+
* Custom warning handler for overflow events.
|
|
3009
|
+
* @default console.warn
|
|
3010
|
+
*/
|
|
3011
|
+
readonly onOverflow?: (droppedCount: number) => void;
|
|
3012
|
+
/**
|
|
3013
|
+
* Maximum number of latency samples to keep for statistics.
|
|
3014
|
+
* @default 1000
|
|
3015
|
+
*/
|
|
3016
|
+
readonly maxLatencySamples?: number;
|
|
3017
|
+
/**
|
|
3018
|
+
* Maximum number of frame processing time samples to keep.
|
|
3019
|
+
* @default 100
|
|
3020
|
+
*/
|
|
3021
|
+
readonly maxFrameSamples?: number;
|
|
3022
|
+
}
|
|
3023
|
+
/**
|
|
3024
|
+
* Input event buffer data structure.
|
|
3025
|
+
* All state is stored in plain arrays for functional manipulation.
|
|
3026
|
+
*/
|
|
3027
|
+
interface InputEventBufferData {
|
|
3028
|
+
/** Pending key events */
|
|
3029
|
+
keyEvents: TimestampedKeyEvent[];
|
|
3030
|
+
/** Pending mouse events */
|
|
3031
|
+
mouseEvents: TimestampedMouseEvent[];
|
|
3032
|
+
/** Latency samples for statistics */
|
|
3033
|
+
latencySamples: number[];
|
|
3034
|
+
/** Frame processing time samples */
|
|
3035
|
+
frameProcessingTimes: number[];
|
|
3036
|
+
/** Frame start timestamp */
|
|
3037
|
+
frameStartTime: number;
|
|
3038
|
+
/** Total key events pushed since creation/reset */
|
|
3039
|
+
totalKeyEvents: number;
|
|
3040
|
+
/** Total mouse events pushed since creation/reset */
|
|
3041
|
+
totalMouseEvents: number;
|
|
3042
|
+
/** Number of events dropped due to overflow */
|
|
3043
|
+
droppedEvents: number;
|
|
3044
|
+
/** Configuration */
|
|
3045
|
+
readonly config: {
|
|
3046
|
+
readonly maxBufferSize: number;
|
|
3047
|
+
readonly maxLatencySamples: number;
|
|
3048
|
+
readonly maxFrameSamples: number;
|
|
3049
|
+
readonly warnOnOverflow: boolean;
|
|
3050
|
+
readonly onOverflow: (droppedCount: number) => void;
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
/**
|
|
3054
|
+
* Creates a new input event buffer.
|
|
2990
3055
|
*
|
|
2991
|
-
* @
|
|
3056
|
+
* @param options - Buffer configuration options
|
|
3057
|
+
* @returns A new InputEventBufferData
|
|
2992
3058
|
*
|
|
2993
3059
|
* @example
|
|
2994
3060
|
* ```typescript
|
|
2995
|
-
* import {
|
|
3061
|
+
* import { createInputEventBuffer, pushKeyEvent, drainKeys } from 'blecsd';
|
|
2996
3062
|
*
|
|
2997
|
-
* const
|
|
3063
|
+
* const buffer = createInputEventBuffer({ maxBufferSize: 500 });
|
|
3064
|
+
*
|
|
3065
|
+
* // Push events from stdin
|
|
3066
|
+
* pushKeyEvent(buffer, keyEvent);
|
|
3067
|
+
*
|
|
3068
|
+
* // Drain in game loop
|
|
3069
|
+
* const keys = drainKeys(buffer);
|
|
2998
3070
|
* ```
|
|
2999
3071
|
*/
|
|
3000
|
-
declare function
|
|
3072
|
+
declare function createInputEventBuffer(options?: InputEventBufferOptions): InputEventBufferData;
|
|
3001
3073
|
/**
|
|
3002
|
-
*
|
|
3074
|
+
* Pushes a keyboard event to the buffer.
|
|
3003
3075
|
*
|
|
3004
|
-
*
|
|
3005
|
-
* -
|
|
3006
|
-
*
|
|
3007
|
-
* - Interactive state changes (clickable/hoverable toggled)
|
|
3008
|
-
*
|
|
3009
|
-
* @param cache - The clickable cache
|
|
3076
|
+
* @param buffer - The input event buffer
|
|
3077
|
+
* @param event - The keyboard event to buffer
|
|
3078
|
+
* @param timestamp - Optional timestamp (default: now)
|
|
3010
3079
|
*
|
|
3011
3080
|
* @example
|
|
3012
3081
|
* ```typescript
|
|
3013
|
-
*
|
|
3014
|
-
*
|
|
3015
|
-
* // After adding a new clickable entity
|
|
3016
|
-
* invalidateClickableCache(cache);
|
|
3082
|
+
* pushKeyEvent(buffer, { name: 'a', ctrl: false, meta: false, shift: false, sequence: 'a' });
|
|
3017
3083
|
* ```
|
|
3018
3084
|
*/
|
|
3019
|
-
declare function
|
|
3085
|
+
declare function pushKeyEvent(buffer: InputEventBufferData, event: KeyEvent, timestamp?: number): void;
|
|
3020
3086
|
/**
|
|
3021
|
-
*
|
|
3087
|
+
* Pushes a mouse event to the buffer.
|
|
3022
3088
|
*
|
|
3023
|
-
* @param
|
|
3024
|
-
* @
|
|
3089
|
+
* @param buffer - The input event buffer
|
|
3090
|
+
* @param event - The mouse event to buffer
|
|
3091
|
+
* @param timestamp - Optional timestamp (default: now)
|
|
3092
|
+
*
|
|
3093
|
+
* @example
|
|
3094
|
+
* ```typescript
|
|
3095
|
+
* pushMouseEvent(buffer, { x: 10, y: 20, button: 'left', action: 'mousedown', ctrl: false, meta: false, shift: false });
|
|
3096
|
+
* ```
|
|
3025
3097
|
*/
|
|
3026
|
-
declare function
|
|
3098
|
+
declare function pushMouseEvent(buffer: InputEventBufferData, event: MouseEvent, timestamp?: number): void;
|
|
3027
3099
|
/**
|
|
3028
|
-
*
|
|
3100
|
+
* Drains all keyboard events from the buffer.
|
|
3101
|
+
* Returns events in order (oldest first) and clears the buffer.
|
|
3029
3102
|
*
|
|
3030
|
-
*
|
|
3031
|
-
*
|
|
3103
|
+
* @param buffer - The input event buffer
|
|
3104
|
+
* @returns Array of timestamped key events
|
|
3032
3105
|
*
|
|
3033
|
-
* @
|
|
3034
|
-
*
|
|
3106
|
+
* @example
|
|
3107
|
+
* ```typescript
|
|
3108
|
+
* const keys = drainKeys(buffer);
|
|
3109
|
+
* for (const { event, timestamp } of keys) {
|
|
3110
|
+
* console.log(`Key: ${event.name} at ${timestamp}`);
|
|
3111
|
+
* }
|
|
3112
|
+
* ```
|
|
3113
|
+
*/
|
|
3114
|
+
declare function drainKeys(buffer: InputEventBufferData): TimestampedKeyEvent[];
|
|
3115
|
+
/**
|
|
3116
|
+
* Drains all mouse events from the buffer.
|
|
3117
|
+
* Returns events in order (oldest first) and clears the buffer.
|
|
3118
|
+
*
|
|
3119
|
+
* @param buffer - The input event buffer
|
|
3120
|
+
* @returns Array of timestamped mouse events
|
|
3035
3121
|
*
|
|
3036
3122
|
* @example
|
|
3037
3123
|
* ```typescript
|
|
3038
|
-
*
|
|
3124
|
+
* const mouse = drainMouse(buffer);
|
|
3125
|
+
* for (const { event, timestamp } of mouse) {
|
|
3126
|
+
* console.log(`Mouse: ${event.action} at ${event.x},${event.y}`);
|
|
3127
|
+
* }
|
|
3128
|
+
* ```
|
|
3129
|
+
*/
|
|
3130
|
+
declare function drainMouse(buffer: InputEventBufferData): TimestampedMouseEvent[];
|
|
3131
|
+
/**
|
|
3132
|
+
* Drains all events (keys and mouse) from the buffer.
|
|
3133
|
+
* Returns events in chronological order by timestamp.
|
|
3039
3134
|
*
|
|
3040
|
-
*
|
|
3041
|
-
*
|
|
3135
|
+
* @param buffer - The input event buffer
|
|
3136
|
+
* @returns Array of all timestamped events sorted by timestamp
|
|
3137
|
+
*
|
|
3138
|
+
* @example
|
|
3139
|
+
* ```typescript
|
|
3140
|
+
* const events = drainAllEvents(buffer);
|
|
3141
|
+
* for (const event of events) {
|
|
3142
|
+
* if (event.type === 'key') {
|
|
3143
|
+
* handleKey(event.event);
|
|
3144
|
+
* } else {
|
|
3145
|
+
* handleMouse(event.event);
|
|
3146
|
+
* }
|
|
3147
|
+
* }
|
|
3042
3148
|
* ```
|
|
3043
3149
|
*/
|
|
3044
|
-
declare function
|
|
3150
|
+
declare function drainAllEvents(buffer: InputEventBufferData): TimestampedInputEvent[];
|
|
3045
3151
|
/**
|
|
3046
|
-
*
|
|
3152
|
+
* Peeks at all pending events without removing them.
|
|
3047
3153
|
*
|
|
3048
|
-
* @param
|
|
3049
|
-
* @
|
|
3050
|
-
* @returns Array of entities sorted by z-index (highest first)
|
|
3154
|
+
* @param buffer - The input event buffer
|
|
3155
|
+
* @returns Array of all pending events sorted by timestamp
|
|
3051
3156
|
*/
|
|
3052
|
-
declare function
|
|
3157
|
+
declare function peekEvents(buffer: InputEventBufferData): TimestampedInputEvent[];
|
|
3053
3158
|
/**
|
|
3054
|
-
*
|
|
3159
|
+
* Peeks at pending key events without removing them.
|
|
3055
3160
|
*
|
|
3056
|
-
* @param
|
|
3057
|
-
* @
|
|
3058
|
-
* @returns Number of clickable/hoverable entities
|
|
3161
|
+
* @param buffer - The input event buffer
|
|
3162
|
+
* @returns Array of pending key events
|
|
3059
3163
|
*/
|
|
3060
|
-
declare function
|
|
3061
|
-
declare function hitTest(world: World, x: number, y: number, cache?: ClickableCache, options?: HitTestOptions): Entity | null;
|
|
3164
|
+
declare function peekKeys(buffer: InputEventBufferData): readonly TimestampedKeyEvent[];
|
|
3062
3165
|
/**
|
|
3063
|
-
*
|
|
3166
|
+
* Peeks at pending mouse events without removing them.
|
|
3064
3167
|
*
|
|
3065
|
-
*
|
|
3168
|
+
* @param buffer - The input event buffer
|
|
3169
|
+
* @returns Array of pending mouse events
|
|
3170
|
+
*/
|
|
3171
|
+
declare function peekMouse(buffer: InputEventBufferData): readonly TimestampedMouseEvent[];
|
|
3172
|
+
/**
|
|
3173
|
+
* Clears all pending events from the buffer.
|
|
3066
3174
|
*
|
|
3067
|
-
* @param
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
*
|
|
3072
|
-
*
|
|
3175
|
+
* @param buffer - The input event buffer
|
|
3176
|
+
*/
|
|
3177
|
+
declare function clearBuffer(buffer: InputEventBufferData): void;
|
|
3178
|
+
/**
|
|
3179
|
+
* Gets the number of pending key events.
|
|
3180
|
+
*
|
|
3181
|
+
* @param buffer - The input event buffer
|
|
3182
|
+
*/
|
|
3183
|
+
declare function getPendingKeyCount(buffer: InputEventBufferData): number;
|
|
3184
|
+
/**
|
|
3185
|
+
* Gets the number of pending mouse events.
|
|
3186
|
+
*
|
|
3187
|
+
* @param buffer - The input event buffer
|
|
3188
|
+
*/
|
|
3189
|
+
declare function getPendingMouseCount(buffer: InputEventBufferData): number;
|
|
3190
|
+
/**
|
|
3191
|
+
* Gets the total number of pending events.
|
|
3192
|
+
*
|
|
3193
|
+
* @param buffer - The input event buffer
|
|
3194
|
+
*/
|
|
3195
|
+
declare function getPendingCount(buffer: InputEventBufferData): number;
|
|
3196
|
+
/**
|
|
3197
|
+
* Checks if there are any pending events.
|
|
3198
|
+
*
|
|
3199
|
+
* @param buffer - The input event buffer
|
|
3200
|
+
*/
|
|
3201
|
+
declare function hasPendingEvents(buffer: InputEventBufferData): boolean;
|
|
3202
|
+
/**
|
|
3203
|
+
* Gets buffer statistics for debugging.
|
|
3204
|
+
*
|
|
3205
|
+
* @param buffer - The input event buffer
|
|
3206
|
+
* @returns Statistics about the buffer
|
|
3073
3207
|
*
|
|
3074
3208
|
* @example
|
|
3075
3209
|
* ```typescript
|
|
3076
|
-
*
|
|
3210
|
+
* const stats = getStats(buffer);
|
|
3211
|
+
* console.log(`Total events: ${stats.totalKeyEvents + stats.totalMouseEvents}`);
|
|
3212
|
+
* console.log(`Dropped: ${stats.droppedEvents}`);
|
|
3213
|
+
* ```
|
|
3214
|
+
*/
|
|
3215
|
+
declare function getStats(buffer: InputEventBufferData): InputBufferStats;
|
|
3216
|
+
/**
|
|
3217
|
+
* Resets buffer statistics.
|
|
3077
3218
|
*
|
|
3078
|
-
*
|
|
3219
|
+
* @param buffer - The input event buffer
|
|
3220
|
+
*/
|
|
3221
|
+
declare function resetStats(buffer: InputEventBufferData): void;
|
|
3222
|
+
/**
|
|
3223
|
+
* Marks the start of frame processing.
|
|
3224
|
+
* Call this at the beginning of your input processing phase.
|
|
3079
3225
|
*
|
|
3080
|
-
*
|
|
3081
|
-
* const entities = hitTestAll(world, mouseX, mouseY, cache);
|
|
3226
|
+
* @param buffer - The input event buffer
|
|
3082
3227
|
*
|
|
3083
|
-
*
|
|
3084
|
-
*
|
|
3085
|
-
*
|
|
3228
|
+
* @example
|
|
3229
|
+
* ```typescript
|
|
3230
|
+
* beginFrame(buffer);
|
|
3231
|
+
* const keys = drainKeys(buffer);
|
|
3232
|
+
* // process keys...
|
|
3233
|
+
* endFrame(buffer);
|
|
3086
3234
|
* ```
|
|
3087
3235
|
*/
|
|
3088
|
-
declare function
|
|
3236
|
+
declare function beginFrame(buffer: InputEventBufferData): void;
|
|
3089
3237
|
/**
|
|
3090
|
-
*
|
|
3238
|
+
* Marks the end of frame processing and records the processing time.
|
|
3239
|
+
* Call this after all input events have been processed.
|
|
3091
3240
|
*
|
|
3092
|
-
* @param
|
|
3093
|
-
* @
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
*
|
|
3241
|
+
* @param buffer - The input event buffer
|
|
3242
|
+
* @returns The frame processing time in milliseconds
|
|
3243
|
+
*/
|
|
3244
|
+
declare function endFrame(buffer: InputEventBufferData): number;
|
|
3245
|
+
/**
|
|
3246
|
+
* Records latency for a processed event.
|
|
3247
|
+
* Call this when an event has been fully processed to track input latency.
|
|
3248
|
+
*
|
|
3249
|
+
* @param buffer - The input event buffer
|
|
3250
|
+
* @param latencyMs - The latency in milliseconds
|
|
3098
3251
|
*
|
|
3099
3252
|
* @example
|
|
3100
3253
|
* ```typescript
|
|
3101
|
-
*
|
|
3254
|
+
* for (const { event, timestamp } of drainKeys(buffer)) {
|
|
3255
|
+
* handleKey(event);
|
|
3256
|
+
* const latency = performance.now() - timestamp;
|
|
3257
|
+
* recordLatency(buffer, latency);
|
|
3258
|
+
* }
|
|
3259
|
+
* ```
|
|
3260
|
+
*/
|
|
3261
|
+
declare function recordLatency(buffer: InputEventBufferData, latencyMs: number): void;
|
|
3262
|
+
/**
|
|
3263
|
+
* Records latency for multiple events at once.
|
|
3264
|
+
* More efficient than calling recordLatency for each event.
|
|
3265
|
+
*
|
|
3266
|
+
* @param buffer - The input event buffer
|
|
3267
|
+
* @param avgLatencyMs - Average latency for all events
|
|
3268
|
+
* @param eventCount - Number of events processed
|
|
3269
|
+
*/
|
|
3270
|
+
declare function recordLatencyBatch(buffer: InputEventBufferData, avgLatencyMs: number, eventCount: number): void;
|
|
3271
|
+
/**
|
|
3272
|
+
* Gets latency statistics for input processing.
|
|
3273
|
+
* Returns min, max, average, and percentile latencies.
|
|
3102
3274
|
*
|
|
3103
|
-
*
|
|
3275
|
+
* @param buffer - The input event buffer
|
|
3276
|
+
* @returns Latency statistics in milliseconds
|
|
3104
3277
|
*
|
|
3105
|
-
*
|
|
3106
|
-
*
|
|
3107
|
-
*
|
|
3278
|
+
* @example
|
|
3279
|
+
* ```typescript
|
|
3280
|
+
* const stats = getLatencyStats(buffer);
|
|
3281
|
+
* console.log(`Avg latency: ${stats.avg.toFixed(2)}ms`);
|
|
3282
|
+
* console.log(`P95 latency: ${stats.p95.toFixed(2)}ms`);
|
|
3283
|
+
* if (stats.max > 16) {
|
|
3284
|
+
* console.warn('Input latency exceeds frame budget!');
|
|
3108
3285
|
* }
|
|
3109
3286
|
* ```
|
|
3110
3287
|
*/
|
|
3111
|
-
declare function
|
|
3288
|
+
declare function getLatencyStats(buffer: InputEventBufferData): InputLatencyStats;
|
|
3112
3289
|
/**
|
|
3113
|
-
*
|
|
3290
|
+
* Resets latency statistics.
|
|
3114
3291
|
*
|
|
3115
|
-
* @param
|
|
3116
|
-
* @param x - Screen X coordinate
|
|
3117
|
-
* @param y - Screen Y coordinate
|
|
3118
|
-
* @param cache - Optional clickable cache
|
|
3119
|
-
* @returns true if any clickable entity is under the point
|
|
3292
|
+
* @param buffer - The input event buffer
|
|
3120
3293
|
*/
|
|
3121
|
-
declare function
|
|
3294
|
+
declare function resetLatencyStats(buffer: InputEventBufferData): void;
|
|
3122
3295
|
/**
|
|
3123
|
-
* Checks if
|
|
3296
|
+
* Checks if the current latency is within acceptable bounds.
|
|
3297
|
+
* By default, checks if p95 latency is under 16ms (one frame at 60fps).
|
|
3124
3298
|
*
|
|
3125
|
-
* @param
|
|
3126
|
-
* @param
|
|
3127
|
-
* @
|
|
3128
|
-
* @param cache - Optional clickable cache
|
|
3129
|
-
* @returns true if any hoverable entity is under the point
|
|
3299
|
+
* @param buffer - The input event buffer
|
|
3300
|
+
* @param maxLatencyMs - Maximum acceptable p95 latency in milliseconds
|
|
3301
|
+
* @returns True if latency is acceptable
|
|
3130
3302
|
*/
|
|
3131
|
-
declare function
|
|
3303
|
+
declare function isLatencyAcceptable(buffer: InputEventBufferData, maxLatencyMs?: number): boolean;
|
|
3132
3304
|
/**
|
|
3133
|
-
*
|
|
3305
|
+
* Checks if frame processing time is within budget.
|
|
3306
|
+
* By default, checks if average processing time is under 1ms.
|
|
3134
3307
|
*
|
|
3135
|
-
*
|
|
3308
|
+
* @param buffer - The input event buffer
|
|
3309
|
+
* @param maxProcessingTimeMs - Maximum acceptable processing time in milliseconds
|
|
3310
|
+
* @returns True if processing time is acceptable
|
|
3311
|
+
*/
|
|
3312
|
+
declare function isProcessingTimeAcceptable(buffer: InputEventBufferData, maxProcessingTimeMs?: number): boolean;
|
|
3313
|
+
/**
|
|
3314
|
+
* Global shared input buffer for simple use cases.
|
|
3136
3315
|
*
|
|
3137
|
-
*
|
|
3138
|
-
*
|
|
3139
|
-
*
|
|
3140
|
-
* @
|
|
3141
|
-
*
|
|
3316
|
+
* For more complex scenarios (multiple input sources, custom overflow handling),
|
|
3317
|
+
* create your own buffer with createInputEventBuffer().
|
|
3318
|
+
*
|
|
3319
|
+
* @example
|
|
3320
|
+
* ```typescript
|
|
3321
|
+
* import { globalInputBuffer, pushKeyEvent, drainAllEvents } from 'blecsd';
|
|
3322
|
+
*
|
|
3323
|
+
* // Push from stdin handler
|
|
3324
|
+
* pushKeyEvent(globalInputBuffer, event);
|
|
3325
|
+
*
|
|
3326
|
+
* // Drain in game loop
|
|
3327
|
+
* const events = drainAllEvents(globalInputBuffer);
|
|
3328
|
+
* ```
|
|
3142
3329
|
*/
|
|
3143
|
-
declare
|
|
3330
|
+
declare const globalInputBuffer: InputEventBufferData;
|
|
3331
|
+
|
|
3144
3332
|
/**
|
|
3145
|
-
*
|
|
3333
|
+
* Input state tracking for keyboard and mouse.
|
|
3146
3334
|
*
|
|
3147
|
-
*
|
|
3335
|
+
* Provides frame-aware input queries like isKeyPressed (just this frame),
|
|
3336
|
+
* isKeyReleased, key hold time, and repeat handling.
|
|
3148
3337
|
*
|
|
3149
|
-
* @
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
*
|
|
3338
|
+
* @module core/inputState
|
|
3339
|
+
*/
|
|
3340
|
+
|
|
3341
|
+
/**
|
|
3342
|
+
* State of a single key.
|
|
3343
|
+
*/
|
|
3344
|
+
interface KeyState {
|
|
3345
|
+
/** Key is currently pressed down */
|
|
3346
|
+
readonly pressed: boolean;
|
|
3347
|
+
/** Key was pressed this frame (transitioned from up to down) */
|
|
3348
|
+
readonly justPressed: boolean;
|
|
3349
|
+
/** Key was released this frame (transitioned from down to up) */
|
|
3350
|
+
readonly justReleased: boolean;
|
|
3351
|
+
/** Time the key has been held in milliseconds */
|
|
3352
|
+
readonly heldTime: number;
|
|
3353
|
+
/** Number of auto-repeat events received while held */
|
|
3354
|
+
readonly repeatCount: number;
|
|
3355
|
+
/** Last event timestamp */
|
|
3356
|
+
readonly lastEventTime: number;
|
|
3357
|
+
}
|
|
3358
|
+
/**
|
|
3359
|
+
* State of a mouse button.
|
|
3360
|
+
*/
|
|
3361
|
+
interface MouseButtonState {
|
|
3362
|
+
/** Button is currently pressed */
|
|
3363
|
+
readonly pressed: boolean;
|
|
3364
|
+
/** Button was pressed this frame */
|
|
3365
|
+
readonly justPressed: boolean;
|
|
3366
|
+
/** Button was released this frame */
|
|
3367
|
+
readonly justReleased: boolean;
|
|
3368
|
+
/** Time the button has been held in milliseconds */
|
|
3369
|
+
readonly heldTime: number;
|
|
3370
|
+
/** Last event timestamp */
|
|
3371
|
+
readonly lastEventTime: number;
|
|
3372
|
+
}
|
|
3373
|
+
/**
|
|
3374
|
+
* Current mouse position and state.
|
|
3375
|
+
*/
|
|
3376
|
+
interface MouseState {
|
|
3377
|
+
/** Current X position */
|
|
3378
|
+
readonly x: number;
|
|
3379
|
+
/** Current Y position */
|
|
3380
|
+
readonly y: number;
|
|
3381
|
+
/** X movement since last frame */
|
|
3382
|
+
readonly deltaX: number;
|
|
3383
|
+
/** Y movement since last frame */
|
|
3384
|
+
readonly deltaY: number;
|
|
3385
|
+
/** Scroll wheel delta since last frame (positive = up) */
|
|
3386
|
+
readonly wheelDelta: number;
|
|
3387
|
+
/** State of each button */
|
|
3388
|
+
readonly buttons: Readonly<Record<MouseButton, MouseButtonState>>;
|
|
3389
|
+
}
|
|
3390
|
+
/**
|
|
3391
|
+
* Input state statistics.
|
|
3392
|
+
*/
|
|
3393
|
+
interface InputStateStats {
|
|
3394
|
+
/** Number of keys currently held down */
|
|
3395
|
+
readonly keysDown: number;
|
|
3396
|
+
/** Number of keys pressed this frame */
|
|
3397
|
+
readonly keysPressed: number;
|
|
3398
|
+
/** Number of keys released this frame */
|
|
3399
|
+
readonly keysReleased: number;
|
|
3400
|
+
/** Total key events processed this frame */
|
|
3401
|
+
readonly keyEventsThisFrame: number;
|
|
3402
|
+
/** Total mouse events processed this frame */
|
|
3403
|
+
readonly mouseEventsThisFrame: number;
|
|
3404
|
+
/** Current frame number */
|
|
3405
|
+
readonly frameCount: number;
|
|
3406
|
+
}
|
|
3407
|
+
/**
|
|
3408
|
+
* Configuration for input state tracking.
|
|
3154
3409
|
*/
|
|
3155
|
-
|
|
3410
|
+
interface InputStateConfig {
|
|
3411
|
+
/**
|
|
3412
|
+
* Whether to track OS key repeats separately.
|
|
3413
|
+
* When true, repeatCount increments for each repeat event.
|
|
3414
|
+
* When false, repeats are ignored after initial press.
|
|
3415
|
+
* @default true
|
|
3416
|
+
*/
|
|
3417
|
+
readonly trackRepeats?: boolean;
|
|
3418
|
+
/**
|
|
3419
|
+
* Minimum time (ms) between key events to consider them separate presses.
|
|
3420
|
+
* Helps filter out very fast unintentional double-presses.
|
|
3421
|
+
* @default 0 (no debouncing)
|
|
3422
|
+
*/
|
|
3423
|
+
readonly debounceTime?: number;
|
|
3424
|
+
/**
|
|
3425
|
+
* Custom repeat rate in ms. When set, overrides OS key repeat.
|
|
3426
|
+
* InputState will generate synthetic repeat events at this rate.
|
|
3427
|
+
* @default undefined (use OS repeat)
|
|
3428
|
+
*/
|
|
3429
|
+
readonly customRepeatRate?: number;
|
|
3430
|
+
/**
|
|
3431
|
+
* Initial delay before custom repeat starts (ms).
|
|
3432
|
+
* @default 500
|
|
3433
|
+
*/
|
|
3434
|
+
readonly customRepeatDelay?: number;
|
|
3435
|
+
}
|
|
3436
|
+
/**
|
|
3437
|
+
* InputState interface for type-safe access.
|
|
3438
|
+
*
|
|
3439
|
+
* Tracks input state across frames.
|
|
3440
|
+
* Call `update()` at the start of each frame with input events from the buffer.
|
|
3441
|
+
* Then use query methods like `isKeyDown()`, `isKeyPressed()`, etc.
|
|
3442
|
+
*/
|
|
3443
|
+
interface InputState {
|
|
3444
|
+
update(keyEvents: readonly TimestampedKeyEvent[], mouseEvents: readonly TimestampedMouseEvent[], deltaTime: number): void;
|
|
3445
|
+
isKeyDown(key: KeyName | string): boolean;
|
|
3446
|
+
isKeyPressed(key: KeyName | string): boolean;
|
|
3447
|
+
isKeyReleased(key: KeyName | string): boolean;
|
|
3448
|
+
getKeyHeldTime(key: KeyName | string): number;
|
|
3449
|
+
getKeyState(key: KeyName | string): KeyState;
|
|
3450
|
+
getKeyRepeatCount(key: KeyName | string): number;
|
|
3451
|
+
getPressedKeys(): string[];
|
|
3452
|
+
getJustPressedKeys(): string[];
|
|
3453
|
+
getJustReleasedKeys(): string[];
|
|
3454
|
+
isCtrlDown(): boolean;
|
|
3455
|
+
isAltDown(): boolean;
|
|
3456
|
+
isShiftDown(): boolean;
|
|
3457
|
+
hasModifier(): boolean;
|
|
3458
|
+
isMouseButtonDown(button: MouseButton): boolean;
|
|
3459
|
+
isMouseButtonPressed(button: MouseButton): boolean;
|
|
3460
|
+
isMouseButtonReleased(button: MouseButton): boolean;
|
|
3461
|
+
getMouseX(): number;
|
|
3462
|
+
getMouseY(): number;
|
|
3463
|
+
getMousePosition(): {
|
|
3464
|
+
x: number;
|
|
3465
|
+
y: number;
|
|
3466
|
+
};
|
|
3467
|
+
getMouseDelta(): {
|
|
3468
|
+
deltaX: number;
|
|
3469
|
+
deltaY: number;
|
|
3470
|
+
};
|
|
3471
|
+
getWheelDelta(): number;
|
|
3472
|
+
getMouseState(): MouseState;
|
|
3473
|
+
releaseKey(key: KeyName | string): void;
|
|
3474
|
+
releaseAllKeys(): void;
|
|
3475
|
+
releaseAllMouseButtons(): void;
|
|
3476
|
+
releaseAll(): void;
|
|
3477
|
+
getStats(): InputStateStats;
|
|
3478
|
+
getFrameCount(): number;
|
|
3479
|
+
reset(): void;
|
|
3480
|
+
}
|
|
3156
3481
|
/**
|
|
3157
|
-
*
|
|
3482
|
+
* Creates a new InputState tracker.
|
|
3158
3483
|
*
|
|
3159
|
-
* @param
|
|
3160
|
-
* @
|
|
3161
|
-
*
|
|
3162
|
-
* @
|
|
3163
|
-
*
|
|
3484
|
+
* @param config - Configuration options
|
|
3485
|
+
* @returns A new InputState instance
|
|
3486
|
+
*
|
|
3487
|
+
* @example
|
|
3488
|
+
* ```typescript
|
|
3489
|
+
* import { createInputState } from 'blecsd';
|
|
3490
|
+
*
|
|
3491
|
+
* const inputState = createInputState({
|
|
3492
|
+
* trackRepeats: true,
|
|
3493
|
+
* debounceTime: 50, // Ignore inputs within 50ms
|
|
3494
|
+
* });
|
|
3495
|
+
* ```
|
|
3164
3496
|
*/
|
|
3165
|
-
declare function
|
|
3497
|
+
declare function createInputState(config?: InputStateConfig): InputState;
|
|
3166
3498
|
/**
|
|
3167
|
-
*
|
|
3499
|
+
* Checks if any of the specified keys are pressed.
|
|
3168
3500
|
*
|
|
3169
|
-
* @param
|
|
3170
|
-
* @param
|
|
3171
|
-
* @
|
|
3172
|
-
*
|
|
3173
|
-
* @
|
|
3501
|
+
* @param inputState - The input state to check
|
|
3502
|
+
* @param keys - Keys to check
|
|
3503
|
+
* @returns true if any key is currently pressed
|
|
3504
|
+
*
|
|
3505
|
+
* @example
|
|
3506
|
+
* ```typescript
|
|
3507
|
+
* if (isAnyKeyDown(inputState, ['w', 'up'])) {
|
|
3508
|
+
* moveForward();
|
|
3509
|
+
* }
|
|
3510
|
+
* ```
|
|
3511
|
+
*/
|
|
3512
|
+
declare function isAnyKeyDown(inputState: InputState, keys: readonly (KeyName | string)[]): boolean;
|
|
3513
|
+
/**
|
|
3514
|
+
* Checks if all specified keys are pressed.
|
|
3515
|
+
*
|
|
3516
|
+
* @param inputState - The input state to check
|
|
3517
|
+
* @param keys - Keys to check
|
|
3518
|
+
* @returns true if all keys are currently pressed
|
|
3519
|
+
*
|
|
3520
|
+
* @example
|
|
3521
|
+
* ```typescript
|
|
3522
|
+
* if (isAllKeysDown(inputState, ['ctrl', 's'])) {
|
|
3523
|
+
* save();
|
|
3524
|
+
* }
|
|
3525
|
+
* ```
|
|
3526
|
+
*/
|
|
3527
|
+
declare function isAllKeysDown(inputState: InputState, keys: readonly (KeyName | string)[]): boolean;
|
|
3528
|
+
/**
|
|
3529
|
+
* Checks if any of the specified keys were just pressed this frame.
|
|
3530
|
+
*
|
|
3531
|
+
* @param inputState - The input state to check
|
|
3532
|
+
* @param keys - Keys to check
|
|
3533
|
+
* @returns true if any key was just pressed
|
|
3534
|
+
*/
|
|
3535
|
+
declare function isAnyKeyPressed(inputState: InputState, keys: readonly (KeyName | string)[]): boolean;
|
|
3536
|
+
/**
|
|
3537
|
+
* Gets the direction vector from WASD or arrow keys.
|
|
3538
|
+
*
|
|
3539
|
+
* @param inputState - The input state to check
|
|
3540
|
+
* @returns Object with x (-1, 0, or 1) and y (-1, 0, or 1)
|
|
3541
|
+
*
|
|
3542
|
+
* @example
|
|
3543
|
+
* ```typescript
|
|
3544
|
+
* const dir = getMovementDirection(inputState);
|
|
3545
|
+
* player.x += dir.x * speed;
|
|
3546
|
+
* player.y += dir.y * speed;
|
|
3547
|
+
* ```
|
|
3548
|
+
*/
|
|
3549
|
+
declare function getMovementDirection(inputState: InputState): {
|
|
3550
|
+
x: number;
|
|
3551
|
+
y: number;
|
|
3552
|
+
};
|
|
3553
|
+
|
|
3554
|
+
/**
|
|
3555
|
+
* Input action mapping system for game controls.
|
|
3556
|
+
*
|
|
3557
|
+
* Maps physical inputs (keys, mouse buttons) to logical game actions.
|
|
3558
|
+
* Supports multiple bindings per action, runtime rebinding, and save/load.
|
|
3559
|
+
*
|
|
3560
|
+
* @module core/inputActions
|
|
3561
|
+
*/
|
|
3562
|
+
|
|
3563
|
+
/**
|
|
3564
|
+
* Configuration for a single action binding.
|
|
3565
|
+
*/
|
|
3566
|
+
interface ActionBinding {
|
|
3567
|
+
/** Unique action identifier (e.g., 'jump', 'attack', 'move_left') */
|
|
3568
|
+
readonly action: string;
|
|
3569
|
+
/** Keys that activate this action */
|
|
3570
|
+
readonly keys: readonly string[];
|
|
3571
|
+
/** Mouse buttons that activate this action */
|
|
3572
|
+
readonly mouseButtons?: readonly MouseButton[] | undefined;
|
|
3573
|
+
/** Whether action fires continuously while held (default: false) */
|
|
3574
|
+
readonly continuous?: boolean | undefined;
|
|
3575
|
+
/** Deadzone for analog inputs (0-1, default: 0.1) */
|
|
3576
|
+
readonly deadzone?: number | undefined;
|
|
3577
|
+
}
|
|
3578
|
+
/**
|
|
3579
|
+
* Runtime state of an action.
|
|
3580
|
+
*/
|
|
3581
|
+
interface ActionState {
|
|
3582
|
+
/** Action is currently active (input is held) */
|
|
3583
|
+
readonly active: boolean;
|
|
3584
|
+
/** Action was just activated this frame */
|
|
3585
|
+
readonly justActivated: boolean;
|
|
3586
|
+
/** Action was just deactivated this frame */
|
|
3587
|
+
readonly justDeactivated: boolean;
|
|
3588
|
+
/** How long the action has been active (ms) */
|
|
3589
|
+
readonly activeTime: number;
|
|
3590
|
+
/** Analog value (0-1), 1 when digital input is pressed */
|
|
3591
|
+
readonly value: number;
|
|
3592
|
+
}
|
|
3593
|
+
/**
|
|
3594
|
+
* Serialized action bindings for save/load.
|
|
3595
|
+
*/
|
|
3596
|
+
interface SerializedBindings {
|
|
3597
|
+
readonly version: number;
|
|
3598
|
+
readonly bindings: readonly {
|
|
3599
|
+
readonly action: string;
|
|
3600
|
+
readonly keys: readonly string[];
|
|
3601
|
+
readonly mouseButtons?: readonly string[] | undefined;
|
|
3602
|
+
readonly continuous?: boolean | undefined;
|
|
3603
|
+
}[];
|
|
3604
|
+
}
|
|
3605
|
+
/**
|
|
3606
|
+
* Callback for action state changes.
|
|
3607
|
+
*/
|
|
3608
|
+
type ActionCallback = (action: string, state: ActionState, inputState: InputState) => void;
|
|
3609
|
+
/**
|
|
3610
|
+
* Zod schema for action binding validation.
|
|
3611
|
+
*/
|
|
3612
|
+
declare const ActionBindingSchema: z.ZodObject<{
|
|
3613
|
+
action: z.ZodString;
|
|
3614
|
+
keys: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
3615
|
+
mouseButtons: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
3616
|
+
unknown: "unknown";
|
|
3617
|
+
left: "left";
|
|
3618
|
+
right: "right";
|
|
3619
|
+
middle: "middle";
|
|
3620
|
+
wheelUp: "wheelUp";
|
|
3621
|
+
wheelDown: "wheelDown";
|
|
3622
|
+
}>>>;
|
|
3623
|
+
continuous: z.ZodDefault<z.ZodBoolean>;
|
|
3624
|
+
deadzone: z.ZodDefault<z.ZodNumber>;
|
|
3625
|
+
}, z.core.$strip>;
|
|
3626
|
+
/**
|
|
3627
|
+
* Zod schema for serialized bindings.
|
|
3628
|
+
*/
|
|
3629
|
+
declare const SerializedBindingsSchema: z.ZodObject<{
|
|
3630
|
+
version: z.ZodNumber;
|
|
3631
|
+
bindings: z.ZodArray<z.ZodObject<{
|
|
3632
|
+
action: z.ZodString;
|
|
3633
|
+
keys: z.ZodArray<z.ZodString>;
|
|
3634
|
+
mouseButtons: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3635
|
+
continuous: z.ZodOptional<z.ZodBoolean>;
|
|
3636
|
+
}, z.core.$strip>>;
|
|
3637
|
+
}, z.core.$strip>;
|
|
3638
|
+
/**
|
|
3639
|
+
* InputActionManager interface for type-safe access.
|
|
3640
|
+
*/
|
|
3641
|
+
interface InputActionManager {
|
|
3642
|
+
register(binding: ActionBinding): InputActionManager;
|
|
3643
|
+
registerAll(bindings: readonly ActionBinding[]): InputActionManager;
|
|
3644
|
+
unregister(action: string): boolean;
|
|
3645
|
+
hasAction(action: string): boolean;
|
|
3646
|
+
getActions(): string[];
|
|
3647
|
+
getBinding(action: string): ActionBinding | undefined;
|
|
3648
|
+
update(inputState: InputState, deltaTime: number): void;
|
|
3649
|
+
isActive(action: string): boolean;
|
|
3650
|
+
isJustActivated(action: string): boolean;
|
|
3651
|
+
isJustDeactivated(action: string): boolean;
|
|
3652
|
+
getValue(action: string): number;
|
|
3653
|
+
getActiveTime(action: string): number;
|
|
3654
|
+
getState(action: string): ActionState;
|
|
3655
|
+
getActiveActions(): string[];
|
|
3656
|
+
rebindKeys(action: string, keys: readonly string[]): boolean;
|
|
3657
|
+
rebindMouseButtons(action: string, buttons: readonly MouseButton[]): boolean;
|
|
3658
|
+
addKey(action: string, key: string): boolean;
|
|
3659
|
+
removeKey(action: string, key: string): boolean;
|
|
3660
|
+
getKeysForAction(action: string): string[];
|
|
3661
|
+
getMouseButtonsForAction(action: string): MouseButton[];
|
|
3662
|
+
getActionsForKey(key: string): string[];
|
|
3663
|
+
onAction(action: string, callback: ActionCallback): () => void;
|
|
3664
|
+
onAnyAction(callback: ActionCallback): () => void;
|
|
3665
|
+
saveBindings(): SerializedBindings;
|
|
3666
|
+
loadBindings(data: unknown): void;
|
|
3667
|
+
toJSON(pretty?: boolean): string;
|
|
3668
|
+
fromJSON(json: string): void;
|
|
3669
|
+
resetStates(): void;
|
|
3670
|
+
clear(): void;
|
|
3671
|
+
}
|
|
3672
|
+
/**
|
|
3673
|
+
* Creates a new InputActionManager.
|
|
3674
|
+
*
|
|
3675
|
+
* @param initialBindings - Optional initial bindings to register
|
|
3676
|
+
* @returns A new InputActionManager instance
|
|
3677
|
+
*
|
|
3678
|
+
* @example
|
|
3679
|
+
* ```typescript
|
|
3680
|
+
* import { createInputActionManager } from 'blecsd';
|
|
3681
|
+
*
|
|
3682
|
+
* const actions = createInputActionManager([
|
|
3683
|
+
* { action: 'jump', keys: ['space'] },
|
|
3684
|
+
* { action: 'attack', keys: ['j'], mouseButtons: ['left'] },
|
|
3685
|
+
* ]);
|
|
3686
|
+
* ```
|
|
3174
3687
|
*/
|
|
3175
|
-
declare function
|
|
3688
|
+
declare function createInputActionManager(initialBindings?: readonly ActionBinding[]): InputActionManager;
|
|
3689
|
+
/**
|
|
3690
|
+
* Common action presets for quick setup.
|
|
3691
|
+
*/
|
|
3692
|
+
declare const ActionPresets: {
|
|
3693
|
+
/**
|
|
3694
|
+
* Standard platformer controls.
|
|
3695
|
+
*/
|
|
3696
|
+
readonly platformer: readonly ActionBinding[];
|
|
3697
|
+
/**
|
|
3698
|
+
* Standard top-down controls.
|
|
3699
|
+
*/
|
|
3700
|
+
readonly topDown: readonly ActionBinding[];
|
|
3701
|
+
/**
|
|
3702
|
+
* Menu navigation controls.
|
|
3703
|
+
*/
|
|
3704
|
+
readonly menu: readonly ActionBinding[];
|
|
3705
|
+
};
|
|
3176
3706
|
|
|
3177
3707
|
/**
|
|
3178
3708
|
* Configurable key binding system.
|
|
@@ -4262,506 +4792,783 @@ declare function createPhaseManager(): PhaseManager;
|
|
|
4262
4792
|
declare const defaultPhaseManager: PhaseManager;
|
|
4263
4793
|
|
|
4264
4794
|
/**
|
|
4265
|
-
*
|
|
4266
|
-
* Caches computed positions to avoid expensive recalculations.
|
|
4267
|
-
* @module core/positionCache
|
|
4268
|
-
*/
|
|
4269
|
-
|
|
4270
|
-
/**
|
|
4271
|
-
* Last computed position data.
|
|
4272
|
-
* Used to cache resolved positions and skip recalculation when unchanged.
|
|
4795
|
+
* Plugin/Module System
|
|
4273
4796
|
*
|
|
4274
|
-
*
|
|
4275
|
-
*
|
|
4276
|
-
*
|
|
4277
|
-
*
|
|
4278
|
-
*
|
|
4279
|
-
*
|
|
4797
|
+
* Provides a plugin interface for extending blECSd with reusable modules
|
|
4798
|
+
* that bundle components, systems, and lifecycle hooks. Plugins declare
|
|
4799
|
+
* which scheduler phase their systems belong to, enabling modular
|
|
4800
|
+
* composition of functionality.
|
|
4801
|
+
*
|
|
4802
|
+
* @module core/plugins
|
|
4280
4803
|
*
|
|
4281
4804
|
* @example
|
|
4282
4805
|
* ```typescript
|
|
4283
|
-
* import {
|
|
4284
|
-
*
|
|
4285
|
-
* // Set cached position after computing
|
|
4286
|
-
* setPositionCache(world, entity, { xi: 5, xl: 85, yi: 3, yl: 23, base: 0 });
|
|
4806
|
+
* import { createPluginRegistry, registerPlugin, LoopPhase } from 'blecsd';
|
|
4287
4807
|
*
|
|
4288
|
-
*
|
|
4289
|
-
* const
|
|
4290
|
-
*
|
|
4291
|
-
*
|
|
4292
|
-
*
|
|
4293
|
-
* }
|
|
4808
|
+
* const registry = createPluginRegistry();
|
|
4809
|
+
* const plugin = {
|
|
4810
|
+
* name: 'physics',
|
|
4811
|
+
* version: '1.0.0',
|
|
4812
|
+
* systems: [
|
|
4813
|
+
* { system: gravitySystem, phase: LoopPhase.ANIMATION, priority: 0 },
|
|
4814
|
+
* ],
|
|
4815
|
+
* };
|
|
4294
4816
|
*
|
|
4295
|
-
*
|
|
4296
|
-
* invalidatePositionCache(world, entity);
|
|
4817
|
+
* registerPlugin(registry, scheduler, world, plugin);
|
|
4297
4818
|
* ```
|
|
4298
4819
|
*/
|
|
4299
|
-
|
|
4300
|
-
/** Inner X start (left edge after border/padding) */
|
|
4301
|
-
xi: Float32Array<ArrayBuffer>;
|
|
4302
|
-
/** Inner X end (right edge before border/padding) */
|
|
4303
|
-
xl: Float32Array<ArrayBuffer>;
|
|
4304
|
-
/** Inner Y start (top edge after border/padding) */
|
|
4305
|
-
yi: Float32Array<ArrayBuffer>;
|
|
4306
|
-
/** Inner Y end (bottom edge before border/padding) */
|
|
4307
|
-
yl: Float32Array<ArrayBuffer>;
|
|
4308
|
-
/** Scroll base offset */
|
|
4309
|
-
base: Float32Array<ArrayBuffer>;
|
|
4310
|
-
/** Cache validity flag (1 = valid, 0 = invalid) */
|
|
4311
|
-
valid: Uint8Array<ArrayBuffer>;
|
|
4312
|
-
};
|
|
4820
|
+
|
|
4313
4821
|
/**
|
|
4314
|
-
*
|
|
4822
|
+
* A component definition that a plugin provides.
|
|
4823
|
+
* Stores metadata about the component for registration tracking.
|
|
4315
4824
|
*/
|
|
4316
|
-
interface
|
|
4317
|
-
/**
|
|
4318
|
-
readonly
|
|
4319
|
-
/**
|
|
4320
|
-
readonly
|
|
4321
|
-
/** Inner Y start (top edge after border/padding) */
|
|
4322
|
-
readonly yi: number;
|
|
4323
|
-
/** Inner Y end (bottom edge before border/padding) */
|
|
4324
|
-
readonly yl: number;
|
|
4325
|
-
/** Scroll base offset */
|
|
4326
|
-
readonly base: number;
|
|
4825
|
+
interface PluginComponent {
|
|
4826
|
+
/** Unique name identifying this component */
|
|
4827
|
+
readonly name: string;
|
|
4828
|
+
/** The actual component store (SoA typed arrays or marker) */
|
|
4829
|
+
readonly store: unknown;
|
|
4327
4830
|
}
|
|
4328
4831
|
/**
|
|
4329
|
-
*
|
|
4832
|
+
* A system definition that a plugin provides,
|
|
4833
|
+
* including which scheduler phase it should run in.
|
|
4330
4834
|
*/
|
|
4331
|
-
interface
|
|
4332
|
-
/**
|
|
4333
|
-
readonly
|
|
4334
|
-
/**
|
|
4335
|
-
readonly
|
|
4336
|
-
/**
|
|
4337
|
-
readonly
|
|
4338
|
-
/** Inner Y end (bottom edge before border/padding) */
|
|
4339
|
-
readonly yl: number;
|
|
4340
|
-
/** Scroll base offset */
|
|
4341
|
-
readonly base: number;
|
|
4835
|
+
interface PluginSystem {
|
|
4836
|
+
/** The system function */
|
|
4837
|
+
readonly system: System;
|
|
4838
|
+
/** The scheduler phase this system should be registered in */
|
|
4839
|
+
readonly phase: LoopPhase;
|
|
4840
|
+
/** Priority within the phase (lower = earlier, default: 0) */
|
|
4841
|
+
readonly priority?: number;
|
|
4342
4842
|
}
|
|
4343
4843
|
/**
|
|
4344
|
-
*
|
|
4345
|
-
*
|
|
4844
|
+
* A widget declaration that a plugin provides.
|
|
4845
|
+
* Used to register widgets when the plugin is installed.
|
|
4846
|
+
*/
|
|
4847
|
+
interface PluginWidgetDeclaration {
|
|
4848
|
+
/** Widget type name (e.g., 'bar-chart', 'pie-chart') */
|
|
4849
|
+
readonly name: string;
|
|
4850
|
+
/** Human-readable description */
|
|
4851
|
+
readonly description?: string;
|
|
4852
|
+
/** Factory function for creating the widget entity */
|
|
4853
|
+
readonly factory: (world: World, config: Record<string, unknown>) => number;
|
|
4854
|
+
/** Tags for categorization */
|
|
4855
|
+
readonly tags?: readonly string[];
|
|
4856
|
+
}
|
|
4857
|
+
/**
|
|
4858
|
+
* A theme declaration that a plugin provides.
|
|
4859
|
+
* Used to register themes when the plugin is installed.
|
|
4860
|
+
*/
|
|
4861
|
+
interface PluginThemeDeclaration {
|
|
4862
|
+
/** Theme name */
|
|
4863
|
+
readonly name: string;
|
|
4864
|
+
/** Theme data object */
|
|
4865
|
+
readonly theme: Record<string, unknown>;
|
|
4866
|
+
}
|
|
4867
|
+
/**
|
|
4868
|
+
* Plugin interface for extending blECSd with reusable functionality.
|
|
4346
4869
|
*
|
|
4347
|
-
*
|
|
4348
|
-
*
|
|
4349
|
-
*
|
|
4870
|
+
* Plugins bundle components, systems, and lifecycle hooks into a
|
|
4871
|
+
* single installable unit. They declare dependencies and can
|
|
4872
|
+
* initialize/cleanup world state.
|
|
4350
4873
|
*
|
|
4351
4874
|
* @example
|
|
4352
4875
|
* ```typescript
|
|
4353
|
-
* import {
|
|
4876
|
+
* import type { Plugin } from 'blecsd';
|
|
4877
|
+
* import { LoopPhase } from 'blecsd';
|
|
4354
4878
|
*
|
|
4355
|
-
*
|
|
4356
|
-
*
|
|
4357
|
-
*
|
|
4358
|
-
*
|
|
4359
|
-
*
|
|
4360
|
-
*
|
|
4361
|
-
*
|
|
4362
|
-
*
|
|
4879
|
+
* const myPlugin: Plugin = {
|
|
4880
|
+
* name: 'my-plugin',
|
|
4881
|
+
* version: '1.0.0',
|
|
4882
|
+
* dependencies: ['core-renderer'],
|
|
4883
|
+
* components: [
|
|
4884
|
+
* { name: 'MyComponent', store: MyComponentStore },
|
|
4885
|
+
* ],
|
|
4886
|
+
* systems: [
|
|
4887
|
+
* { system: myUpdateSystem, phase: LoopPhase.UPDATE },
|
|
4888
|
+
* { system: myRenderSystem, phase: LoopPhase.RENDER, priority: 10 },
|
|
4889
|
+
* ],
|
|
4890
|
+
* init: (world) => {
|
|
4891
|
+
* // Set up initial world state
|
|
4892
|
+
* return world;
|
|
4893
|
+
* },
|
|
4894
|
+
* cleanup: (world) => {
|
|
4895
|
+
* // Tear down plugin state
|
|
4896
|
+
* return world;
|
|
4897
|
+
* },
|
|
4898
|
+
* };
|
|
4363
4899
|
* ```
|
|
4364
4900
|
*/
|
|
4365
|
-
|
|
4901
|
+
interface Plugin {
|
|
4902
|
+
/** Unique plugin name */
|
|
4903
|
+
readonly name: string;
|
|
4904
|
+
/** Semantic version string */
|
|
4905
|
+
readonly version: string;
|
|
4906
|
+
/** Names of plugins this one depends on (must be registered first) */
|
|
4907
|
+
readonly dependencies?: readonly string[];
|
|
4908
|
+
/** Components provided by this plugin */
|
|
4909
|
+
readonly components?: readonly PluginComponent[];
|
|
4910
|
+
/** Systems provided by this plugin, with phase assignments */
|
|
4911
|
+
readonly systems?: readonly PluginSystem[];
|
|
4912
|
+
/** Widget declarations provided by this plugin */
|
|
4913
|
+
readonly widgets?: readonly PluginWidgetDeclaration[];
|
|
4914
|
+
/** Theme declarations provided by this plugin */
|
|
4915
|
+
readonly themes?: readonly PluginThemeDeclaration[];
|
|
4916
|
+
/** Zod schema for plugin configuration validation */
|
|
4917
|
+
readonly configSchema?: z.ZodType;
|
|
4918
|
+
/** Called when the plugin is registered. Can set up initial world state. */
|
|
4919
|
+
readonly init?: (world: World) => World;
|
|
4920
|
+
/** Called when the plugin is activated (starts processing). */
|
|
4921
|
+
readonly onActivate?: (world: World) => void;
|
|
4922
|
+
/** Called when the plugin is deactivated (stops processing). */
|
|
4923
|
+
readonly onDeactivate?: (world: World) => void;
|
|
4924
|
+
/** Called when the plugin is unregistered. Can clean up world state. */
|
|
4925
|
+
readonly cleanup?: (world: World) => World;
|
|
4926
|
+
}
|
|
4366
4927
|
/**
|
|
4367
|
-
*
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4928
|
+
* Info about a registered plugin, returned by getPlugins().
|
|
4929
|
+
*/
|
|
4930
|
+
interface PluginInfo {
|
|
4931
|
+
/** Plugin name */
|
|
4932
|
+
readonly name: string;
|
|
4933
|
+
/** Plugin version */
|
|
4934
|
+
readonly version: string;
|
|
4935
|
+
/** Names of dependencies */
|
|
4936
|
+
readonly dependencies: readonly string[];
|
|
4937
|
+
/** Number of components provided */
|
|
4938
|
+
readonly componentCount: number;
|
|
4939
|
+
/** Number of systems provided */
|
|
4940
|
+
readonly systemCount: number;
|
|
4941
|
+
/** Number of widgets provided */
|
|
4942
|
+
readonly widgetCount: number;
|
|
4943
|
+
/** Number of themes provided */
|
|
4944
|
+
readonly themeCount: number;
|
|
4945
|
+
/** Whether the plugin is currently active */
|
|
4946
|
+
readonly active: boolean;
|
|
4947
|
+
}
|
|
4948
|
+
/**
|
|
4949
|
+
* Result of a plugin registration operation.
|
|
4950
|
+
*/
|
|
4951
|
+
interface PluginRegistrationResult {
|
|
4952
|
+
/** Whether registration succeeded */
|
|
4953
|
+
readonly success: boolean;
|
|
4954
|
+
/** Error message if registration failed */
|
|
4955
|
+
readonly error?: string;
|
|
4956
|
+
/** Number of systems registered with the scheduler */
|
|
4957
|
+
readonly systemsRegistered: number;
|
|
4958
|
+
/** Number of components registered */
|
|
4959
|
+
readonly componentsRegistered: number;
|
|
4960
|
+
}
|
|
4961
|
+
/**
|
|
4962
|
+
* Registry that tracks all registered plugins and their state.
|
|
4963
|
+
*/
|
|
4964
|
+
interface PluginRegistry {
|
|
4965
|
+
/** Internal storage, not for direct access */
|
|
4966
|
+
readonly _plugins: ReadonlyMap<string, PluginRegistryEntry>;
|
|
4967
|
+
}
|
|
4968
|
+
/**
|
|
4969
|
+
* Internal entry for a registered plugin.
|
|
4970
|
+
* @internal
|
|
4971
|
+
*/
|
|
4972
|
+
interface PluginRegistryEntry {
|
|
4973
|
+
readonly plugin: Plugin;
|
|
4974
|
+
readonly registeredSystems: readonly PluginSystem[];
|
|
4975
|
+
active: boolean;
|
|
4976
|
+
}
|
|
4977
|
+
/**
|
|
4978
|
+
* Zod schema for PluginComponent validation.
|
|
4373
4979
|
*
|
|
4374
4980
|
* @example
|
|
4375
4981
|
* ```typescript
|
|
4376
|
-
* import {
|
|
4982
|
+
* import { PluginComponentSchema } from 'blecsd';
|
|
4377
4983
|
*
|
|
4378
|
-
* const
|
|
4379
|
-
*
|
|
4380
|
-
*
|
|
4381
|
-
*
|
|
4382
|
-
* const innerHeight = cached.yl - cached.yi;
|
|
4383
|
-
* }
|
|
4984
|
+
* const validated = PluginComponentSchema.parse({
|
|
4985
|
+
* name: 'MyComponent',
|
|
4986
|
+
* store: myStore,
|
|
4987
|
+
* });
|
|
4384
4988
|
* ```
|
|
4385
4989
|
*/
|
|
4386
|
-
declare
|
|
4990
|
+
declare const PluginComponentSchema: z.ZodObject<{
|
|
4991
|
+
name: z.ZodString;
|
|
4992
|
+
store: z.ZodUnknown;
|
|
4993
|
+
}, z.core.$strip>;
|
|
4387
4994
|
/**
|
|
4388
|
-
*
|
|
4995
|
+
* Zod schema for PluginSystem validation.
|
|
4389
4996
|
*
|
|
4390
|
-
* @
|
|
4391
|
-
*
|
|
4392
|
-
*
|
|
4997
|
+
* @example
|
|
4998
|
+
* ```typescript
|
|
4999
|
+
* import { PluginSystemSchema } from 'blecsd';
|
|
5000
|
+
*
|
|
5001
|
+
* const validated = PluginSystemSchema.parse({
|
|
5002
|
+
* system: mySystem,
|
|
5003
|
+
* phase: 2, // LoopPhase.UPDATE
|
|
5004
|
+
* priority: 0,
|
|
5005
|
+
* });
|
|
5006
|
+
* ```
|
|
5007
|
+
*/
|
|
5008
|
+
declare const PluginSystemSchema: z.ZodObject<{
|
|
5009
|
+
system: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
5010
|
+
phase: z.ZodEnum<typeof LoopPhase>;
|
|
5011
|
+
priority: z.ZodOptional<z.ZodNumber>;
|
|
5012
|
+
}, z.core.$strip>;
|
|
5013
|
+
/**
|
|
5014
|
+
* Zod schema for Plugin manifest validation.
|
|
5015
|
+
* Validates the structure of a plugin before registration.
|
|
4393
5016
|
*
|
|
4394
5017
|
* @example
|
|
4395
5018
|
* ```typescript
|
|
4396
|
-
* import {
|
|
5019
|
+
* import { PluginSchema } from 'blecsd';
|
|
4397
5020
|
*
|
|
4398
|
-
*
|
|
4399
|
-
*
|
|
5021
|
+
* const result = PluginSchema.safeParse(pluginCandidate);
|
|
5022
|
+
* if (result.success) {
|
|
5023
|
+
* registerPlugin(registry, scheduler, world, result.data);
|
|
4400
5024
|
* }
|
|
4401
5025
|
* ```
|
|
4402
5026
|
*/
|
|
4403
|
-
declare function hasValidPositionCache(_world: World, eid: Entity): boolean;
|
|
4404
5027
|
/**
|
|
4405
|
-
*
|
|
4406
|
-
|
|
5028
|
+
* Zod schema for PluginWidgetDeclaration validation.
|
|
5029
|
+
*/
|
|
5030
|
+
declare const PluginWidgetDeclarationSchema: z.ZodObject<{
|
|
5031
|
+
name: z.ZodString;
|
|
5032
|
+
description: z.ZodOptional<z.ZodString>;
|
|
5033
|
+
factory: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
5034
|
+
tags: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
5035
|
+
}, z.core.$strip>;
|
|
5036
|
+
/**
|
|
5037
|
+
* Zod schema for PluginThemeDeclaration validation.
|
|
5038
|
+
*/
|
|
5039
|
+
declare const PluginThemeDeclarationSchema: z.ZodObject<{
|
|
5040
|
+
name: z.ZodString;
|
|
5041
|
+
theme: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
5042
|
+
}, z.core.$strip>;
|
|
5043
|
+
declare const PluginSchema: z.ZodObject<{
|
|
5044
|
+
name: z.ZodString;
|
|
5045
|
+
version: z.ZodString;
|
|
5046
|
+
dependencies: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
5047
|
+
components: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
5048
|
+
name: z.ZodString;
|
|
5049
|
+
store: z.ZodUnknown;
|
|
5050
|
+
}, z.core.$strip>>>>;
|
|
5051
|
+
systems: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
5052
|
+
system: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
5053
|
+
phase: z.ZodEnum<typeof LoopPhase>;
|
|
5054
|
+
priority: z.ZodOptional<z.ZodNumber>;
|
|
5055
|
+
}, z.core.$strip>>>>;
|
|
5056
|
+
widgets: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
5057
|
+
name: z.ZodString;
|
|
5058
|
+
description: z.ZodOptional<z.ZodString>;
|
|
5059
|
+
factory: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
5060
|
+
tags: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
5061
|
+
}, z.core.$strip>>>>;
|
|
5062
|
+
themes: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
5063
|
+
name: z.ZodString;
|
|
5064
|
+
theme: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
5065
|
+
}, z.core.$strip>>>>;
|
|
5066
|
+
configSchema: z.ZodOptional<z.ZodUnknown>;
|
|
5067
|
+
init: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
|
|
5068
|
+
onActivate: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
|
|
5069
|
+
onDeactivate: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
|
|
5070
|
+
cleanup: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
|
|
5071
|
+
}, z.core.$strip>;
|
|
5072
|
+
/**
|
|
5073
|
+
* Creates a new, empty plugin registry.
|
|
4407
5074
|
*
|
|
4408
|
-
* @
|
|
4409
|
-
* @param eid - The entity ID
|
|
5075
|
+
* @returns A new PluginRegistry
|
|
4410
5076
|
*
|
|
4411
5077
|
* @example
|
|
4412
5078
|
* ```typescript
|
|
4413
|
-
* import {
|
|
5079
|
+
* import { createPluginRegistry } from 'blecsd';
|
|
4414
5080
|
*
|
|
4415
|
-
*
|
|
4416
|
-
* setPosition(world, entity, 10, 20);
|
|
4417
|
-
* invalidatePositionCache(world, entity);
|
|
5081
|
+
* const registry = createPluginRegistry();
|
|
4418
5082
|
* ```
|
|
4419
5083
|
*/
|
|
4420
|
-
declare function
|
|
5084
|
+
declare function createPluginRegistry(): PluginRegistry;
|
|
4421
5085
|
/**
|
|
4422
|
-
*
|
|
4423
|
-
* Call this when a parent changes position, as all children need recalculation.
|
|
5086
|
+
* Registers a plugin with the given registry and scheduler.
|
|
4424
5087
|
*
|
|
4425
|
-
*
|
|
4426
|
-
*
|
|
4427
|
-
*
|
|
5088
|
+
* Validates the plugin manifest, checks dependencies, registers systems
|
|
5089
|
+
* with the scheduler, and calls the plugin's init hook if present.
|
|
5090
|
+
*
|
|
5091
|
+
* @param registry - The plugin registry to register with
|
|
5092
|
+
* @param scheduler - The scheduler to register systems with
|
|
5093
|
+
* @param world - The ECS world (passed to init hook)
|
|
5094
|
+
* @param plugin - The plugin to register
|
|
5095
|
+
* @returns Registration result with success status and details
|
|
4428
5096
|
*
|
|
4429
5097
|
* @example
|
|
4430
5098
|
* ```typescript
|
|
4431
|
-
* import {
|
|
5099
|
+
* import { createPluginRegistry, createScheduler, registerPlugin, LoopPhase } from 'blecsd';
|
|
4432
5100
|
*
|
|
4433
|
-
*
|
|
4434
|
-
*
|
|
4435
|
-
*
|
|
4436
|
-
*
|
|
5101
|
+
* const registry = createPluginRegistry();
|
|
5102
|
+
* const scheduler = createScheduler();
|
|
5103
|
+
* const world = createWorld();
|
|
5104
|
+
*
|
|
5105
|
+
* const result = registerPlugin(registry, scheduler, world, {
|
|
5106
|
+
* name: 'physics',
|
|
5107
|
+
* version: '1.0.0',
|
|
5108
|
+
* systems: [
|
|
5109
|
+
* { system: gravitySystem, phase: LoopPhase.ANIMATION },
|
|
5110
|
+
* ],
|
|
4437
5111
|
* });
|
|
5112
|
+
*
|
|
5113
|
+
* if (!result.success) {
|
|
5114
|
+
* console.error('Plugin registration failed:', result.error);
|
|
5115
|
+
* }
|
|
4438
5116
|
* ```
|
|
4439
5117
|
*/
|
|
4440
|
-
declare function
|
|
5118
|
+
declare function registerPlugin(registry: PluginRegistry, scheduler: Scheduler, world: World, plugin: Plugin): PluginRegistrationResult;
|
|
4441
5119
|
/**
|
|
4442
|
-
*
|
|
4443
|
-
*
|
|
5120
|
+
* Unregisters a plugin, removing its systems from the scheduler
|
|
5121
|
+
* and calling the cleanup hook.
|
|
4444
5122
|
*
|
|
4445
|
-
* @param
|
|
5123
|
+
* @param registry - The plugin registry
|
|
5124
|
+
* @param scheduler - The scheduler to unregister systems from
|
|
5125
|
+
* @param world - The ECS world (passed to cleanup hook)
|
|
5126
|
+
* @param pluginName - The name of the plugin to unregister
|
|
5127
|
+
* @returns true if the plugin was found and unregistered
|
|
4446
5128
|
*
|
|
4447
5129
|
* @example
|
|
4448
5130
|
* ```typescript
|
|
4449
|
-
* import {
|
|
5131
|
+
* import { unregisterPlugin } from 'blecsd';
|
|
4450
5132
|
*
|
|
4451
|
-
*
|
|
4452
|
-
*
|
|
5133
|
+
* const removed = unregisterPlugin(registry, scheduler, world, 'physics');
|
|
5134
|
+
* if (!removed) {
|
|
5135
|
+
* console.warn('Plugin not found');
|
|
5136
|
+
* }
|
|
4453
5137
|
* ```
|
|
4454
5138
|
*/
|
|
4455
|
-
declare function
|
|
5139
|
+
declare function unregisterPlugin(registry: PluginRegistry, scheduler: Scheduler, world: World, pluginName: string): boolean;
|
|
4456
5140
|
/**
|
|
4457
|
-
* Gets
|
|
4458
|
-
* Returns 0 if cache is invalid.
|
|
5141
|
+
* Gets information about all registered plugins.
|
|
4459
5142
|
*
|
|
4460
|
-
* @param
|
|
4461
|
-
* @
|
|
4462
|
-
* @returns Inner width or 0 if invalid
|
|
5143
|
+
* @param registry - The plugin registry
|
|
5144
|
+
* @returns Array of plugin info objects
|
|
4463
5145
|
*
|
|
4464
5146
|
* @example
|
|
4465
5147
|
* ```typescript
|
|
4466
|
-
* import {
|
|
5148
|
+
* import { getPlugins } from 'blecsd';
|
|
4467
5149
|
*
|
|
4468
|
-
* const
|
|
5150
|
+
* const plugins = getPlugins(registry);
|
|
5151
|
+
* for (const info of plugins) {
|
|
5152
|
+
* console.log(`${info.name} v${info.version} (${info.systemCount} systems)`);
|
|
5153
|
+
* }
|
|
4469
5154
|
* ```
|
|
4470
5155
|
*/
|
|
4471
|
-
declare function
|
|
5156
|
+
declare function getPlugins(registry: PluginRegistry): readonly PluginInfo[];
|
|
4472
5157
|
/**
|
|
4473
|
-
*
|
|
4474
|
-
* Returns 0 if cache is invalid.
|
|
5158
|
+
* Checks if a plugin is registered.
|
|
4475
5159
|
*
|
|
4476
|
-
* @param
|
|
4477
|
-
* @param
|
|
4478
|
-
* @returns
|
|
5160
|
+
* @param registry - The plugin registry
|
|
5161
|
+
* @param pluginName - The plugin name to check
|
|
5162
|
+
* @returns true if the plugin is registered
|
|
4479
5163
|
*
|
|
4480
5164
|
* @example
|
|
4481
5165
|
* ```typescript
|
|
4482
|
-
* import {
|
|
5166
|
+
* import { hasPlugin } from 'blecsd';
|
|
4483
5167
|
*
|
|
4484
|
-
*
|
|
5168
|
+
* if (hasPlugin(registry, 'physics')) {
|
|
5169
|
+
* console.log('Physics plugin is loaded');
|
|
5170
|
+
* }
|
|
4485
5171
|
* ```
|
|
4486
5172
|
*/
|
|
4487
|
-
declare function
|
|
5173
|
+
declare function hasPlugin(registry: PluginRegistry, pluginName: string): boolean;
|
|
4488
5174
|
/**
|
|
4489
|
-
*
|
|
4490
|
-
* Useful when only scroll position changes but layout is the same.
|
|
5175
|
+
* Gets the count of registered plugins.
|
|
4491
5176
|
*
|
|
4492
|
-
* @param
|
|
4493
|
-
* @
|
|
4494
|
-
* @param base - New scroll base value
|
|
5177
|
+
* @param registry - The plugin registry
|
|
5178
|
+
* @returns Number of registered plugins
|
|
4495
5179
|
*
|
|
4496
5180
|
* @example
|
|
4497
5181
|
* ```typescript
|
|
4498
|
-
* import {
|
|
5182
|
+
* import { getPluginCount } from 'blecsd';
|
|
4499
5183
|
*
|
|
4500
|
-
*
|
|
4501
|
-
* updateCachedScrollBase(world, entity, newScrollY);
|
|
5184
|
+
* console.log(`${getPluginCount(registry)} plugins loaded`);
|
|
4502
5185
|
* ```
|
|
4503
5186
|
*/
|
|
4504
|
-
declare function
|
|
5187
|
+
declare function getPluginCount(registry: PluginRegistry): number;
|
|
4505
5188
|
/**
|
|
4506
|
-
*
|
|
4507
|
-
*
|
|
5189
|
+
* Unregisters all plugins in reverse registration order,
|
|
5190
|
+
* calling cleanup hooks and removing systems.
|
|
4508
5191
|
*
|
|
4509
|
-
* @param
|
|
4510
|
-
* @param
|
|
4511
|
-
* @param
|
|
4512
|
-
* @param y - Y coordinate to test
|
|
4513
|
-
* @returns true if point is within inner bounds
|
|
5192
|
+
* @param registry - The plugin registry
|
|
5193
|
+
* @param scheduler - The scheduler to unregister systems from
|
|
5194
|
+
* @param world - The ECS world (passed to cleanup hooks)
|
|
4514
5195
|
*
|
|
4515
5196
|
* @example
|
|
4516
5197
|
* ```typescript
|
|
4517
|
-
* import {
|
|
5198
|
+
* import { clearPlugins } from 'blecsd';
|
|
4518
5199
|
*
|
|
4519
|
-
*
|
|
4520
|
-
* if (isPointInCachedBounds(world, entity, mouseX, mouseY)) {
|
|
4521
|
-
* // Point is inside the element's inner area
|
|
4522
|
-
* }
|
|
5200
|
+
* clearPlugins(registry, scheduler, world);
|
|
4523
5201
|
* ```
|
|
4524
5202
|
*/
|
|
4525
|
-
declare function
|
|
4526
|
-
|
|
5203
|
+
declare function clearPlugins(registry: PluginRegistry, scheduler: Scheduler, world: World): void;
|
|
4527
5204
|
/**
|
|
4528
|
-
*
|
|
4529
|
-
*
|
|
4530
|
-
*
|
|
5205
|
+
* Creates a plugin definition with sensible defaults.
|
|
5206
|
+
* A convenience function that makes plugin creation more concise.
|
|
5207
|
+
*
|
|
5208
|
+
* @param config - Plugin configuration
|
|
5209
|
+
* @returns A fully-formed Plugin object
|
|
5210
|
+
*
|
|
5211
|
+
* @example
|
|
5212
|
+
* ```typescript
|
|
5213
|
+
* import { definePlugin, LoopPhase } from 'blecsd';
|
|
5214
|
+
*
|
|
5215
|
+
* const myPlugin = definePlugin({
|
|
5216
|
+
* name: 'my-charts',
|
|
5217
|
+
* version: '1.0.0',
|
|
5218
|
+
* widgets: [
|
|
5219
|
+
* { name: 'bar-chart', factory: createBarChart, tags: ['chart', 'data'] },
|
|
5220
|
+
* { name: 'pie-chart', factory: createPieChart, tags: ['chart', 'data'] },
|
|
5221
|
+
* ],
|
|
5222
|
+
* systems: [
|
|
5223
|
+
* { system: chartAnimationSystem, phase: LoopPhase.ANIMATION },
|
|
5224
|
+
* ],
|
|
5225
|
+
* });
|
|
5226
|
+
* ```
|
|
4531
5227
|
*/
|
|
4532
|
-
|
|
5228
|
+
declare function definePlugin(config: Plugin): Plugin;
|
|
4533
5229
|
/**
|
|
4534
|
-
*
|
|
4535
|
-
* -
|
|
4536
|
-
*
|
|
5230
|
+
* Activates a previously deactivated plugin.
|
|
5231
|
+
* Re-registers its systems with the scheduler and calls onActivate.
|
|
5232
|
+
*
|
|
5233
|
+
* @param registry - The plugin registry
|
|
5234
|
+
* @param scheduler - The scheduler to register systems with
|
|
5235
|
+
* @param world - The ECS world
|
|
5236
|
+
* @param pluginName - The name of the plugin to activate
|
|
5237
|
+
* @returns true if the plugin was found and activated
|
|
5238
|
+
*
|
|
5239
|
+
* @example
|
|
5240
|
+
* ```typescript
|
|
5241
|
+
* import { activatePlugin } from 'blecsd';
|
|
5242
|
+
*
|
|
5243
|
+
* activatePlugin(registry, scheduler, world, 'physics');
|
|
5244
|
+
* ```
|
|
4537
5245
|
*/
|
|
4538
|
-
|
|
5246
|
+
declare function activatePlugin(registry: PluginRegistry, scheduler: Scheduler, world: World, pluginName: string): boolean;
|
|
4539
5247
|
/**
|
|
4540
|
-
*
|
|
4541
|
-
*
|
|
5248
|
+
* Deactivates a plugin without fully unregistering it.
|
|
5249
|
+
* Removes its systems from the scheduler and calls onDeactivate,
|
|
5250
|
+
* but keeps the plugin in the registry for later reactivation.
|
|
5251
|
+
*
|
|
5252
|
+
* @param registry - The plugin registry
|
|
5253
|
+
* @param scheduler - The scheduler to unregister systems from
|
|
5254
|
+
* @param world - The ECS world
|
|
5255
|
+
* @param pluginName - The name of the plugin to deactivate
|
|
5256
|
+
* @returns true if the plugin was found and deactivated
|
|
4542
5257
|
*
|
|
4543
5258
|
* @example
|
|
4544
5259
|
* ```typescript
|
|
4545
|
-
* import {
|
|
5260
|
+
* import { deactivatePlugin } from 'blecsd';
|
|
4546
5261
|
*
|
|
4547
|
-
*
|
|
4548
|
-
*
|
|
4549
|
-
*
|
|
4550
|
-
* PositionValueSchema.parse('center'); // Valid: keyword
|
|
5262
|
+
* deactivatePlugin(registry, scheduler, world, 'physics');
|
|
5263
|
+
* // Plugin is still registered but not running
|
|
5264
|
+
* // Re-activate later with activatePlugin()
|
|
4551
5265
|
* ```
|
|
4552
5266
|
*/
|
|
4553
|
-
declare
|
|
5267
|
+
declare function deactivatePlugin(registry: PluginRegistry, scheduler: Scheduler, world: World, pluginName: string): boolean;
|
|
4554
5268
|
/**
|
|
4555
|
-
*
|
|
4556
|
-
*
|
|
4557
|
-
* Supports:
|
|
4558
|
-
* - Numbers: returned as-is
|
|
4559
|
-
* - Percentages: '50%' → parentSize * 0.5
|
|
4560
|
-
* - Expressions: '50%-5' → (parentSize * 0.5) - 5
|
|
4561
|
-
* - Keywords:
|
|
4562
|
-
* - 'center': (parentSize - elementSize) / 2
|
|
4563
|
-
* - 'half': parentSize / 2
|
|
4564
|
-
* - 'left'/'top': 0
|
|
4565
|
-
* - 'right'/'bottom': parentSize - elementSize
|
|
5269
|
+
* Checks if a plugin is currently active.
|
|
4566
5270
|
*
|
|
4567
|
-
* @param
|
|
4568
|
-
* @param
|
|
4569
|
-
* @
|
|
4570
|
-
* @returns Resolved absolute position
|
|
5271
|
+
* @param registry - The plugin registry
|
|
5272
|
+
* @param pluginName - The name of the plugin to check
|
|
5273
|
+
* @returns true if the plugin is registered and active
|
|
4571
5274
|
*
|
|
4572
5275
|
* @example
|
|
4573
5276
|
* ```typescript
|
|
4574
|
-
* import {
|
|
5277
|
+
* import { isPluginActive } from 'blecsd';
|
|
4575
5278
|
*
|
|
4576
|
-
*
|
|
4577
|
-
*
|
|
5279
|
+
* if (isPluginActive(registry, 'physics')) {
|
|
5280
|
+
* console.log('Physics is running');
|
|
5281
|
+
* }
|
|
5282
|
+
* ```
|
|
5283
|
+
*/
|
|
5284
|
+
declare function isPluginActive(registry: PluginRegistry, pluginName: string): boolean;
|
|
5285
|
+
/**
|
|
5286
|
+
* Validates plugin configuration against its declared config schema.
|
|
5287
|
+
* Returns the validated config or throws if invalid.
|
|
5288
|
+
*
|
|
5289
|
+
* @param plugin - The plugin with a configSchema
|
|
5290
|
+
* @param config - The configuration to validate
|
|
5291
|
+
* @returns The validated configuration
|
|
5292
|
+
* @throws If the config is invalid according to the plugin's schema
|
|
4578
5293
|
*
|
|
4579
|
-
*
|
|
4580
|
-
*
|
|
5294
|
+
* @example
|
|
5295
|
+
* ```typescript
|
|
5296
|
+
* import { validatePluginConfig, definePlugin } from 'blecsd';
|
|
5297
|
+
* import { z } from 'zod';
|
|
4581
5298
|
*
|
|
4582
|
-
*
|
|
4583
|
-
*
|
|
4584
|
-
*
|
|
5299
|
+
* const plugin = definePlugin({
|
|
5300
|
+
* name: 'my-plugin',
|
|
5301
|
+
* version: '1.0.0',
|
|
5302
|
+
* configSchema: z.object({ maxItems: z.number().positive() }),
|
|
5303
|
+
* });
|
|
4585
5304
|
*
|
|
4586
|
-
*
|
|
4587
|
-
* parsePosition('center', 100, 20); // 40 ((100-20)/2)
|
|
4588
|
-
* parsePosition('half', 100, 20); // 50 (100/2)
|
|
4589
|
-
* parsePosition('right', 100, 20); // 80 (100-20)
|
|
5305
|
+
* const config = validatePluginConfig(plugin, { maxItems: 10 });
|
|
4590
5306
|
* ```
|
|
4591
5307
|
*/
|
|
4592
|
-
declare function
|
|
5308
|
+
declare function validatePluginConfig(plugin: Plugin, config: unknown): unknown;
|
|
5309
|
+
|
|
5310
|
+
/**
|
|
5311
|
+
* Position caching for render optimization.
|
|
5312
|
+
* Caches computed positions to avoid expensive recalculations.
|
|
5313
|
+
* @module core/positionCache
|
|
5314
|
+
*/
|
|
5315
|
+
|
|
4593
5316
|
/**
|
|
4594
|
-
*
|
|
4595
|
-
*
|
|
5317
|
+
* Last computed position data.
|
|
5318
|
+
* Used to cache resolved positions and skip recalculation when unchanged.
|
|
4596
5319
|
*
|
|
4597
|
-
*
|
|
4598
|
-
*
|
|
4599
|
-
*
|
|
4600
|
-
*
|
|
5320
|
+
* - `xi`: Inner X start (left edge after border/padding)
|
|
5321
|
+
* - `xl`: Inner X end (right edge before border/padding)
|
|
5322
|
+
* - `yi`: Inner Y start (top edge after border/padding)
|
|
5323
|
+
* - `yl`: Inner Y end (bottom edge before border/padding)
|
|
5324
|
+
* - `base`: Scroll base offset
|
|
5325
|
+
* - `valid`: Cache validity flag (1 = valid, 0 = invalid)
|
|
4601
5326
|
*
|
|
4602
5327
|
* @example
|
|
4603
5328
|
* ```typescript
|
|
4604
|
-
* import {
|
|
5329
|
+
* import { setPositionCache, getPositionCache, invalidatePositionCache } from 'blecsd';
|
|
4605
5330
|
*
|
|
4606
|
-
* //
|
|
4607
|
-
*
|
|
5331
|
+
* // Set cached position after computing
|
|
5332
|
+
* setPositionCache(world, entity, { xi: 5, xl: 85, yi: 3, yl: 23, base: 0 });
|
|
4608
5333
|
*
|
|
4609
|
-
* //
|
|
4610
|
-
*
|
|
4611
|
-
*
|
|
5334
|
+
* // Get cached position (returns undefined if invalid)
|
|
5335
|
+
* const cached = getPositionCache(world, entity);
|
|
5336
|
+
* if (cached) {
|
|
5337
|
+
* // Use cached values instead of recalculating
|
|
5338
|
+
* console.log(`Inner bounds: ${cached.xi},${cached.yi} to ${cached.xl},${cached.yl}`);
|
|
5339
|
+
* }
|
|
5340
|
+
*
|
|
5341
|
+
* // Invalidate when position changes
|
|
5342
|
+
* invalidatePositionCache(world, entity);
|
|
4612
5343
|
* ```
|
|
4613
5344
|
*/
|
|
4614
|
-
declare
|
|
5345
|
+
declare const PositionCache: {
|
|
5346
|
+
/** Inner X start (left edge after border/padding) */
|
|
5347
|
+
xi: Float32Array<ArrayBuffer>;
|
|
5348
|
+
/** Inner X end (right edge before border/padding) */
|
|
5349
|
+
xl: Float32Array<ArrayBuffer>;
|
|
5350
|
+
/** Inner Y start (top edge after border/padding) */
|
|
5351
|
+
yi: Float32Array<ArrayBuffer>;
|
|
5352
|
+
/** Inner Y end (bottom edge before border/padding) */
|
|
5353
|
+
yl: Float32Array<ArrayBuffer>;
|
|
5354
|
+
/** Scroll base offset */
|
|
5355
|
+
base: Float32Array<ArrayBuffer>;
|
|
5356
|
+
/** Cache validity flag (1 = valid, 0 = invalid) */
|
|
5357
|
+
valid: Uint8Array<ArrayBuffer>;
|
|
5358
|
+
};
|
|
5359
|
+
/**
|
|
5360
|
+
* Cached position data returned by getPositionCache.
|
|
5361
|
+
*/
|
|
5362
|
+
interface CachedPosition {
|
|
5363
|
+
/** Inner X start (left edge after border/padding) */
|
|
5364
|
+
readonly xi: number;
|
|
5365
|
+
/** Inner X end (right edge before border/padding) */
|
|
5366
|
+
readonly xl: number;
|
|
5367
|
+
/** Inner Y start (top edge after border/padding) */
|
|
5368
|
+
readonly yi: number;
|
|
5369
|
+
/** Inner Y end (bottom edge before border/padding) */
|
|
5370
|
+
readonly yl: number;
|
|
5371
|
+
/** Scroll base offset */
|
|
5372
|
+
readonly base: number;
|
|
5373
|
+
}
|
|
4615
5374
|
/**
|
|
4616
|
-
*
|
|
5375
|
+
* Options for setting position cache.
|
|
5376
|
+
*/
|
|
5377
|
+
interface SetPositionCacheOptions {
|
|
5378
|
+
/** Inner X start (left edge after border/padding) */
|
|
5379
|
+
readonly xi: number;
|
|
5380
|
+
/** Inner X end (right edge before border/padding) */
|
|
5381
|
+
readonly xl: number;
|
|
5382
|
+
/** Inner Y start (top edge after border/padding) */
|
|
5383
|
+
readonly yi: number;
|
|
5384
|
+
/** Inner Y end (bottom edge before border/padding) */
|
|
5385
|
+
readonly yl: number;
|
|
5386
|
+
/** Scroll base offset */
|
|
5387
|
+
readonly base: number;
|
|
5388
|
+
}
|
|
5389
|
+
/**
|
|
5390
|
+
* Sets the cached position for an entity.
|
|
5391
|
+
* Marks the cache as valid.
|
|
4617
5392
|
*
|
|
4618
|
-
* @param
|
|
4619
|
-
* @param
|
|
4620
|
-
* @param
|
|
4621
|
-
* @returns Clamped position value within bounds
|
|
5393
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5394
|
+
* @param eid - The entity ID
|
|
5395
|
+
* @param options - Position values to cache
|
|
4622
5396
|
*
|
|
4623
5397
|
* @example
|
|
4624
5398
|
* ```typescript
|
|
4625
|
-
* import {
|
|
5399
|
+
* import { setPositionCache } from 'blecsd';
|
|
4626
5400
|
*
|
|
4627
|
-
*
|
|
4628
|
-
*
|
|
4629
|
-
*
|
|
5401
|
+
* // After computing positions during render
|
|
5402
|
+
* setPositionCache(world, entity, {
|
|
5403
|
+
* xi: 5, // Inner left
|
|
5404
|
+
* xl: 85, // Inner right
|
|
5405
|
+
* yi: 3, // Inner top
|
|
5406
|
+
* yl: 23, // Inner bottom
|
|
5407
|
+
* base: 0, // Scroll offset
|
|
5408
|
+
* });
|
|
4630
5409
|
* ```
|
|
4631
5410
|
*/
|
|
4632
|
-
declare function
|
|
5411
|
+
declare function setPositionCache(_world: World, eid: Entity, options: SetPositionCacheOptions): void;
|
|
4633
5412
|
/**
|
|
4634
|
-
*
|
|
5413
|
+
* Gets the cached position for an entity.
|
|
5414
|
+
* Returns undefined if the cache is invalid.
|
|
4635
5415
|
*
|
|
4636
|
-
* @param
|
|
4637
|
-
* @
|
|
5416
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5417
|
+
* @param eid - The entity ID
|
|
5418
|
+
* @returns Cached position data or undefined if invalid
|
|
4638
5419
|
*
|
|
4639
5420
|
* @example
|
|
4640
5421
|
* ```typescript
|
|
4641
|
-
* import {
|
|
5422
|
+
* import { getPositionCache } from 'blecsd';
|
|
4642
5423
|
*
|
|
4643
|
-
*
|
|
4644
|
-
*
|
|
4645
|
-
*
|
|
4646
|
-
*
|
|
5424
|
+
* const cached = getPositionCache(world, entity);
|
|
5425
|
+
* if (cached) {
|
|
5426
|
+
* // Use cached values
|
|
5427
|
+
* const innerWidth = cached.xl - cached.xi;
|
|
5428
|
+
* const innerHeight = cached.yl - cached.yi;
|
|
5429
|
+
* }
|
|
4647
5430
|
* ```
|
|
4648
5431
|
*/
|
|
4649
|
-
declare function
|
|
5432
|
+
declare function getPositionCache(_world: World, eid: Entity): CachedPosition | undefined;
|
|
4650
5433
|
/**
|
|
4651
|
-
* Checks if
|
|
5434
|
+
* Checks if the position cache is valid for an entity.
|
|
4652
5435
|
*
|
|
4653
|
-
* @param
|
|
4654
|
-
* @
|
|
5436
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5437
|
+
* @param eid - The entity ID
|
|
5438
|
+
* @returns true if cache is valid
|
|
4655
5439
|
*
|
|
4656
5440
|
* @example
|
|
4657
5441
|
* ```typescript
|
|
4658
|
-
* import {
|
|
5442
|
+
* import { hasValidPositionCache } from 'blecsd';
|
|
4659
5443
|
*
|
|
4660
|
-
*
|
|
4661
|
-
*
|
|
4662
|
-
*
|
|
4663
|
-
* isKeywordPosition(50); // false
|
|
5444
|
+
* if (hasValidPositionCache(world, entity)) {
|
|
5445
|
+
* // Skip expensive position calculation
|
|
5446
|
+
* }
|
|
4664
5447
|
* ```
|
|
4665
5448
|
*/
|
|
4666
|
-
declare function
|
|
5449
|
+
declare function hasValidPositionCache(_world: World, eid: Entity): boolean;
|
|
4667
5450
|
/**
|
|
4668
|
-
*
|
|
5451
|
+
* Invalidates the position cache for an entity.
|
|
5452
|
+
* Call this when position, size, or parent changes.
|
|
4669
5453
|
*
|
|
4670
|
-
* @
|
|
5454
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5455
|
+
* @param eid - The entity ID
|
|
4671
5456
|
*
|
|
4672
5457
|
* @example
|
|
4673
5458
|
* ```typescript
|
|
4674
|
-
* import {
|
|
5459
|
+
* import { invalidatePositionCache } from 'blecsd';
|
|
4675
5460
|
*
|
|
4676
|
-
*
|
|
4677
|
-
*
|
|
5461
|
+
* // Invalidate when entity moves
|
|
5462
|
+
* setPosition(world, entity, 10, 20);
|
|
5463
|
+
* invalidatePositionCache(world, entity);
|
|
4678
5464
|
* ```
|
|
4679
5465
|
*/
|
|
4680
|
-
declare function
|
|
5466
|
+
declare function invalidatePositionCache(_world: World, eid: Entity): void;
|
|
4681
5467
|
/**
|
|
4682
|
-
*
|
|
5468
|
+
* Invalidates the position cache for an entity and all its descendants.
|
|
5469
|
+
* Call this when a parent changes position, as all children need recalculation.
|
|
4683
5470
|
*
|
|
4684
|
-
* @param
|
|
4685
|
-
* @
|
|
5471
|
+
* @param world - The ECS world
|
|
5472
|
+
* @param eid - The entity ID
|
|
5473
|
+
* @param getDescendants - Function to get descendant entities
|
|
4686
5474
|
*
|
|
4687
5475
|
* @example
|
|
4688
5476
|
* ```typescript
|
|
4689
|
-
* import {
|
|
5477
|
+
* import { invalidatePositionCacheTree, getChildren } from 'blecsd';
|
|
4690
5478
|
*
|
|
4691
|
-
*
|
|
4692
|
-
*
|
|
5479
|
+
* // Invalidate entire subtree when parent moves
|
|
5480
|
+
* invalidatePositionCacheTree(world, parentEntity, (w, e) => {
|
|
5481
|
+
* // Return all descendants recursively
|
|
5482
|
+
* return getAllDescendants(w, e);
|
|
5483
|
+
* });
|
|
4693
5484
|
* ```
|
|
4694
5485
|
*/
|
|
4695
|
-
declare function
|
|
5486
|
+
declare function invalidatePositionCacheTree(world: World, eid: Entity, getDescendants: (world: World, eid: Entity) => Entity[]): void;
|
|
4696
5487
|
/**
|
|
4697
|
-
*
|
|
5488
|
+
* Clears all position caches.
|
|
5489
|
+
* Useful for forcing a complete recalculation after major changes.
|
|
4698
5490
|
*
|
|
4699
|
-
* @param
|
|
4700
|
-
* @param offset - Offset to add (negative to subtract)
|
|
4701
|
-
* @returns Expression string
|
|
5491
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
4702
5492
|
*
|
|
4703
5493
|
* @example
|
|
4704
5494
|
* ```typescript
|
|
4705
|
-
* import {
|
|
5495
|
+
* import { clearAllPositionCaches } from 'blecsd';
|
|
4706
5496
|
*
|
|
4707
|
-
*
|
|
4708
|
-
*
|
|
5497
|
+
* // After screen resize
|
|
5498
|
+
* clearAllPositionCaches(world);
|
|
5499
|
+
* ```
|
|
5500
|
+
*/
|
|
5501
|
+
declare function clearAllPositionCaches(_world: World): void;
|
|
5502
|
+
/**
|
|
5503
|
+
* Gets inner width from cached position.
|
|
5504
|
+
* Returns 0 if cache is invalid.
|
|
5505
|
+
*
|
|
5506
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5507
|
+
* @param eid - The entity ID
|
|
5508
|
+
* @returns Inner width or 0 if invalid
|
|
5509
|
+
*
|
|
5510
|
+
* @example
|
|
5511
|
+
* ```typescript
|
|
5512
|
+
* import { getCachedInnerWidth } from 'blecsd';
|
|
4709
5513
|
*
|
|
4710
|
-
* const
|
|
4711
|
-
* const resolved2 = parsePosition(pos2, 100, 0); // 90
|
|
5514
|
+
* const innerWidth = getCachedInnerWidth(world, entity);
|
|
4712
5515
|
* ```
|
|
4713
5516
|
*/
|
|
4714
|
-
declare function
|
|
5517
|
+
declare function getCachedInnerWidth(_world: World, eid: Entity): number;
|
|
4715
5518
|
/**
|
|
4716
|
-
*
|
|
5519
|
+
* Gets inner height from cached position.
|
|
5520
|
+
* Returns 0 if cache is invalid.
|
|
4717
5521
|
*
|
|
4718
|
-
* @param
|
|
4719
|
-
* @param
|
|
4720
|
-
* @
|
|
4721
|
-
* @param parentHeight - Parent container height
|
|
4722
|
-
* @param elementWidth - Element width (for centering)
|
|
4723
|
-
* @param elementHeight - Element height (for centering)
|
|
4724
|
-
* @returns Resolved { x, y } coordinates
|
|
5522
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5523
|
+
* @param eid - The entity ID
|
|
5524
|
+
* @returns Inner height or 0 if invalid
|
|
4725
5525
|
*
|
|
4726
5526
|
* @example
|
|
4727
5527
|
* ```typescript
|
|
4728
|
-
* import {
|
|
5528
|
+
* import { getCachedInnerHeight } from 'blecsd';
|
|
4729
5529
|
*
|
|
4730
|
-
* const
|
|
4731
|
-
*
|
|
5530
|
+
* const innerHeight = getCachedInnerHeight(world, entity);
|
|
5531
|
+
* ```
|
|
5532
|
+
*/
|
|
5533
|
+
declare function getCachedInnerHeight(_world: World, eid: Entity): number;
|
|
5534
|
+
/**
|
|
5535
|
+
* Updates just the scroll base in the cache.
|
|
5536
|
+
* Useful when only scroll position changes but layout is the same.
|
|
5537
|
+
*
|
|
5538
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5539
|
+
* @param eid - The entity ID
|
|
5540
|
+
* @param base - New scroll base value
|
|
5541
|
+
*
|
|
5542
|
+
* @example
|
|
5543
|
+
* ```typescript
|
|
5544
|
+
* import { updateCachedScrollBase } from 'blecsd';
|
|
4732
5545
|
*
|
|
4733
|
-
*
|
|
4734
|
-
*
|
|
5546
|
+
* // After scrolling (layout unchanged, just scroll offset)
|
|
5547
|
+
* updateCachedScrollBase(world, entity, newScrollY);
|
|
4735
5548
|
* ```
|
|
4736
5549
|
*/
|
|
4737
|
-
declare function
|
|
4738
|
-
x: number;
|
|
4739
|
-
y: number;
|
|
4740
|
-
};
|
|
5550
|
+
declare function updateCachedScrollBase(_world: World, eid: Entity, base: number): void;
|
|
4741
5551
|
/**
|
|
4742
|
-
*
|
|
5552
|
+
* Checks if a point is within the cached inner bounds.
|
|
5553
|
+
* Returns false if cache is invalid.
|
|
4743
5554
|
*
|
|
4744
|
-
* @param
|
|
4745
|
-
* @param
|
|
4746
|
-
* @param
|
|
4747
|
-
* @param
|
|
4748
|
-
* @
|
|
4749
|
-
* @param elementHeight - Element height
|
|
4750
|
-
* @returns Resolved and clamped { x, y } coordinates
|
|
5555
|
+
* @param _world - The ECS world (unused, for API consistency)
|
|
5556
|
+
* @param eid - The entity ID
|
|
5557
|
+
* @param x - X coordinate to test
|
|
5558
|
+
* @param y - Y coordinate to test
|
|
5559
|
+
* @returns true if point is within inner bounds
|
|
4751
5560
|
*
|
|
4752
5561
|
* @example
|
|
4753
5562
|
* ```typescript
|
|
4754
|
-
* import {
|
|
5563
|
+
* import { isPointInCachedBounds } from 'blecsd';
|
|
4755
5564
|
*
|
|
4756
|
-
* //
|
|
4757
|
-
*
|
|
4758
|
-
*
|
|
5565
|
+
* // Efficient hit testing using cached positions
|
|
5566
|
+
* if (isPointInCachedBounds(world, entity, mouseX, mouseY)) {
|
|
5567
|
+
* // Point is inside the element's inner area
|
|
5568
|
+
* }
|
|
4759
5569
|
* ```
|
|
4760
5570
|
*/
|
|
4761
|
-
declare function
|
|
4762
|
-
x: number;
|
|
4763
|
-
y: number;
|
|
4764
|
-
};
|
|
5571
|
+
declare function isPointInCachedBounds(_world: World, eid: Entity, x: number, y: number): boolean;
|
|
4765
5572
|
|
|
4766
5573
|
/**
|
|
4767
5574
|
* Common ECS queries for filtering and selecting entities.
|
|
@@ -5079,140 +5886,548 @@ declare function getChildEntities(_world: World, parent: Entity): Entity[];
|
|
|
5079
5886
|
*
|
|
5080
5887
|
* @example
|
|
5081
5888
|
* ```typescript
|
|
5082
|
-
* import { createWorld, createBoxEntity, getDescendantEntities } from 'blecsd';
|
|
5889
|
+
* import { createWorld, createBoxEntity, getDescendantEntities } from 'blecsd';
|
|
5890
|
+
*
|
|
5891
|
+
* const world = createWorld();
|
|
5892
|
+
* const root = createBoxEntity(world, { x: 0, y: 0 });
|
|
5893
|
+
* const child = createBoxEntity(world, { parent: root, x: 1, y: 1 });
|
|
5894
|
+
* const grandchild = createBoxEntity(world, { parent: child, x: 2, y: 2 });
|
|
5895
|
+
*
|
|
5896
|
+
* const descendants = getDescendantEntities(world, root);
|
|
5897
|
+
* // descendants = [child, grandchild]
|
|
5898
|
+
* ```
|
|
5899
|
+
*/
|
|
5900
|
+
declare function getDescendantEntities(world: World, parent: Entity): Entity[];
|
|
5901
|
+
/**
|
|
5902
|
+
* Gets all root entities (entities with no parent).
|
|
5903
|
+
*
|
|
5904
|
+
* Filters queryHierarchy to entities where parent === 0 (NULL_ENTITY).
|
|
5905
|
+
*
|
|
5906
|
+
* @param world - The ECS world
|
|
5907
|
+
* @returns Array of root entity IDs
|
|
5908
|
+
*
|
|
5909
|
+
* @example
|
|
5910
|
+
* ```typescript
|
|
5911
|
+
* import { createWorld, createBoxEntity, getRootEntities } from 'blecsd';
|
|
5912
|
+
*
|
|
5913
|
+
* const world = createWorld();
|
|
5914
|
+
* const root1 = createBoxEntity(world, { x: 0, y: 0 });
|
|
5915
|
+
* const root2 = createBoxEntity(world, { x: 10, y: 0 });
|
|
5916
|
+
* const child = createBoxEntity(world, { parent: root1, x: 1, y: 1 });
|
|
5917
|
+
*
|
|
5918
|
+
* const roots = getRootEntities(world);
|
|
5919
|
+
* // roots = [root1, root2]
|
|
5920
|
+
* ```
|
|
5921
|
+
*/
|
|
5922
|
+
declare function getRootEntities(world: World): Entity[];
|
|
5923
|
+
/**
|
|
5924
|
+
* Filters entities to only those that are focusable and enabled.
|
|
5925
|
+
*
|
|
5926
|
+
* Returns entities where Focusable.focusable === 1.
|
|
5927
|
+
*
|
|
5928
|
+
* @param world - The ECS world
|
|
5929
|
+
* @param entities - Array of entity IDs to filter
|
|
5930
|
+
* @returns Filtered array of focusable entity IDs
|
|
5931
|
+
*
|
|
5932
|
+
* @example
|
|
5933
|
+
* ```typescript
|
|
5934
|
+
* import { createWorld, queryFocusable, filterFocusable } from 'blecsd';
|
|
5935
|
+
*
|
|
5936
|
+
* const world = createWorld();
|
|
5937
|
+
* // ... create focusable entities, some disabled ...
|
|
5938
|
+
*
|
|
5939
|
+
* const allFocusables = queryFocusable(world);
|
|
5940
|
+
* const enabledFocusables = filterFocusable(world, allFocusables);
|
|
5941
|
+
*
|
|
5942
|
+
* for (const eid of enabledFocusables) {
|
|
5943
|
+
* // Process only enabled focusable entities
|
|
5944
|
+
* }
|
|
5945
|
+
* ```
|
|
5946
|
+
*/
|
|
5947
|
+
declare function filterFocusable(_world: World, entities: readonly Entity[]): Entity[];
|
|
5948
|
+
/**
|
|
5949
|
+
* Filters entities to only those that are clickable.
|
|
5950
|
+
*
|
|
5951
|
+
* Returns entities where Interactive.clickable === 1.
|
|
5952
|
+
*
|
|
5953
|
+
* @param world - The ECS world
|
|
5954
|
+
* @param entities - Array of entity IDs to filter
|
|
5955
|
+
* @returns Filtered array of clickable entity IDs
|
|
5956
|
+
*
|
|
5957
|
+
* @example
|
|
5958
|
+
* ```typescript
|
|
5959
|
+
* import { createWorld, queryInteractive, filterClickable } from 'blecsd';
|
|
5960
|
+
*
|
|
5961
|
+
* const world = createWorld();
|
|
5962
|
+
* // ... create interactive entities ...
|
|
5963
|
+
*
|
|
5964
|
+
* const allInteractives = queryInteractive(world);
|
|
5965
|
+
* const clickables = filterClickable(world, allInteractives);
|
|
5966
|
+
*
|
|
5967
|
+
* for (const eid of clickables) {
|
|
5968
|
+
* // Process only clickable entities
|
|
5969
|
+
* }
|
|
5970
|
+
* ```
|
|
5971
|
+
*/
|
|
5972
|
+
declare function filterClickable(_world: World, entities: readonly Entity[]): Entity[];
|
|
5973
|
+
/**
|
|
5974
|
+
* Sorts entities by tab index for focus navigation.
|
|
5975
|
+
*
|
|
5976
|
+
* Entities with lower tabIndex are focused first. Entities with tabIndex 0
|
|
5977
|
+
* follow DOM-like ordering.
|
|
5978
|
+
*
|
|
5979
|
+
* @param world - The ECS world
|
|
5980
|
+
* @param entities - Array of entity IDs to sort
|
|
5981
|
+
* @returns New array of entity IDs sorted by tab index
|
|
5982
|
+
*
|
|
5983
|
+
* @example
|
|
5984
|
+
* ```typescript
|
|
5985
|
+
* import { createWorld, queryFocusable, sortByTabIndex, filterFocusable } from 'blecsd';
|
|
5986
|
+
*
|
|
5987
|
+
* const world = createWorld();
|
|
5988
|
+
* // ... create focusable entities with different tab indices ...
|
|
5989
|
+
*
|
|
5990
|
+
* const focusables = queryFocusable(world);
|
|
5991
|
+
* const enabled = filterFocusable(world, focusables);
|
|
5992
|
+
* const tabOrder = sortByTabIndex(world, enabled);
|
|
5993
|
+
*
|
|
5994
|
+
* // tabOrder is now in correct focus navigation order
|
|
5995
|
+
* ```
|
|
5996
|
+
*/
|
|
5997
|
+
declare function sortByTabIndex(_world: World, entities: readonly Entity[]): Entity[];
|
|
5998
|
+
/**
|
|
5999
|
+
* Sorts entities by depth in the hierarchy (ancestors first).
|
|
6000
|
+
*
|
|
6001
|
+
* Useful for processing entities in parent-to-child order.
|
|
6002
|
+
*
|
|
6003
|
+
* @param world - The ECS world
|
|
6004
|
+
* @param entities - Array of entity IDs to sort
|
|
6005
|
+
* @returns New array of entity IDs sorted by depth (ascending)
|
|
6006
|
+
*
|
|
6007
|
+
* @example
|
|
6008
|
+
* ```typescript
|
|
6009
|
+
* import { createWorld, queryHierarchy, sortByDepth } from 'blecsd';
|
|
6010
|
+
*
|
|
6011
|
+
* const world = createWorld();
|
|
6012
|
+
* // ... create hierarchical entities ...
|
|
6013
|
+
*
|
|
6014
|
+
* const hierarchical = queryHierarchy(world);
|
|
6015
|
+
* const topDown = sortByDepth(world, hierarchical);
|
|
6016
|
+
*
|
|
6017
|
+
* for (const eid of topDown) {
|
|
6018
|
+
* // Process parent before children
|
|
6019
|
+
* }
|
|
6020
|
+
* ```
|
|
6021
|
+
*/
|
|
6022
|
+
declare function sortByDepth(_world: World, entities: readonly Entity[]): Entity[];
|
|
6023
|
+
|
|
6024
|
+
/**
|
|
6025
|
+
* Reactive effect system for blECSd.
|
|
6026
|
+
* Effects automatically re-run when their dependencies change.
|
|
6027
|
+
*
|
|
6028
|
+
* @module core/reactiveEffects
|
|
6029
|
+
*/
|
|
6030
|
+
|
|
6031
|
+
/**
|
|
6032
|
+
* Effect handle for disposal.
|
|
6033
|
+
*/
|
|
6034
|
+
interface EffectHandle {
|
|
6035
|
+
readonly dispose: () => void;
|
|
6036
|
+
}
|
|
6037
|
+
/**
|
|
6038
|
+
* Effect function that may optionally return a cleanup function.
|
|
6039
|
+
* The function can return nothing (void/undefined) or a cleanup function.
|
|
6040
|
+
*/
|
|
6041
|
+
type EffectFunction = () => unknown;
|
|
6042
|
+
/**
|
|
6043
|
+
* Creates an immediate effect that runs when dependencies change.
|
|
6044
|
+
* The effect runs immediately on creation and re-runs whenever any signal
|
|
6045
|
+
* read inside the effect changes.
|
|
6046
|
+
*
|
|
6047
|
+
* @param fn - Effect function to run
|
|
6048
|
+
* @returns Effect handle for disposal
|
|
6049
|
+
*
|
|
6050
|
+
* @example
|
|
6051
|
+
* ```typescript
|
|
6052
|
+
* import { createSignal, createEffect } from 'blecsd';
|
|
6053
|
+
*
|
|
6054
|
+
* const [count, setCount] = createSignal(0);
|
|
6055
|
+
*
|
|
6056
|
+
* const effect = createEffect(() => {
|
|
6057
|
+
* console.log(`Count is now: ${count()}`);
|
|
6058
|
+
* return () => console.log('Cleaning up effect');
|
|
6059
|
+
* });
|
|
6060
|
+
*
|
|
6061
|
+
* setCount(5); // Logs: "Cleaning up effect", then "Count is now: 5"
|
|
6062
|
+
*
|
|
6063
|
+
* effect.dispose(); // Stop the effect
|
|
6064
|
+
* ```
|
|
6065
|
+
*/
|
|
6066
|
+
declare function createEffect(fn: EffectFunction): EffectHandle;
|
|
6067
|
+
/**
|
|
6068
|
+
* Creates a scheduled effect that defers execution to a specific ECS loop phase.
|
|
6069
|
+
* Unlike immediate effects, scheduled effects batch their updates and run during
|
|
6070
|
+
* the specified phase of the game loop.
|
|
6071
|
+
*
|
|
6072
|
+
* @param fn - Effect function to run
|
|
6073
|
+
* @param phase - Loop phase to run in (default: LATE_UPDATE)
|
|
6074
|
+
* @returns Effect handle for disposal
|
|
6075
|
+
*
|
|
6076
|
+
* @example
|
|
6077
|
+
* ```typescript
|
|
6078
|
+
* import { createSignal, createScheduledEffect, LoopPhase } from 'blecsd';
|
|
6079
|
+
*
|
|
6080
|
+
* const [position, setPosition] = createSignal({ x: 0, y: 0 });
|
|
6081
|
+
*
|
|
6082
|
+
* // Effect runs during LAYOUT phase
|
|
6083
|
+
* const effect = createScheduledEffect(() => {
|
|
6084
|
+
* const pos = position();
|
|
6085
|
+
* console.log(`Position updated: ${pos.x}, ${pos.y}`);
|
|
6086
|
+
* }, LoopPhase.LAYOUT);
|
|
6087
|
+
*
|
|
6088
|
+
* setPosition({ x: 10, y: 20 }); // Marked dirty, waits for LAYOUT phase
|
|
6089
|
+
*
|
|
6090
|
+
* effect.dispose(); // Stop the effect
|
|
6091
|
+
* ```
|
|
6092
|
+
*/
|
|
6093
|
+
declare function createScheduledEffect(fn: EffectFunction, phase?: LoopPhase): EffectHandle;
|
|
6094
|
+
/**
|
|
6095
|
+
* Disposes an effect, stopping it from running and cleaning up.
|
|
6096
|
+
* This is a convenience function equivalent to calling effect.dispose().
|
|
6097
|
+
*
|
|
6098
|
+
* @param handle - Effect handle to dispose
|
|
6099
|
+
*
|
|
6100
|
+
* @example
|
|
6101
|
+
* ```typescript
|
|
6102
|
+
* import { createEffect, disposeEffect } from 'blecsd';
|
|
6103
|
+
*
|
|
6104
|
+
* const effect = createEffect(() => {
|
|
6105
|
+
* console.log('Effect running');
|
|
6106
|
+
* });
|
|
6107
|
+
*
|
|
6108
|
+
* disposeEffect(effect); // Same as effect.dispose()
|
|
6109
|
+
* ```
|
|
6110
|
+
*/
|
|
6111
|
+
declare function disposeEffect(handle: EffectHandle): void;
|
|
6112
|
+
/**
|
|
6113
|
+
* Flushes all scheduled effects for a specific phase.
|
|
6114
|
+
* This is called by the reactive system during each loop phase.
|
|
6115
|
+
*
|
|
6116
|
+
* @param phase - Loop phase to flush effects for
|
|
6117
|
+
* @internal
|
|
6118
|
+
*/
|
|
6119
|
+
declare function flushScheduledEffects(phase: LoopPhase): void;
|
|
6120
|
+
/**
|
|
6121
|
+
* Gets the count of scheduled effects for a specific phase.
|
|
6122
|
+
* Useful for debugging and testing.
|
|
6123
|
+
*
|
|
6124
|
+
* @param phase - Loop phase to count effects for
|
|
6125
|
+
* @returns Number of scheduled effects in the phase
|
|
6126
|
+
*
|
|
6127
|
+
* @example
|
|
6128
|
+
* ```typescript
|
|
6129
|
+
* import { createScheduledEffect, getScheduledEffectCount, LoopPhase } from 'blecsd';
|
|
6130
|
+
*
|
|
6131
|
+
* createScheduledEffect(() => {}, LoopPhase.UPDATE);
|
|
6132
|
+
* createScheduledEffect(() => {}, LoopPhase.UPDATE);
|
|
6133
|
+
*
|
|
6134
|
+
* console.log(getScheduledEffectCount(LoopPhase.UPDATE)); // 2
|
|
6135
|
+
* ```
|
|
6136
|
+
*/
|
|
6137
|
+
declare function getScheduledEffectCount(phase: LoopPhase): number;
|
|
6138
|
+
/**
|
|
6139
|
+
* Gets the total count of all scheduled effects across all phases.
|
|
6140
|
+
*
|
|
6141
|
+
* @returns Total number of scheduled effects
|
|
6142
|
+
*
|
|
6143
|
+
* @example
|
|
6144
|
+
* ```typescript
|
|
6145
|
+
* import { createScheduledEffect, getTotalScheduledEffectCount, LoopPhase } from 'blecsd';
|
|
6146
|
+
*
|
|
6147
|
+
* createScheduledEffect(() => {}, LoopPhase.UPDATE);
|
|
6148
|
+
* createScheduledEffect(() => {}, LoopPhase.RENDER);
|
|
6149
|
+
*
|
|
6150
|
+
* console.log(getTotalScheduledEffectCount()); // 2
|
|
6151
|
+
* ```
|
|
6152
|
+
*/
|
|
6153
|
+
declare function getTotalScheduledEffectCount(): number;
|
|
6154
|
+
|
|
6155
|
+
/**
|
|
6156
|
+
* Reactive data source adapters for blECSd.
|
|
6157
|
+
* Provides signal-based wrappers for common data sources like intervals, timers, and reducers.
|
|
6158
|
+
*
|
|
6159
|
+
* @module core/reactiveSource
|
|
6160
|
+
*/
|
|
6161
|
+
|
|
6162
|
+
/**
|
|
6163
|
+
* Dispose function for reactive sources.
|
|
6164
|
+
*/
|
|
6165
|
+
type Dispose = () => void;
|
|
6166
|
+
/**
|
|
6167
|
+
* Creates a signal that updates at a regular interval.
|
|
6168
|
+
* The signal value is computed by calling the provided function.
|
|
6169
|
+
*
|
|
6170
|
+
* @param fn - Function to call on each interval
|
|
6171
|
+
* @param intervalMs - Interval in milliseconds
|
|
6172
|
+
* @returns Tuple of [getter, dispose]
|
|
6173
|
+
*
|
|
6174
|
+
* @example
|
|
6175
|
+
* ```typescript
|
|
6176
|
+
* import { createIntervalSignal } from 'blecsd';
|
|
6177
|
+
*
|
|
6178
|
+
* const [time, dispose] = createIntervalSignal(() => Date.now(), 1000);
|
|
6179
|
+
*
|
|
6180
|
+
* console.log(time()); // Current timestamp
|
|
6181
|
+
* // ... wait 1 second ...
|
|
6182
|
+
* console.log(time()); // Updated timestamp
|
|
6183
|
+
*
|
|
6184
|
+
* dispose(); // Stop the interval
|
|
6185
|
+
* ```
|
|
6186
|
+
*/
|
|
6187
|
+
declare function createIntervalSignal<T>(fn: () => T, intervalMs: number): [SignalGetter<T>, Dispose];
|
|
6188
|
+
/**
|
|
6189
|
+
* Creates a signal that tracks elapsed time as a progress value from 0 to 1.
|
|
6190
|
+
* Useful for animations, countdowns, and timed transitions.
|
|
6191
|
+
*
|
|
6192
|
+
* @param durationMs - Duration in milliseconds
|
|
6193
|
+
* @returns Tuple of [progress getter (0-1), dispose]
|
|
6194
|
+
*
|
|
6195
|
+
* @example
|
|
6196
|
+
* ```typescript
|
|
6197
|
+
* import { createTimerSignal } from 'blecsd';
|
|
6198
|
+
*
|
|
6199
|
+
* const [progress, dispose] = createTimerSignal(5000); // 5 second timer
|
|
6200
|
+
*
|
|
6201
|
+
* console.log(progress()); // 0.0
|
|
6202
|
+
* // ... wait 2.5 seconds ...
|
|
6203
|
+
* console.log(progress()); // ~0.5
|
|
6204
|
+
* // ... wait 2.5 more seconds ...
|
|
6205
|
+
* console.log(progress()); // 1.0
|
|
6206
|
+
*
|
|
6207
|
+
* dispose(); // Stop the timer
|
|
6208
|
+
* ```
|
|
6209
|
+
*/
|
|
6210
|
+
declare function createTimerSignal(durationMs: number): [SignalGetter<number>, Dispose];
|
|
6211
|
+
/**
|
|
6212
|
+
* Dispatch function for reducer signal.
|
|
6213
|
+
*/
|
|
6214
|
+
type Dispatch<A> = (action: A) => void;
|
|
6215
|
+
/**
|
|
6216
|
+
* Reducer function type.
|
|
6217
|
+
*/
|
|
6218
|
+
type Reducer<T, A> = (state: T, action: A) => T;
|
|
6219
|
+
/**
|
|
6220
|
+
* Creates a signal with a reducer-style update pattern.
|
|
6221
|
+
* Similar to React's useReducer, but as a reactive signal.
|
|
6222
|
+
*
|
|
6223
|
+
* @param reducer - Reducer function (state, action) => newState
|
|
6224
|
+
* @param initial - Initial state value
|
|
6225
|
+
* @returns Tuple of [getter, dispatch]
|
|
6226
|
+
*
|
|
6227
|
+
* @example
|
|
6228
|
+
* ```typescript
|
|
6229
|
+
* import { createReducerSignal } from 'blecsd';
|
|
5083
6230
|
*
|
|
5084
|
-
*
|
|
5085
|
-
* const root = createBoxEntity(world, { x: 0, y: 0 });
|
|
5086
|
-
* const child = createBoxEntity(world, { parent: root, x: 1, y: 1 });
|
|
5087
|
-
* const grandchild = createBoxEntity(world, { parent: child, x: 2, y: 2 });
|
|
6231
|
+
* type CounterAction = { type: 'increment' } | { type: 'decrement' } | { type: 'reset' };
|
|
5088
6232
|
*
|
|
5089
|
-
* const
|
|
5090
|
-
*
|
|
6233
|
+
* const [count, dispatch] = createReducerSignal<number, CounterAction>(
|
|
6234
|
+
* (state, action) => {
|
|
6235
|
+
* switch (action.type) {
|
|
6236
|
+
* case 'increment': return state + 1;
|
|
6237
|
+
* case 'decrement': return state - 1;
|
|
6238
|
+
* case 'reset': return 0;
|
|
6239
|
+
* }
|
|
6240
|
+
* },
|
|
6241
|
+
* 0
|
|
6242
|
+
* );
|
|
6243
|
+
*
|
|
6244
|
+
* console.log(count()); // 0
|
|
6245
|
+
* dispatch({ type: 'increment' });
|
|
6246
|
+
* console.log(count()); // 1
|
|
6247
|
+
* dispatch({ type: 'increment' });
|
|
6248
|
+
* console.log(count()); // 2
|
|
6249
|
+
* dispatch({ type: 'reset' });
|
|
6250
|
+
* console.log(count()); // 0
|
|
5091
6251
|
* ```
|
|
5092
6252
|
*/
|
|
5093
|
-
declare function
|
|
6253
|
+
declare function createReducerSignal<T, A>(reducer: Reducer<T, A>, initial: T): [SignalGetter<T>, Dispatch<A>];
|
|
5094
6254
|
/**
|
|
5095
|
-
*
|
|
5096
|
-
|
|
5097
|
-
|
|
6255
|
+
* Combiner function type for derived signals.
|
|
6256
|
+
*/
|
|
6257
|
+
type Combiner<T, R> = (...values: T[]) => R;
|
|
6258
|
+
/**
|
|
6259
|
+
* Creates a derived signal that combines multiple signal values.
|
|
6260
|
+
* The combiner function is called whenever any input signal changes.
|
|
5098
6261
|
*
|
|
5099
|
-
* @param
|
|
5100
|
-
* @
|
|
6262
|
+
* @param signals - Array of signal getters to combine
|
|
6263
|
+
* @param combiner - Function to combine signal values
|
|
6264
|
+
* @returns Computed signal with combined value
|
|
5101
6265
|
*
|
|
5102
6266
|
* @example
|
|
5103
6267
|
* ```typescript
|
|
5104
|
-
* import {
|
|
6268
|
+
* import { createSignal, createDerivedSignal } from 'blecsd';
|
|
5105
6269
|
*
|
|
5106
|
-
* const
|
|
5107
|
-
* const
|
|
5108
|
-
* const root2 = createBoxEntity(world, { x: 10, y: 0 });
|
|
5109
|
-
* const child = createBoxEntity(world, { parent: root1, x: 1, y: 1 });
|
|
6270
|
+
* const [firstName, setFirstName] = createSignal('John');
|
|
6271
|
+
* const [lastName, setLastName] = createSignal('Doe');
|
|
5110
6272
|
*
|
|
5111
|
-
* const
|
|
5112
|
-
*
|
|
6273
|
+
* const fullName = createDerivedSignal(
|
|
6274
|
+
* [firstName, lastName],
|
|
6275
|
+
* (first, last) => `${first} ${last}`
|
|
6276
|
+
* );
|
|
6277
|
+
*
|
|
6278
|
+
* console.log(fullName()); // "John Doe"
|
|
6279
|
+
* setFirstName('Jane');
|
|
6280
|
+
* console.log(fullName()); // "Jane Doe"
|
|
5113
6281
|
* ```
|
|
5114
6282
|
*/
|
|
5115
|
-
declare function
|
|
6283
|
+
declare function createDerivedSignal<T, R>(signals: ReadonlyArray<SignalGetter<T>>, combiner: Combiner<T, R>): ComputedSignal<R>;
|
|
5116
6284
|
/**
|
|
5117
|
-
*
|
|
5118
|
-
|
|
5119
|
-
|
|
6285
|
+
* Minimal interface for a readable stream.
|
|
6286
|
+
*/
|
|
6287
|
+
interface ReadableStream {
|
|
6288
|
+
on(event: string, listener: (...args: unknown[]) => void): void;
|
|
6289
|
+
removeListener(event: string, listener: (...args: unknown[]) => void): void;
|
|
6290
|
+
destroy?(): void;
|
|
6291
|
+
}
|
|
6292
|
+
/**
|
|
6293
|
+
* Options for stream signal creation.
|
|
6294
|
+
*/
|
|
6295
|
+
interface StreamSignalOptions<T> {
|
|
6296
|
+
/**
|
|
6297
|
+
* Transform function to convert Buffer chunks to signal values.
|
|
6298
|
+
* Defaults to converting Buffer to string.
|
|
6299
|
+
*/
|
|
6300
|
+
transform?: (chunk: Buffer) => T;
|
|
6301
|
+
/**
|
|
6302
|
+
* Initial value for the signal.
|
|
6303
|
+
*/
|
|
6304
|
+
initialValue: T;
|
|
6305
|
+
/**
|
|
6306
|
+
* Whether to destroy the stream on dispose. Defaults to false.
|
|
6307
|
+
*/
|
|
6308
|
+
destroyOnDispose?: boolean;
|
|
6309
|
+
}
|
|
6310
|
+
/**
|
|
6311
|
+
* Creates a signal from a Node.js Readable stream.
|
|
6312
|
+
* Updates on each 'data' event with the transformed chunk value.
|
|
5120
6313
|
*
|
|
5121
|
-
* @param
|
|
5122
|
-
* @param
|
|
5123
|
-
* @returns
|
|
6314
|
+
* @param readable - A readable stream (Node.js Readable or compatible)
|
|
6315
|
+
* @param options - Stream signal options
|
|
6316
|
+
* @returns Tuple of [getter, dispose]
|
|
5124
6317
|
*
|
|
5125
6318
|
* @example
|
|
5126
6319
|
* ```typescript
|
|
5127
|
-
* import {
|
|
6320
|
+
* import { createStreamSignal } from 'blecsd';
|
|
6321
|
+
* import { createReadStream } from 'fs';
|
|
5128
6322
|
*
|
|
5129
|
-
* const
|
|
5130
|
-
*
|
|
6323
|
+
* const stream = createReadStream('./data.txt', { encoding: 'utf8' });
|
|
6324
|
+
* const [data, dispose] = createStreamSignal(stream, {
|
|
6325
|
+
* initialValue: '',
|
|
6326
|
+
* transform: (chunk) => chunk.toString('utf8')
|
|
6327
|
+
* });
|
|
5131
6328
|
*
|
|
5132
|
-
*
|
|
5133
|
-
* const enabledFocusables = filterFocusable(world, allFocusables);
|
|
6329
|
+
* console.log(data()); // Latest chunk from stream
|
|
5134
6330
|
*
|
|
5135
|
-
*
|
|
5136
|
-
* // Process only enabled focusable entities
|
|
5137
|
-
* }
|
|
6331
|
+
* dispose(); // Clean up listeners
|
|
5138
6332
|
* ```
|
|
5139
6333
|
*/
|
|
5140
|
-
declare function
|
|
6334
|
+
declare function createStreamSignal<T>(readable: ReadableStream, options: StreamSignalOptions<T>): [SignalGetter<T>, Dispose];
|
|
5141
6335
|
/**
|
|
5142
|
-
*
|
|
5143
|
-
*
|
|
5144
|
-
|
|
6336
|
+
* Subscribe function type for callback signal.
|
|
6337
|
+
* Takes a callback and returns an unsubscribe function.
|
|
6338
|
+
*/
|
|
6339
|
+
type Subscribe<T> = (callback: (value: T) => void) => () => void;
|
|
6340
|
+
/**
|
|
6341
|
+
* Creates a signal from a generic subscribe/unsubscribe pattern.
|
|
6342
|
+
* This is a universal adapter for WebSocket, EventEmitter, and other callback-based sources.
|
|
5145
6343
|
*
|
|
5146
|
-
* @param
|
|
5147
|
-
* @param
|
|
5148
|
-
* @returns
|
|
6344
|
+
* @param subscribe - Function that takes a callback and returns an unsubscribe function
|
|
6345
|
+
* @param initialValue - Initial value for the signal
|
|
6346
|
+
* @returns Tuple of [getter, dispose]
|
|
5149
6347
|
*
|
|
5150
6348
|
* @example
|
|
5151
6349
|
* ```typescript
|
|
5152
|
-
* import {
|
|
6350
|
+
* import { createCallbackSignal } from 'blecsd';
|
|
5153
6351
|
*
|
|
5154
|
-
*
|
|
5155
|
-
*
|
|
6352
|
+
* // WebSocket example
|
|
6353
|
+
* const ws = new WebSocket('ws://localhost:8080');
|
|
6354
|
+
* const [message, dispose] = createCallbackSignal<string>(
|
|
6355
|
+
* (callback) => {
|
|
6356
|
+
* const handler = (event: MessageEvent) => callback(event.data);
|
|
6357
|
+
* ws.addEventListener('message', handler);
|
|
6358
|
+
* return () => ws.removeEventListener('message', handler);
|
|
6359
|
+
* },
|
|
6360
|
+
* ''
|
|
6361
|
+
* );
|
|
5156
6362
|
*
|
|
5157
|
-
*
|
|
5158
|
-
* const clickables = filterClickable(world, allInteractives);
|
|
6363
|
+
* console.log(message()); // Latest WebSocket message
|
|
5159
6364
|
*
|
|
5160
|
-
*
|
|
5161
|
-
* // Process only clickable entities
|
|
5162
|
-
* }
|
|
6365
|
+
* dispose(); // Unsubscribe
|
|
5163
6366
|
* ```
|
|
5164
6367
|
*/
|
|
5165
|
-
declare function
|
|
6368
|
+
declare function createCallbackSignal<T>(subscribe: Subscribe<T>, initialValue: T): [SignalGetter<T>, Dispose];
|
|
5166
6369
|
/**
|
|
5167
|
-
*
|
|
5168
|
-
*
|
|
5169
|
-
* Entities with lower tabIndex are focused first. Entities with tabIndex 0
|
|
5170
|
-
* follow DOM-like ordering.
|
|
6370
|
+
* Creates a signal that polls an async function at regular intervals.
|
|
6371
|
+
* Handles promises and errors gracefully.
|
|
5171
6372
|
*
|
|
5172
|
-
* @param
|
|
5173
|
-
* @param
|
|
5174
|
-
* @
|
|
6373
|
+
* @param fn - Async function to poll
|
|
6374
|
+
* @param intervalMs - Polling interval in milliseconds
|
|
6375
|
+
* @param initialValue - Initial value for the signal
|
|
6376
|
+
* @returns Tuple of [getter, dispose]
|
|
5175
6377
|
*
|
|
5176
6378
|
* @example
|
|
5177
6379
|
* ```typescript
|
|
5178
|
-
* import {
|
|
6380
|
+
* import { createPollingSignal } from 'blecsd';
|
|
5179
6381
|
*
|
|
5180
|
-
* const
|
|
5181
|
-
*
|
|
6382
|
+
* const [apiData, dispose] = createPollingSignal(
|
|
6383
|
+
* async () => {
|
|
6384
|
+
* const response = await fetch('https://api.example.com/status');
|
|
6385
|
+
* return response.json();
|
|
6386
|
+
* },
|
|
6387
|
+
* 5000, // Poll every 5 seconds
|
|
6388
|
+
* { status: 'unknown' }
|
|
6389
|
+
* );
|
|
5182
6390
|
*
|
|
5183
|
-
*
|
|
5184
|
-
* const enabled = filterFocusable(world, focusables);
|
|
5185
|
-
* const tabOrder = sortByTabIndex(world, enabled);
|
|
6391
|
+
* console.log(apiData()); // Latest API response
|
|
5186
6392
|
*
|
|
5187
|
-
* //
|
|
6393
|
+
* dispose(); // Stop polling
|
|
5188
6394
|
* ```
|
|
5189
6395
|
*/
|
|
5190
|
-
declare function
|
|
6396
|
+
declare function createPollingSignal<T>(fn: () => Promise<T>, intervalMs: number, initialValue: T): [SignalGetter<T>, Dispose];
|
|
5191
6397
|
/**
|
|
5192
|
-
*
|
|
5193
|
-
|
|
5194
|
-
|
|
6398
|
+
* Minimal interface for an event emitter.
|
|
6399
|
+
*/
|
|
6400
|
+
interface EventEmitter {
|
|
6401
|
+
on(eventName: string, listener: (...args: unknown[]) => void): void;
|
|
6402
|
+
removeListener(eventName: string, listener: (...args: unknown[]) => void): void;
|
|
6403
|
+
}
|
|
6404
|
+
/**
|
|
6405
|
+
* Creates a signal from a Node.js EventEmitter event.
|
|
6406
|
+
* Updates whenever the specified event is emitted.
|
|
5195
6407
|
*
|
|
5196
|
-
* @param
|
|
5197
|
-
* @param
|
|
5198
|
-
* @
|
|
6408
|
+
* @param emitter - Event emitter instance
|
|
6409
|
+
* @param eventName - Name of the event to listen to
|
|
6410
|
+
* @param initialValue - Initial value for the signal (optional)
|
|
6411
|
+
* @returns Tuple of [getter, dispose]
|
|
5199
6412
|
*
|
|
5200
6413
|
* @example
|
|
5201
6414
|
* ```typescript
|
|
5202
|
-
* import {
|
|
6415
|
+
* import { createEventSignal } from 'blecsd';
|
|
6416
|
+
* import { EventEmitter } from 'events';
|
|
5203
6417
|
*
|
|
5204
|
-
* const
|
|
5205
|
-
*
|
|
6418
|
+
* const emitter = new EventEmitter();
|
|
6419
|
+
* const [message, dispose] = createEventSignal<string>(emitter, 'message', '');
|
|
5206
6420
|
*
|
|
5207
|
-
*
|
|
5208
|
-
*
|
|
6421
|
+
* emitter.emit('message', 'Hello');
|
|
6422
|
+
* console.log(message()); // "Hello"
|
|
5209
6423
|
*
|
|
5210
|
-
*
|
|
5211
|
-
*
|
|
5212
|
-
*
|
|
6424
|
+
* emitter.emit('message', 'World');
|
|
6425
|
+
* console.log(message()); // "World"
|
|
6426
|
+
*
|
|
6427
|
+
* dispose(); // Remove listener
|
|
5213
6428
|
* ```
|
|
5214
6429
|
*/
|
|
5215
|
-
declare function
|
|
6430
|
+
declare function createEventSignal<T>(emitter: EventEmitter, eventName: string, initialValue?: T): [SignalGetter<T | undefined>, Dispose];
|
|
5216
6431
|
|
|
5217
6432
|
/**
|
|
5218
6433
|
* Scene management for game screens.
|
|
@@ -5426,283 +6641,156 @@ declare function createSlideTransition(duration: number, direction: 'left' | 'ri
|
|
|
5426
6641
|
declare function createSceneSystem(sceneManager: SceneManager, getDelta: () => number): System;
|
|
5427
6642
|
|
|
5428
6643
|
/**
|
|
5429
|
-
* ECS world state serialization
|
|
5430
|
-
*
|
|
5431
|
-
* Provides functions to serialize ECS world state to JSON and restore it,
|
|
5432
|
-
* supporting component data, entity relationships, and custom serializers
|
|
5433
|
-
* for complex (non-typed-array) data.
|
|
5434
|
-
*
|
|
6644
|
+
* ECS world state serialization with delta compression
|
|
5435
6645
|
* @module core/serialization
|
|
5436
6646
|
*/
|
|
5437
6647
|
|
|
5438
6648
|
/**
|
|
5439
|
-
*
|
|
5440
|
-
*/
|
|
5441
|
-
interface ComponentDescriptor {
|
|
5442
|
-
/** Unique name for the component (used as key in serialized data) */
|
|
5443
|
-
readonly name: string;
|
|
5444
|
-
/** The component store object (SoA typed arrays) */
|
|
5445
|
-
readonly store: Record<string, any>;
|
|
5446
|
-
/** Optional custom serializer for non-typed-array data */
|
|
5447
|
-
readonly serialize?: (eid: Entity) => unknown;
|
|
5448
|
-
/** Optional custom deserializer for non-typed-array data */
|
|
5449
|
-
readonly deserialize?: (eid: Entity, data: unknown) => void;
|
|
5450
|
-
}
|
|
5451
|
-
/**
|
|
5452
|
-
* Serialized entity data.
|
|
6649
|
+
* Component field data - maps field names to their value arrays
|
|
5453
6650
|
*/
|
|
5454
|
-
interface
|
|
5455
|
-
|
|
5456
|
-
readonly id: number;
|
|
5457
|
-
/** Map of component name to serialized component data */
|
|
5458
|
-
readonly components: Record<string, SerializedComponentData>;
|
|
6651
|
+
interface ComponentFieldData {
|
|
6652
|
+
readonly [fieldName: string]: readonly number[];
|
|
5459
6653
|
}
|
|
5460
6654
|
/**
|
|
5461
|
-
* Serialized component data
|
|
6655
|
+
* Serialized component data
|
|
5462
6656
|
*/
|
|
5463
|
-
interface
|
|
5464
|
-
|
|
5465
|
-
readonly
|
|
5466
|
-
|
|
5467
|
-
readonly custom?: unknown;
|
|
6657
|
+
interface ComponentData {
|
|
6658
|
+
readonly name: string;
|
|
6659
|
+
readonly entities: readonly number[];
|
|
6660
|
+
readonly values: ComponentFieldData;
|
|
5468
6661
|
}
|
|
5469
6662
|
/**
|
|
5470
|
-
* Complete
|
|
6663
|
+
* Complete world snapshot
|
|
5471
6664
|
*/
|
|
5472
|
-
interface
|
|
5473
|
-
/** Version for forward compatibility */
|
|
6665
|
+
interface WorldSnapshot {
|
|
5474
6666
|
readonly version: number;
|
|
5475
|
-
/** Timestamp of serialization */
|
|
5476
6667
|
readonly timestamp: number;
|
|
5477
|
-
|
|
5478
|
-
readonly
|
|
5479
|
-
/** Optional metadata attached by user */
|
|
5480
|
-
readonly metadata?: Record<string, unknown> | undefined;
|
|
5481
|
-
}
|
|
5482
|
-
/**
|
|
5483
|
-
* Options for serialization.
|
|
5484
|
-
*/
|
|
5485
|
-
interface SerializeOptions {
|
|
5486
|
-
/** Only serialize entities with these IDs (default: all entities) */
|
|
5487
|
-
readonly entityFilter?: readonly Entity[] | undefined;
|
|
5488
|
-
/** Only serialize these components by name (default: all registered) */
|
|
5489
|
-
readonly componentFilter?: readonly string[] | undefined;
|
|
5490
|
-
/** Metadata to include in the snapshot */
|
|
5491
|
-
readonly metadata?: Record<string, unknown> | undefined;
|
|
6668
|
+
readonly entityCount: number;
|
|
6669
|
+
readonly components: readonly ComponentData[];
|
|
5492
6670
|
}
|
|
5493
6671
|
/**
|
|
5494
|
-
*
|
|
6672
|
+
* Delta between two world snapshots
|
|
5495
6673
|
*/
|
|
5496
|
-
interface
|
|
5497
|
-
|
|
5498
|
-
readonly
|
|
5499
|
-
|
|
5500
|
-
readonly
|
|
6674
|
+
interface WorldDelta {
|
|
6675
|
+
readonly baseTimestamp: number;
|
|
6676
|
+
readonly timestamp: number;
|
|
6677
|
+
readonly addedEntities: readonly number[];
|
|
6678
|
+
readonly removedEntities: readonly number[];
|
|
6679
|
+
readonly changedComponents: readonly ComponentData[];
|
|
5501
6680
|
}
|
|
5502
6681
|
/**
|
|
5503
|
-
*
|
|
6682
|
+
* Component registration for serialization
|
|
5504
6683
|
*/
|
|
5505
|
-
interface
|
|
5506
|
-
|
|
5507
|
-
readonly
|
|
5508
|
-
|
|
5509
|
-
readonly entityMap: ReadonlyMap<number, Entity>;
|
|
5510
|
-
/** Count of entities restored */
|
|
5511
|
-
readonly entityCount: number;
|
|
5512
|
-
/** Count of components restored */
|
|
5513
|
-
readonly componentCount: number;
|
|
6684
|
+
interface ComponentRegistration {
|
|
6685
|
+
readonly name: string;
|
|
6686
|
+
readonly component: any;
|
|
6687
|
+
readonly fields: readonly string[];
|
|
5514
6688
|
}
|
|
5515
6689
|
/**
|
|
5516
|
-
* Registers
|
|
5517
|
-
*
|
|
5518
|
-
* Components must be registered before they can be serialized or deserialized.
|
|
5519
|
-
* The descriptor tells the serializer how to read/write the component's data.
|
|
5520
|
-
*
|
|
5521
|
-
* @param descriptor - Component descriptor with name, store, and optional custom serializers
|
|
5522
|
-
*
|
|
5523
|
-
* @example
|
|
5524
|
-
* ```typescript
|
|
5525
|
-
* import { registerSerializable, Position } from 'blecsd';
|
|
5526
|
-
*
|
|
5527
|
-
* registerSerializable({
|
|
5528
|
-
* name: 'Position',
|
|
5529
|
-
* store: Position,
|
|
5530
|
-
* });
|
|
5531
|
-
* ```
|
|
5532
|
-
*/
|
|
5533
|
-
declare function registerSerializable(descriptor: ComponentDescriptor): void;
|
|
5534
|
-
/**
|
|
5535
|
-
* Unregisters a component from serialization.
|
|
5536
|
-
*
|
|
5537
|
-
* @param name - The component name to unregister
|
|
5538
|
-
* @returns True if the component was found and removed
|
|
5539
|
-
*
|
|
5540
|
-
* @example
|
|
5541
|
-
* ```typescript
|
|
5542
|
-
* import { unregisterSerializable } from 'blecsd';
|
|
5543
|
-
*
|
|
5544
|
-
* unregisterSerializable('Position');
|
|
5545
|
-
* ```
|
|
5546
|
-
*/
|
|
5547
|
-
declare function unregisterSerializable(name: string): boolean;
|
|
5548
|
-
/**
|
|
5549
|
-
* Gets a registered component descriptor by name.
|
|
6690
|
+
* Registers components for serialization.
|
|
6691
|
+
* Must be called before serializing/deserializing world state.
|
|
5550
6692
|
*
|
|
5551
|
-
* @param
|
|
5552
|
-
* @returns The descriptor, or undefined if not registered
|
|
6693
|
+
* @param registrations - Array of component registrations
|
|
5553
6694
|
*
|
|
5554
6695
|
* @example
|
|
5555
6696
|
* ```typescript
|
|
5556
|
-
* import {
|
|
6697
|
+
* import { registerComponents, Position, Velocity } from 'blecsd';
|
|
5557
6698
|
*
|
|
5558
|
-
*
|
|
5559
|
-
*
|
|
5560
|
-
*
|
|
5561
|
-
*
|
|
6699
|
+
* registerComponents([
|
|
6700
|
+
* { name: 'Position', component: Position, fields: ['x', 'y', 'z', 'absolute'] },
|
|
6701
|
+
* { name: 'Velocity', component: Velocity, fields: ['x', 'y', 'maxSpeed', 'friction'] },
|
|
6702
|
+
* ]);
|
|
5562
6703
|
* ```
|
|
5563
6704
|
*/
|
|
5564
|
-
declare function
|
|
6705
|
+
declare function registerComponents(registrations: readonly ComponentRegistration[]): void;
|
|
5565
6706
|
/**
|
|
5566
|
-
* Gets
|
|
6707
|
+
* Gets the currently registered components.
|
|
5567
6708
|
*
|
|
5568
|
-
* @returns Array of
|
|
6709
|
+
* @returns Array of component registrations
|
|
5569
6710
|
*
|
|
5570
6711
|
* @example
|
|
5571
6712
|
* ```typescript
|
|
5572
6713
|
* import { getRegisteredComponents } from 'blecsd';
|
|
5573
6714
|
*
|
|
5574
|
-
* const
|
|
5575
|
-
* console.log(
|
|
5576
|
-
* ```
|
|
5577
|
-
*/
|
|
5578
|
-
declare function getRegisteredComponents(): readonly string[];
|
|
5579
|
-
/**
|
|
5580
|
-
* Clears all registered serializable components.
|
|
5581
|
-
* Useful for testing.
|
|
5582
|
-
*
|
|
5583
|
-
* @example
|
|
5584
|
-
* ```typescript
|
|
5585
|
-
* import { clearSerializableRegistry } from 'blecsd';
|
|
5586
|
-
*
|
|
5587
|
-
* clearSerializableRegistry();
|
|
5588
|
-
* ```
|
|
5589
|
-
*/
|
|
5590
|
-
declare function clearSerializableRegistry(): void;
|
|
5591
|
-
/**
|
|
5592
|
-
* Serializes ECS world state to a snapshot object.
|
|
5593
|
-
*
|
|
5594
|
-
* Only components registered via `registerSerializable` are included.
|
|
5595
|
-
* The snapshot can be converted to JSON with `JSON.stringify`.
|
|
5596
|
-
*
|
|
5597
|
-
* @param world - The world to serialize
|
|
5598
|
-
* @param options - Optional serialization options
|
|
5599
|
-
* @returns A serialized world snapshot
|
|
5600
|
-
*
|
|
5601
|
-
* @example
|
|
5602
|
-
* ```typescript
|
|
5603
|
-
* import { createWorld, addEntity, setPosition, serializeWorld, registerSerializable, Position } from 'blecsd';
|
|
5604
|
-
*
|
|
5605
|
-
* registerSerializable({ name: 'Position', store: Position });
|
|
5606
|
-
*
|
|
5607
|
-
* const world = createWorld();
|
|
5608
|
-
* const eid = addEntity(world);
|
|
5609
|
-
* setPosition(world, eid, 10, 20);
|
|
5610
|
-
*
|
|
5611
|
-
* const snapshot = serializeWorld(world);
|
|
5612
|
-
* const json = JSON.stringify(snapshot);
|
|
6715
|
+
* const components = getRegisteredComponents();
|
|
6716
|
+
* console.log(components.map(c => c.name));
|
|
5613
6717
|
* ```
|
|
5614
6718
|
*/
|
|
5615
|
-
declare function
|
|
6719
|
+
declare function getRegisteredComponents(): readonly ComponentRegistration[];
|
|
5616
6720
|
/**
|
|
5617
|
-
* Serializes
|
|
6721
|
+
* Serializes a world to a snapshot.
|
|
5618
6722
|
*
|
|
5619
|
-
*
|
|
5620
|
-
*
|
|
5621
|
-
* @
|
|
5622
|
-
* @param options - Optional serialization options
|
|
5623
|
-
* @returns JSON string of the world state
|
|
6723
|
+
* @param world - The ECS world to serialize
|
|
6724
|
+
* @param components - Array of component registrations to serialize
|
|
6725
|
+
* @returns World snapshot
|
|
5624
6726
|
*
|
|
5625
6727
|
* @example
|
|
5626
6728
|
* ```typescript
|
|
5627
|
-
* import { createWorld, addEntity, setPosition,
|
|
5628
|
-
*
|
|
5629
|
-
* registerSerializable({ name: 'Position', store: Position });
|
|
6729
|
+
* import { createWorld, addEntity, setPosition, serializeWorld } from 'blecsd';
|
|
5630
6730
|
*
|
|
5631
6731
|
* const world = createWorld();
|
|
5632
|
-
* const
|
|
5633
|
-
* setPosition(world,
|
|
6732
|
+
* const entity = addEntity(world);
|
|
6733
|
+
* setPosition(world, entity, 10, 5);
|
|
5634
6734
|
*
|
|
5635
|
-
* const
|
|
5636
|
-
*
|
|
6735
|
+
* const snapshot = serializeWorld(world, [
|
|
6736
|
+
* { name: 'Position', component: Position, fields: ['x', 'y', 'z', 'absolute'] },
|
|
6737
|
+
* ]);
|
|
5637
6738
|
* ```
|
|
5638
6739
|
*/
|
|
5639
|
-
declare function
|
|
6740
|
+
declare function serializeWorld(world: World, components: readonly ComponentRegistration[]): WorldSnapshot;
|
|
5640
6741
|
/**
|
|
5641
|
-
* Deserializes a
|
|
5642
|
-
*
|
|
5643
|
-
* Creates new entities and restores their component data from the snapshot.
|
|
5644
|
-
* Returns a mapping from old entity IDs to new ones for relationship fixup.
|
|
6742
|
+
* Deserializes a snapshot into a new world.
|
|
5645
6743
|
*
|
|
5646
|
-
* @param snapshot -
|
|
5647
|
-
* @
|
|
5648
|
-
* @param options - Optional deserialization options
|
|
5649
|
-
* @returns Result with the world, entity map, and statistics
|
|
6744
|
+
* @param snapshot - World snapshot to deserialize
|
|
6745
|
+
* @returns A new world with the snapshot data
|
|
5650
6746
|
*
|
|
5651
6747
|
* @example
|
|
5652
6748
|
* ```typescript
|
|
5653
|
-
* import {
|
|
5654
|
-
*
|
|
5655
|
-
* registerSerializable({ name: 'Position', store: Position });
|
|
5656
|
-
*
|
|
5657
|
-
* const world = createWorld();
|
|
5658
|
-
* const result = deserializeWorld(snapshot, world);
|
|
6749
|
+
* import { deserializeWorld, getAllEntities } from 'blecsd';
|
|
5659
6750
|
*
|
|
5660
|
-
*
|
|
5661
|
-
*
|
|
6751
|
+
* const world = deserializeWorld(snapshot);
|
|
6752
|
+
* const entities = getAllEntities(world);
|
|
6753
|
+
* console.log(`Restored ${entities.length} entities`);
|
|
5662
6754
|
* ```
|
|
5663
6755
|
*/
|
|
5664
|
-
declare function deserializeWorld(snapshot:
|
|
6756
|
+
declare function deserializeWorld(snapshot: WorldSnapshot): World;
|
|
5665
6757
|
/**
|
|
5666
|
-
*
|
|
6758
|
+
* Creates a delta between two snapshots.
|
|
5667
6759
|
*
|
|
5668
|
-
*
|
|
5669
|
-
*
|
|
5670
|
-
* @
|
|
5671
|
-
* @param world - The world to deserialize into
|
|
5672
|
-
* @param options - Optional deserialization options
|
|
5673
|
-
* @returns Result with the world, entity map, and statistics
|
|
6760
|
+
* @param prev - Previous snapshot
|
|
6761
|
+
* @param current - Current snapshot
|
|
6762
|
+
* @returns Delta containing changes between snapshots
|
|
5674
6763
|
*
|
|
5675
6764
|
* @example
|
|
5676
6765
|
* ```typescript
|
|
5677
|
-
* import {
|
|
5678
|
-
*
|
|
5679
|
-
* registerSerializable({ name: 'Position', store: Position });
|
|
6766
|
+
* import { serializeWorld, createWorldDelta } from 'blecsd';
|
|
5680
6767
|
*
|
|
5681
|
-
* const
|
|
5682
|
-
*
|
|
6768
|
+
* const snapshot1 = serializeWorld(world, components);
|
|
6769
|
+
* // ... modify world ...
|
|
6770
|
+
* const snapshot2 = serializeWorld(world, components);
|
|
5683
6771
|
*
|
|
5684
|
-
*
|
|
6772
|
+
* const delta = createWorldDelta(snapshot1, snapshot2);
|
|
6773
|
+
* console.log(`Added: ${delta.addedEntities.length}, Removed: ${delta.removedEntities.length}`);
|
|
5685
6774
|
* ```
|
|
5686
6775
|
*/
|
|
5687
|
-
declare function
|
|
6776
|
+
declare function createWorldDelta(prev: WorldSnapshot, current: WorldSnapshot): WorldDelta;
|
|
5688
6777
|
/**
|
|
5689
|
-
*
|
|
5690
|
-
* Useful for creating save slots or undo history.
|
|
6778
|
+
* Applies a delta to a world.
|
|
5691
6779
|
*
|
|
5692
|
-
* @param
|
|
5693
|
-
* @
|
|
6780
|
+
* @param world - The world to apply the delta to
|
|
6781
|
+
* @param delta - The delta to apply
|
|
6782
|
+
* @param components - Component registrations
|
|
6783
|
+
* @returns The modified world
|
|
5694
6784
|
*
|
|
5695
6785
|
* @example
|
|
5696
6786
|
* ```typescript
|
|
5697
|
-
* import {
|
|
6787
|
+
* import { applyWorldDelta } from 'blecsd';
|
|
5698
6788
|
*
|
|
5699
|
-
* const
|
|
5700
|
-
*
|
|
6789
|
+
* const world = deserializeWorld(baseSnapshot);
|
|
6790
|
+
* applyWorldDelta(world, delta, components);
|
|
5701
6791
|
* ```
|
|
5702
6792
|
*/
|
|
5703
|
-
declare function
|
|
5704
|
-
/** Current serialization format version */
|
|
5705
|
-
declare const SERIALIZATION_VERSION = 1;
|
|
6793
|
+
declare function applyWorldDelta(world: World, delta: WorldDelta, components: readonly ComponentRegistration[]): World;
|
|
5706
6794
|
|
|
5707
6795
|
/**
|
|
5708
6796
|
* Shrink-to-content calculation utilities.
|
|
@@ -6367,11 +7455,41 @@ declare function getComputedStyles(world: World, entities: readonly Entity[]): M
|
|
|
6367
7455
|
*/
|
|
6368
7456
|
|
|
6369
7457
|
/**
|
|
6370
|
-
*
|
|
7458
|
+
* Creates an entity validation error with the given message.
|
|
7459
|
+
*
|
|
7460
|
+
* @param message - The error message
|
|
7461
|
+
* @returns An Error with name set to 'EntityValidationError'
|
|
7462
|
+
*
|
|
7463
|
+
* @example
|
|
7464
|
+
* ```typescript
|
|
7465
|
+
* import { createEntityValidationError, isEntityValidationError } from 'blecsd';
|
|
7466
|
+
*
|
|
7467
|
+
* const error = createEntityValidationError('Entity 5 is missing Position');
|
|
7468
|
+
* console.log(error.name); // 'EntityValidationError'
|
|
7469
|
+
* console.log(isEntityValidationError(error)); // true
|
|
7470
|
+
* ```
|
|
6371
7471
|
*/
|
|
6372
|
-
declare
|
|
6373
|
-
|
|
6374
|
-
|
|
7472
|
+
declare function createEntityValidationError(message: string): Error;
|
|
7473
|
+
/**
|
|
7474
|
+
* Type guard to check if an error is an entity validation error.
|
|
7475
|
+
*
|
|
7476
|
+
* @param error - The value to check
|
|
7477
|
+
* @returns True if the error is an EntityValidationError
|
|
7478
|
+
*
|
|
7479
|
+
* @example
|
|
7480
|
+
* ```typescript
|
|
7481
|
+
* import { isEntityValidationError } from 'blecsd';
|
|
7482
|
+
*
|
|
7483
|
+
* try {
|
|
7484
|
+
* validateEntity(world, eid, [Position], 'test');
|
|
7485
|
+
* } catch (error) {
|
|
7486
|
+
* if (isEntityValidationError(error)) {
|
|
7487
|
+
* console.log('Validation failed:', error.message);
|
|
7488
|
+
* }
|
|
7489
|
+
* }
|
|
7490
|
+
* ```
|
|
7491
|
+
*/
|
|
7492
|
+
declare function isEntityValidationError(error: unknown): error is Error;
|
|
6375
7493
|
/**
|
|
6376
7494
|
* Registers a component name for better error messages.
|
|
6377
7495
|
* This is optional but recommended for clearer validation errors.
|
|
@@ -6396,7 +7514,7 @@ declare function registerComponentName(component: ComponentRef, name: string): v
|
|
|
6396
7514
|
* @param eid - The entity ID to validate
|
|
6397
7515
|
* @param requiredComponents - Array of components the entity must have
|
|
6398
7516
|
* @param context - Context string describing where this validation is happening (e.g., "layoutSystem", "createBox")
|
|
6399
|
-
* @throws {
|
|
7517
|
+
* @throws {Error} An EntityValidationError if entity doesn't exist or is missing required components
|
|
6400
7518
|
*
|
|
6401
7519
|
* @example
|
|
6402
7520
|
* ```typescript
|
|
@@ -6816,6 +7934,8 @@ interface PackedQueryAdapterConfig {
|
|
|
6816
7934
|
readonly queries: readonly PackedQueryRegistration[];
|
|
6817
7935
|
/** Initial capacity for each PackedStore (default: 64) */
|
|
6818
7936
|
readonly initialCapacity?: number;
|
|
7937
|
+
/** Synchronization strategy for scheduler integration (default: 'all') */
|
|
7938
|
+
readonly syncMode?: 'all' | 'render_only';
|
|
6819
7939
|
}
|
|
6820
7940
|
/**
|
|
6821
7941
|
* Extended adapter backed by PackedStores for cache-friendly iteration.
|
|
@@ -6876,6 +7996,8 @@ interface PackedQueryAdapter extends WorldAdapter {
|
|
|
6876
7996
|
* @returns Frozen array of query names
|
|
6877
7997
|
*/
|
|
6878
7998
|
readonly getRegisteredQueries: () => readonly string[];
|
|
7999
|
+
/** Scheduler sync mode hint. */
|
|
8000
|
+
readonly syncMode: 'all' | 'render_only';
|
|
6879
8001
|
}
|
|
6880
8002
|
/**
|
|
6881
8003
|
* Zod schema for PackedQueryRegistration.
|
|
@@ -6917,6 +8039,10 @@ declare const PackedQueryAdapterConfigSchema: z.ZodObject<{
|
|
|
6917
8039
|
components: z.ZodArray<z.ZodUnknown>;
|
|
6918
8040
|
}, z.core.$strip>>;
|
|
6919
8041
|
initialCapacity: z.ZodOptional<z.ZodNumber>;
|
|
8042
|
+
syncMode: z.ZodOptional<z.ZodEnum<{
|
|
8043
|
+
all: "all";
|
|
8044
|
+
render_only: "render_only";
|
|
8045
|
+
}>>;
|
|
6920
8046
|
}, z.core.$strip>;
|
|
6921
8047
|
/**
|
|
6922
8048
|
* Default adapter used when no custom adapter is registered.
|
|
@@ -6980,6 +8106,23 @@ declare function setWorldAdapter(world: World, adapter: WorldAdapter): void;
|
|
|
6980
8106
|
* ```
|
|
6981
8107
|
*/
|
|
6982
8108
|
declare function getWorldAdapter(world: World): WorldAdapter;
|
|
8109
|
+
/**
|
|
8110
|
+
* Synchronizes the registered world adapter if it is PackedStore-backed.
|
|
8111
|
+
*
|
|
8112
|
+
* Safe to call unconditionally each frame/system tick. For non-packed
|
|
8113
|
+
* adapters this is a no-op.
|
|
8114
|
+
*
|
|
8115
|
+
* @param world - The ECS world
|
|
8116
|
+
*
|
|
8117
|
+
* @example
|
|
8118
|
+
* ```typescript
|
|
8119
|
+
* import { syncWorldAdapter } from 'blecsd';
|
|
8120
|
+
*
|
|
8121
|
+
* // Call before systems that read adapter-backed query data
|
|
8122
|
+
* syncWorldAdapter(world);
|
|
8123
|
+
* ```
|
|
8124
|
+
*/
|
|
8125
|
+
declare function syncWorldAdapter(world: World): void;
|
|
6983
8126
|
/**
|
|
6984
8127
|
* Clears any custom adapter for a world.
|
|
6985
8128
|
*
|
|
@@ -7036,6 +8179,13 @@ declare function clearWorldAdapter(world: World): void;
|
|
|
7036
8179
|
* ```
|
|
7037
8180
|
*/
|
|
7038
8181
|
declare function createPackedQueryAdapter(config: PackedQueryAdapterConfig): PackedQueryAdapter;
|
|
8182
|
+
/**
|
|
8183
|
+
* Creates the default PackedQueryAdapter used for TUI acceleration.
|
|
8184
|
+
*
|
|
8185
|
+
* @param _initialCapacity - Deprecated, kept for API compatibility. No longer used.
|
|
8186
|
+
* @returns Packed query adapter with common TUI query registrations
|
|
8187
|
+
*/
|
|
8188
|
+
declare function createDefaultPackedQueryAdapter(_initialCapacity?: number): PackedQueryAdapter;
|
|
7039
8189
|
/**
|
|
7040
8190
|
* Type guard to check if an adapter is a PackedQueryAdapter.
|
|
7041
8191
|
*
|
|
@@ -7055,6 +8205,95 @@ declare function createPackedQueryAdapter(config: PackedQueryAdapterConfig): Pac
|
|
|
7055
8205
|
*/
|
|
7056
8206
|
declare function isPackedQueryAdapter(adapter: WorldAdapter): adapter is PackedQueryAdapter;
|
|
7057
8207
|
|
|
8208
|
+
/**
|
|
8209
|
+
* WorldStore - Utilities for world-scoped storage
|
|
8210
|
+
*
|
|
8211
|
+
* Provides a pattern for storing entity-associated data on the world object
|
|
8212
|
+
* rather than in module-level Map singletons. This ensures:
|
|
8213
|
+
* - World isolation: Each world has its own data
|
|
8214
|
+
* - Memory safety: Data is cleaned up when world is destroyed
|
|
8215
|
+
* - Library-first: Users can create multiple worlds without conflicts
|
|
8216
|
+
* - Testability: No global state between tests
|
|
8217
|
+
*
|
|
8218
|
+
* @module core/worldStore
|
|
8219
|
+
*/
|
|
8220
|
+
|
|
8221
|
+
/**
|
|
8222
|
+
* Gets or creates a world-scoped store.
|
|
8223
|
+
* Stores are Maps that live on the world object, not as module singletons.
|
|
8224
|
+
*
|
|
8225
|
+
* @param world - The ECS world
|
|
8226
|
+
* @param key - Unique string key for this store (e.g., 'select:options')
|
|
8227
|
+
* @returns A Map scoped to this world
|
|
8228
|
+
*
|
|
8229
|
+
* @example
|
|
8230
|
+
* ```typescript
|
|
8231
|
+
* // Instead of module-level singleton:
|
|
8232
|
+
* // const optionsStore = new Map<Entity, SelectOption[]>();
|
|
8233
|
+
*
|
|
8234
|
+
* // Use world-scoped store:
|
|
8235
|
+
* function getOptionsStore(world: World): Map<Entity, SelectOption[]> {
|
|
8236
|
+
* return getWorldStore(world, 'select:options');
|
|
8237
|
+
* }
|
|
8238
|
+
*
|
|
8239
|
+
* // Usage
|
|
8240
|
+
* const store = getOptionsStore(world);
|
|
8241
|
+
* store.set(entity, options);
|
|
8242
|
+
* ```
|
|
8243
|
+
*/
|
|
8244
|
+
declare function getWorldStore<K, V>(world: World, key: string): Map<K, V>;
|
|
8245
|
+
/**
|
|
8246
|
+
* Gets or creates a world-scoped Set.
|
|
8247
|
+
*
|
|
8248
|
+
* @param world - The ECS world
|
|
8249
|
+
* @param key - Unique string key for this set
|
|
8250
|
+
* @returns A Set scoped to this world
|
|
8251
|
+
*
|
|
8252
|
+
* @example
|
|
8253
|
+
* ```typescript
|
|
8254
|
+
* function getActiveSpinners(world: World): Set<Entity> {
|
|
8255
|
+
* return getWorldSet(world, 'spinner:active');
|
|
8256
|
+
* }
|
|
8257
|
+
* ```
|
|
8258
|
+
*/
|
|
8259
|
+
declare function getWorldSet<T>(world: World, key: string): Set<T>;
|
|
8260
|
+
/**
|
|
8261
|
+
* Cleans up all data for an entity across all world stores.
|
|
8262
|
+
* Call this when an entity is removed to prevent memory leaks.
|
|
8263
|
+
*
|
|
8264
|
+
* @param world - The ECS world
|
|
8265
|
+
* @param entity - The entity being removed
|
|
8266
|
+
*
|
|
8267
|
+
* @example
|
|
8268
|
+
* ```typescript
|
|
8269
|
+
* export function removeEntity(world: World, entity: Entity): void {
|
|
8270
|
+
* // ... remove from components ...
|
|
8271
|
+
* cleanupEntityStores(world, entity);
|
|
8272
|
+
* }
|
|
8273
|
+
* ```
|
|
8274
|
+
*/
|
|
8275
|
+
declare function cleanupEntityStores(world: World, entity: Entity): void;
|
|
8276
|
+
/**
|
|
8277
|
+
* Destroys all stores for a world.
|
|
8278
|
+
* Call this when destroying a world to free memory.
|
|
8279
|
+
*
|
|
8280
|
+
* @param world - The ECS world
|
|
8281
|
+
*
|
|
8282
|
+
* @example
|
|
8283
|
+
* ```typescript
|
|
8284
|
+
* export function destroyWorld(world: World): void {
|
|
8285
|
+
* clearWorldStores(world);
|
|
8286
|
+
* // ... other cleanup ...
|
|
8287
|
+
* }
|
|
8288
|
+
* ```
|
|
8289
|
+
*/
|
|
8290
|
+
declare function clearWorldStores(world: World): void;
|
|
8291
|
+
/**
|
|
8292
|
+
* Gets all store keys for debugging/inspection.
|
|
8293
|
+
* @internal
|
|
8294
|
+
*/
|
|
8295
|
+
declare function getStoreKeys(world: World): string[];
|
|
8296
|
+
|
|
7058
8297
|
/**
|
|
7059
8298
|
* Z-order management for entity layering.
|
|
7060
8299
|
*
|
|
@@ -7295,4 +8534,4 @@ declare function normalizeZIndices(world: World, parent: Entity): void;
|
|
|
7295
8534
|
*/
|
|
7296
8535
|
declare function resetZOrder(entity: Entity): void;
|
|
7297
8536
|
|
|
7298
|
-
export { type AbsolutePosition, type AdoptEvent, type ArchetypeDefinition, type ArchetypePoolConfig, type ArchetypePoolStats, type AttachEvent, type AutoPaddingData, BUILTIN_PHASE_NAMES, type BindingMatch, type BorderDockingContext, type BorderDockingOptions, type BorderEdge, type BorderStyleType, BoxConfig, type BubbleResult, type BubbleableEvent, type BubbleableEventOptions, ButtonConfig, type CachedPosition, CheckboxConfig, type CleanupCallback, type ClickableCache, type ClipRect, type ClipStack, Clipping, type ClippingData, type ClippingOptions, type ComponentDescriptor, type ComponentResetFn, type ComputedPositionData, type ConditionContext, type ConnectionFlags, DEFAULT_NAV_BINDINGS, DEFAULT_TEXT_BINDINGS, DEFAULT_WORLD_ADAPTER, DEFAULT_Z_INDEX, type DataValue, type DeprecatedAPIMetadata, DeprecatedAPIMetadataSchema, type DeserializeOptions, type DeserializeResult, type DestroyEvent, type DestroyOptions, type DetachEvent, type DirtyStats, type DirtyTrackerData, type DockingBuffer, type DockingCell, type DynamicValue, type EffectConfig, type EffectivePaddingData, type EffectsConfig, type EmitDescendantsOptions, EmitDescendantsOptionsSchema, type EmitDescendantsResult, EmitDescendantsResultSchema, Entity, type EntityDataMap, type EntityHandle, type EntityPool, EntityValidationError, EventBus, EventMap, FormConfig, GetEntityEventBus, type HitTestOptions, type HitTestResult, INHERITING_PROPERTIES, InitPriority, type InitPriorityLevel, type InnerDimensions, type InnerPosition, InputConfig, JUNCTION_ASCII, JUNCTION_BOLD, JUNCTION_DOUBLE, JUNCTION_SINGLE, type Junction, type JunctionCharset, type KeyBinding, type KeyBindingRegistry, KeyBindingSchema, KeyBindingsArraySchema, type KeyLockFilter, type KeyLockOptions, type KeyLockState, type LazyInitFn, type LazyValue, type DirtyRect as LegacyDirtyRect, type LifecycleEvent, type LifecycleEventMap, type LifecycleEventName, ListConfig, LoopPhase, MAX_Z_INDEX, MIN_Z_INDEX, NON_INHERITING_PROPERTIES, Overflow, type OverflowValue, type PackedQueryAdapter, type PackedQueryAdapterConfig, PackedQueryAdapterConfigSchema, type PackedQueryRegistration, PackedQueryRegistrationSchema, type ParsedKey, type PerformanceIssueMetadata, PerformanceIssueMetadataSchema, type PhaseId, type PhaseManager, PositionCache, type PositionValue, PositionValueSchema, ProgressBarConfig, RadioButtonConfig, RadioSetConfig, type RecyclingSystemStats, type RelativePosition, type RemoveEvent, type ReparentEvent, type ResolvedEffect, SERIALIZATION_VERSION, type Scene, type SceneManager, type SceneTransition, ScreenConfig, SelectConfig, type SerializeOptions, type SerializedComponentData, type SerializedEntity, type SerializedWorld, type SetPositionCacheOptions, type ShrinkBox, SliderConfig, type StartupReport, type SubsystemEntry, System, type TerminalCapabilities, type TerminalTooSmallMetadata, TerminalTooSmallMetadataSchema, TextConfig, TextareaConfig, TextboxConfig, type TotalPadding, type TransitionState, type UnsupportedCapabilityMetadata, UnsupportedCapabilityMetadataSchema, type WarningEmitter, type WarningEvent, type WarningEventMap, WarningEventSchema, type WarningMetadata, WarningType, type WarningTypeValue, World, type WorldAdapter, type WorldAdapterType, ZOrder, acquireEntity, addComponent, addEntity, addIgnoredKeys, allocateEntity, applyCustomEffect, applyDisabledEffect, applyFocusEffect, applyHoverEffect, applyJunctions, applyKeyLockOptions, applyPressEffect, applyShrink, areAllKeysLocked, assertEntityAlive, bubbleEvent, calculateShrinkSize, centerPosition, clampPosition, clampToClipRect, clearAllArchetypePools, clearAllEffectConfigs, clearAllEntityData, clearAllPositionCaches, clearAllStoredStyles, clearArchetypePool, clearCapabilityCache, clearCleanupCallbacks, clearDestroyQueue, clearDockingContext, clearEffectState, clearEffects, clearEntityData, clearIgnoredKeys, clearLifecycleEventBuses, clearSerializableRegistry, clearStoredStyle, clearStyleCache, clearWorldAdapter, cloneSnapshot, computeInheritedStyle, createBorderDockingContext, createBoxEntity, createBubbleableEvent, createButtonEntity, createCheckboxEntity, createClickableCache, createClipRect, createClipStack, createEntityPool, createFadeTransition, createFormEntity, createInfiniteClipRect, createInputEntity, createKeyBindingRegistry, createKeyLockScope, createKeyLockState, createListEntity, createPackedQueryAdapter, createPhaseManager, createProgressBarEntity, createRadioButtonEntity, createRadioSetEntity, createSceneManager, createSceneSystem, createScreenEntity, createSelectEntity, createSlideTransition, createSliderEntity, createTextEntity, createTextareaEntity, createTextboxEntity, createWarningEmitter, createWorld, createWorldAdapter, deallocateEntity, defaultPhaseManager, deleteEntityData, deserializeWorld, deserializeWorldFromJSON, destroyAllChildren, destroyEntity, destroyWorld, detectAllJunctions, detectBorderStyle, detectCapabilities, detectJunctions, doesPropertyInherit, emitAdopt, emitAttach, emitDeprecatedAPIWarning, emitDescendants, emitDestroy, emitDetach, emitPerformanceWarning, emitRemove, emitReparent, emitTerminalTooSmallWarning, emitUnsupportedCapabilityWarning, entityExists, evaluateCondition, filterClickable, filterDirty, filterFocusable, filterVisible, filterVisibleDirty, findPropertySource, flushDestroyQueue, forceFullRedrawFlag, formatKey, formatKeyEvent, formatStartupReport, getAbsoluteEdges, getAbsolutePosition, getAllClickablesAt, getAllEntities, getAllEntityData, getAllHoverablesAt, getArchetypePoolStats, getAutoPadding, getBindingForAction, getBindingsForKey, getCacheGeneration, getCachedInnerHeight, getCachedInnerWidth, getChildEntities, getChildrenByZIndex, getClickableAt, getClickableCount, getClickableEntities, getClipRect, getClipRectHeight, getClipRectToAncestor, getClipRectWidth, getClipping, getComputedEffectStyle, getComputedPosition, getComputedStyles, getConnectionFlags, getCurrentClip, getDefaultStyle, getDescendantEntities, getDestroyQueueSize, getDirtyEntities, getDirtyRegionsInViewport, getDirtyStats, getEdgeCount, getEdgesAt, getEffectState, getEffectivePadding, getEffects, getEntityCount, getEntityData, getEntityDataCount, getEntityDataKeys, getEntityPoolCapacity, getGrabbedKeys, getHoverableAt, getIgnoredKeys, getInheritedProperty, getInnerDimensions, getInnerPosition, getJunctionChar, getJunctionCharset, getJunctionRenderData, getKeyLockFilter, getKeyLockState, getLifecycleEventBus, getLocalStyle, getLocalZ, getOriginalStyle, getOverflow, getPositionCache, getRecyclingStats, getRegisteredComponents, getRelativePosition, getRootEntities, getSerializable, getShrinkBox, getShrinkHeight, getShrinkWidth, getStartupReport, getStoredStyle, getTotalEffectivePadding, getTotalPadding, getWorldAdapter, getZIndex, grabKeys, hasAnyEffectApplied, hasAnyEntityData, hasAutoPadding, hasClickableAt, hasClipping, hasComponent, hasDirtyEntities, hasDisabledEffectApplied, hasEntityAutoPadding, hasEntityData, hasFocusEffectApplied, hasHoverEffectApplied, hasHoverableAt, hasPressEffectApplied, hasStoredStyle, hasValidPositionCache, hasValidStyleCache, hasZOrder, hitTest, hitTestAll, hitTestDetailed, initSubsystem, initSubsystemsUpTo, intersectClipRects, invalidateAllStyleCaches, invalidateClickableCache, invalidatePositionCache, invalidatePositionCacheTree, invalidateStyleCache, isBorderChar, isBuiltinPhase, isCacheDirty, isClipRectEmpty, isDefaultColor, isEntityAlive, isEntityDirty, isEntityValid, isJunctionChar, isKeyGrabbed, isKeyIgnored, isKeyLocked, isKeywordPosition, isMarkedForDestruction, isPackedQueryAdapter, isPercentagePosition, isPointInCachedBounds, isPointInEntity, isPointInInnerBounds, isPointVisible, isRectVisible, lazy, clearDirtyTracking as legacyClearDirtyTracking, createDirtyTracker as legacyCreateDirtyTracker, getDirtyRegions as legacyGetDirtyRegions, isCellDirty as legacyIsCellDirty, markCellDirty as legacyMarkCellDirty, markEntityDirty as legacyMarkEntityDirty, markRegionDirty as legacyMarkRegionDirty, removeEntityFromTracking as legacyRemoveEntityFromTracking, listBindings, lockAllKeys, markAllEntitiesDirty, matchEvent, matchesKey, mergeStyles, moveDown, moveUp, needsFullRedraw, normalizeZIndices, onAdopt, onAttach, onDestroy, onDetach, onRemove, onReparent, parseKeyString, parsePosition, parsePositionWithNegative, percentOffsetPosition, percentPosition, popClipRect, preallocateEntities, precomputeStyles, pushClipRect, query, queryBorder, queryContent, queryFocusable, queryHierarchy, queryInteractive, queryPadding, queryRenderable, queryScrollable, regionIntersectsDirty, registerArchetype, registerBinding, registerBindings, registerCleanupCallback, registerComponent, registerComponentName, registerEdge, registerRectBorder, registerSerializable, registerSubsystem, releaseAllGrabbedKeys, releaseEntity, releaseKeys, removeAllEffects, removeComponent, removeDisabledEffect, removeEntity, removeFocusEffect, removeHoverEffect, removeIgnoredKeys, removeLifecycleEventBus, removePressEffect, resetDisposalState, resetEntityPool, resetKeyLockState, resetSubsystems, resetWorld, resetZOrder, resizeDirtyTracker, resizeDockingContext, resolveEffectConfig, resolvePosition, resolvePositionClamped, resolveStyle, serializeWorld, serializeWorldToJSON, setAbsoluteBottom, setAbsoluteEdges, setAbsoluteLeft, setAbsolutePosition, setAbsoluteRight, setAbsoluteTop, setBack, setEffects, setEntityData, setEntityDataBulk, setFront, setIgnoredKeys, setKeyLockFilter, setLocalZ, setOverflow, setPositionCache, setRelativePosition, setWorldAdapter, setZIndex, shouldBlockKeyEvent, shouldClipContent, sortByDepth, sortByTabIndex, sortByZIndex, syncEffects, unlockAllKeys, unregisterArchetype, unregisterBinding, unregisterSerializable, updateCachedScrollBase, updateClickableCache, updateEntityBounds, updateEntityData, validateEntity, withStore };
|
|
8537
|
+
export { type AbsolutePosition, type ActionBinding, ActionBindingSchema, type ActionCallback, ActionPresets, type ActionState, type AdoptEvent, type ArchetypeDefinition, type ArchetypePoolConfig, type ArchetypePoolStats, type AttachEvent, type AutoPaddingData, BUILTIN_PHASE_NAMES, type BindingMatch, type BorderDockingContext, type BorderDockingOptions, type BorderEdge, type BorderStyleType, type BubbleResult, type BubbleableEvent, type BubbleableEventOptions, type CachedPosition, type ClipRect, type ClipStack, Clipping, type ClippingData, type ClippingOptions, type ComponentData, type ComponentFieldData, type ComponentRegistration, type ComponentResetFn, type ComputedGetter, type ComputedPositionData, type ComputedSignal, type ConditionContext, type ConnectionFlags, DEFAULT_NAV_BINDINGS, DEFAULT_TEXT_BINDINGS, DEFAULT_WORLD_ADAPTER, DEFAULT_Z_INDEX, type DataValue, type DeprecatedAPIMetadata, DeprecatedAPIMetadataSchema, type DestroyEvent, type DetachEvent, type DirtyStats, type DirtyTrackerData, type DockingBuffer, type DockingCell, type DynamicValue, type EffectConfig, type EffectHandle, type EffectivePaddingData, type EffectsConfig, type EmitDescendantsOptions, EmitDescendantsOptionsSchema, type EmitDescendantsResult, EmitDescendantsResultSchema, Entity, type EntityDataMap, type EntityHandle, type EntityPool, EventBus, EventMap, GetEntityEventBus, INHERITING_PROPERTIES, InitPriority, type InitPriorityLevel, type InnerDimensions, type InnerPosition, type InputActionManager, type InputBufferStats, type InputEventBufferData, type InputEventBufferOptions, type InputLatencyStats, type InputState, type InputStateConfig, type InputStateStats, JUNCTION_ASCII, JUNCTION_BOLD, JUNCTION_DOUBLE, JUNCTION_SINGLE, type Junction, type JunctionCharset, type KeyBinding, type KeyBindingRegistry, KeyBindingSchema, KeyBindingsArraySchema, type KeyLockFilter, type KeyLockOptions, type KeyLockState, type KeyState, type LazyInitFn, type LazyValue, type DirtyRect as LegacyDirtyRect, type LifecycleEvent, type LifecycleEventMap, type LifecycleEventName, LoopPhase, MAX_Z_INDEX, MIN_Z_INDEX, type MountedTree, type MouseButtonState, type MouseState, NON_INHERITING_PROPERTIES, Overflow, type OverflowValue, type PackedQueryAdapter, type PackedQueryAdapterConfig, PackedQueryAdapterConfigSchema, type PackedQueryRegistration, PackedQueryRegistrationSchema, type ParsedKey, type PerformanceIssueMetadata, PerformanceIssueMetadataSchema, type PhaseId, type PhaseManager, type Plugin, type PluginComponent, PluginComponentSchema, type PluginInfo, type PluginRegistrationResult, type PluginRegistry, PluginSchema, type PluginSystem, PluginSystemSchema, type PluginThemeDeclaration, PluginThemeDeclarationSchema, type PluginWidgetDeclaration, PluginWidgetDeclarationSchema, PositionCache, type ReactiveConfig, type ReactiveProp, type RecyclingSystemStats, type RelativePosition, type RemoveEvent, type ReparentEvent, type ResolvedEffect, type Scene, type SceneManager, type SceneTransition, Scheduler, type SerializedBindings, SerializedBindingsSchema, type SetPositionCacheOptions, type ShrinkBox, type Signal, type SignalGetter, type SignalSetter, type StartupReport, type SubsystemEntry, System, type TerminalCapabilities, type TerminalTooSmallMetadata, TerminalTooSmallMetadataSchema, type TimestampedInputEvent, type TimestampedKeyEvent, type TimestampedMouseEvent, type TotalPadding, type TransitionState, type UnsupportedCapabilityMetadata, UnsupportedCapabilityMetadataSchema, type WarningEmitter, type WarningEvent, type WarningEventMap, WarningEventSchema, type WarningMetadata, WarningType, type WarningTypeValue, type WidgetDescriptor, type WidgetType, World, type WorldAdapter, type WorldAdapterType, type WorldDelta, type WorldSnapshot, ZOrder, acquireEntity, activatePlugin, addIgnoredKeys, allocateEntity, applyCustomEffect, applyDisabledEffect, applyFocusEffect, applyHoverEffect, applyJunctions, applyKeyLockOptions, applyPressEffect, applyShrink, applyWorldDelta, areAllKeysLocked, assertEntityAlive, beginFrame, bind, bubbleEvent, calculateShrinkSize, clampToClipRect, cleanupEntityStores, clearAllArchetypePools, clearAllEffectConfigs, clearAllEntityData, clearAllPositionCaches, clearAllStoredStyles, clearArchetypePool, clearBuffer, clearCapabilityCache, clearDockingContext, clearEffectState, clearEffects, clearEntityData, clearIgnoredKeys, clearLifecycleEventBuses, clearPlugins, clearStoredStyle, clearStyleCache, clearWorldAdapter, clearWorldStores, computeInheritedStyle, createBatch, createBorderDockingContext, createBubbleableEvent, createCallbackSignal, createClipRect, createClipStack, createComputed, createDefaultPackedQueryAdapter, createDerivedSignal, createEffect, createEntityPool, createEntitySignal, createEntityValidationError, createEventSignal, createFadeTransition, createInfiniteClipRect, createInputActionManager, createInputEventBuffer, createInputState, createIntervalSignal, createKeyBindingRegistry, createKeyLockScope, createKeyLockState, createPackedQueryAdapter, createPhaseManager, createPluginRegistry, createPollingSignal, createReducerSignal, createSceneManager, createSceneSystem, createScheduledEffect, createSignal, createSlideTransition, createStreamSignal, createTimerSignal, createWarningEmitter, createWorldAdapter, createWorldDelta, deactivatePlugin, deallocateEntity, defaultPhaseManager, definePlugin, deleteEntityData, deserializeWorld, detectAllJunctions, detectBorderStyle, detectCapabilities, detectJunctions, disposeEffect, disposeSignal, doesPropertyInherit, drainAllEvents, drainKeys, drainMouse, el, elRef, emitAdopt, emitAttach, emitDeprecatedAPIWarning, emitDescendants, emitDestroy, emitDetach, emitPerformanceWarning, emitRemove, emitReparent, emitTerminalTooSmallWarning, emitUnsupportedCapabilityWarning, endFrame, evaluateCondition, filterClickable, filterDirty, filterFocusable, filterVisible, filterVisibleDirty, findPropertySource, flushScheduledEffects, forceFullRedrawFlag, formatKey, formatKeyEvent, formatStartupReport, getAbsoluteEdges, getAbsolutePosition, getAllEntityData, getArchetypePoolStats, getAutoPadding, getBindingForAction, getBindingsForKey, getCacheGeneration, getCachedInnerHeight, getCachedInnerWidth, getChildEntities, getChildrenByZIndex, getClipRect, getClipRectHeight, getClipRectToAncestor, getClipRectWidth, getClipping, getComputedEffectStyle, getComputedPosition, getComputedStyles, getConnectionFlags, getCurrentClip, getDefaultStyle, getDescendantEntities, getDirtyEntities, getDirtyRegionsInViewport, getDirtyStats, getEdgeCount, getEdgesAt, getEffectState, getEffectivePadding, getEffects, getEntityCount, getEntityData, getEntityDataCount, getEntityDataKeys, getEntityPoolCapacity, getGrabbedKeys, getIgnoredKeys, getInheritedProperty, getInnerDimensions, getInnerPosition, getJunctionChar, getJunctionCharset, getJunctionRenderData, getKeyLockFilter, getKeyLockState, getLatencyStats, getLifecycleEventBus, getLocalStyle, getLocalZ, getMovementDirection, getOriginalStyle, getOverflow, getPendingCount, getPendingKeyCount, getPendingMouseCount, getPluginCount, getPlugins, getPositionCache, getRecyclingStats, getRegisteredComponents, getRelativePosition, getRootEntities, getScheduledEffectCount, getShrinkBox, getShrinkHeight, getShrinkWidth, getStartupReport, getStats, getStoreKeys, getStoredStyle, getTotalEffectivePadding, getTotalPadding, getTotalScheduledEffectCount, getWorldAdapter, getWorldSet, getWorldStore, getZIndex, globalInputBuffer, grabKeys, hasAnyEffectApplied, hasAnyEntityData, hasAutoPadding, hasClipping, hasDirtyEntities, hasDisabledEffectApplied, hasEntityAutoPadding, hasEntityData, hasFocusEffectApplied, hasHoverEffectApplied, hasPendingEvents, hasPlugin, hasPressEffectApplied, hasStoredStyle, hasValidPositionCache, hasValidStyleCache, hasZOrder, hbox, initSubsystem, initSubsystemsUpTo, intersectClipRects, invalidateAllStyleCaches, invalidatePositionCache, invalidatePositionCacheTree, invalidateStyleCache, isAllKeysDown, isAnyKeyDown, isAnyKeyPressed, isBorderChar, isBuiltinPhase, isClipRectEmpty, isDefaultColor, isEntityAlive, isEntityDirty, isEntityValid, isEntityValidationError, isJunctionChar, isKeyGrabbed, isKeyIgnored, isKeyLocked, isLatencyAcceptable, isPackedQueryAdapter, isPluginActive, isPointInCachedBounds, isPointInEntity, isPointInInnerBounds, isPointVisible, isProcessingTimeAcceptable, isRectVisible, lazy, clearDirtyTracking as legacyClearDirtyTracking, createDirtyTracker as legacyCreateDirtyTracker, getDirtyRegions as legacyGetDirtyRegions, isCellDirty as legacyIsCellDirty, markCellDirty as legacyMarkCellDirty, markEntityDirty as legacyMarkEntityDirty, markRegionDirty as legacyMarkRegionDirty, removeEntityFromTracking as legacyRemoveEntityFromTracking, listBindings, lockAllKeys, markAllEntitiesDirty, matchEvent, matchesKey, mergeStyles, mount, moveDown, moveUp, needsFullRedraw, normalizeZIndices, onAdopt, onAttach, onDestroy, onDetach, onRemove, onReparent, parseKeyString, peekEvents, peekKeys, peekMouse, popClipRect, preallocateEntities, precomputeStyles, pushClipRect, pushKeyEvent, pushMouseEvent, queryBorder, queryContent, queryFocusable, queryHierarchy, queryInteractive, queryPadding, queryRenderable, queryScrollable, recordLatency, recordLatencyBatch, regionIntersectsDirty, registerArchetype, registerBinding, registerBindings, registerComponentName, registerComponents, registerDefaultPropSetters, registerEdge, registerPlugin, registerPropSetter, registerRectBorder, registerSubsystem, registerWidgetFactory, releaseAllGrabbedKeys, releaseEntity, releaseKeys, removeAllEffects, removeDisabledEffect, removeFocusEffect, removeHoverEffect, removeIgnoredKeys, removeLifecycleEventBus, removePressEffect, resetDeclarativeRegistrations, resetEntityPool, resetKeyLockState, resetLatencyStats, resetStats, resetSubsystems, resetZOrder, resizeDirtyTracker, resizeDockingContext, resolveEffectConfig, resolveStyle, serializeWorld, setAbsoluteBottom, setAbsoluteEdges, setAbsoluteLeft, setAbsolutePosition, setAbsoluteRight, setAbsoluteTop, setBack, setEffects, setEntityData, setEntityDataBulk, setFront, setIgnoredKeys, setKeyLockFilter, setLocalZ, setOverflow, setPositionCache, setRelativePosition, setWorldAdapter, setZIndex, shouldBlockKeyEvent, shouldClipContent, sortByDepth, sortByTabIndex, sortByZIndex, syncEffects, syncWorldAdapter, trackDependencies, unlockAllKeys, unmount, unregisterArchetype, unregisterBinding, unregisterPlugin, updateCachedScrollBase, updateEntityBounds, updateEntityData, validateEntity, validatePluginConfig, vbox };
|