@draug/engine 1.0.0 → 1.0.1
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/dist/index.cjs +946 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +373 -0
- package/dist/index.d.ts +373 -0
- package/dist/index.js +883 -0
- package/dist/index.js.map +1 -0
- package/package.json +13 -3
- package/ecs/command.ts +0 -44
- package/ecs/components/component-storage.ts +0 -86
- package/ecs/components/index.ts +0 -12
- package/ecs/components/manager.ts +0 -91
- package/ecs/components/singleton-storage.ts +0 -51
- package/ecs/components/types.ts +0 -14
- package/ecs/components/utils.ts +0 -18
- package/ecs/constant.ts +0 -3
- package/ecs/entity.ts +0 -44
- package/ecs/events-buffer.ts +0 -62
- package/ecs/query.ts +0 -169
- package/ecs/resources/index.ts +0 -1
- package/ecs/resources/resources.ts +0 -28
- package/ecs/system.ts +0 -214
- package/ecs/world.ts +0 -99
- package/index.ts +0 -74
- package/plugin/index.ts +0 -15
- package/plugin/plugin.ts +0 -200
- package/runtime/clock.ts +0 -31
- package/runtime/game-loop.ts +0 -32
- package/runtime/runtime.ts +0 -12
- package/tsconfig.json +0 -24
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { ClassType, ComponentType as ComponentType$1 } from '@draug/types/class';
|
|
2
|
+
import { Bitmap } from 'bitmap-index';
|
|
3
|
+
import { AssetsManager } from '@draug/assets/assets';
|
|
4
|
+
|
|
5
|
+
type ComponentType<T extends object = object> = ClassType<T>;
|
|
6
|
+
interface IStorage<T extends object> {
|
|
7
|
+
add(id: number, initFn?: (obj: T) => T): T;
|
|
8
|
+
remove(id: number): void;
|
|
9
|
+
get(id: number): T | null;
|
|
10
|
+
tryGet(id: number): T;
|
|
11
|
+
has(id: number): boolean;
|
|
12
|
+
size(): number;
|
|
13
|
+
forEach(cb: (id: number) => void): void;
|
|
14
|
+
bitmap(): Bitmap;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare enum ComponentStorageType {
|
|
18
|
+
COMPONENT_STORAGE = 1,
|
|
19
|
+
SINGLETON_STORAGE = 2
|
|
20
|
+
}
|
|
21
|
+
type RegisterSingletoneComponentOptions<T extends object> = {
|
|
22
|
+
storageType: ComponentStorageType.SINGLETON_STORAGE;
|
|
23
|
+
factory: () => T;
|
|
24
|
+
};
|
|
25
|
+
type RegisterComponentStorageOptions<T extends object> = {
|
|
26
|
+
storageType: ComponentStorageType.COMPONENT_STORAGE;
|
|
27
|
+
factory?: () => T;
|
|
28
|
+
};
|
|
29
|
+
type RegisterComponentOptions<T extends object> = RegisterSingletoneComponentOptions<T> | RegisterComponentStorageOptions<T>;
|
|
30
|
+
declare class ComponentAlreadyRegisteredError extends Error {
|
|
31
|
+
constructor(component: ComponentType);
|
|
32
|
+
}
|
|
33
|
+
declare class ComponentsManager {
|
|
34
|
+
private maxEntityCount;
|
|
35
|
+
private readonly storages_;
|
|
36
|
+
private currId_;
|
|
37
|
+
private nextId;
|
|
38
|
+
constructor(maxEntityCount?: number);
|
|
39
|
+
register<T extends object>(component: ComponentType<T>, opts?: RegisterComponentOptions<T>): IStorage<T>;
|
|
40
|
+
private createComponentStore;
|
|
41
|
+
private createSingletonStore;
|
|
42
|
+
getStorage<T extends object>(component: ComponentType<T>): IStorage<T>;
|
|
43
|
+
getComponentId(ctor: ComponentType): number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
declare function Component(): ClassDecorator;
|
|
47
|
+
|
|
48
|
+
declare class ComponentStorage<T extends object> implements IStorage<T> {
|
|
49
|
+
private bits_;
|
|
50
|
+
private set_;
|
|
51
|
+
private pool_;
|
|
52
|
+
private id_;
|
|
53
|
+
private cls;
|
|
54
|
+
constructor(cap: number | undefined, factory: () => T, cls: ClassType<T>);
|
|
55
|
+
bitmap(): Bitmap;
|
|
56
|
+
get id(): number;
|
|
57
|
+
_internalSetId(id: number): number;
|
|
58
|
+
add(id: number, initFn?: (obj: T) => T): T;
|
|
59
|
+
remove(id: number): void;
|
|
60
|
+
get(id: number): T | null;
|
|
61
|
+
tryGet(id: number): T;
|
|
62
|
+
writeComponentsToBuf(ids: ReadonlyArray<number>, out: T[]): number;
|
|
63
|
+
has(id: number): boolean;
|
|
64
|
+
entityIds(): number[];
|
|
65
|
+
size(): number;
|
|
66
|
+
forEach(cb: (id: number) => void): void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
declare class SingletonStorage<T extends object> implements IStorage<T> {
|
|
70
|
+
private factory;
|
|
71
|
+
private value;
|
|
72
|
+
private entityId;
|
|
73
|
+
constructor(factory: () => T);
|
|
74
|
+
bitmap(): Bitmap;
|
|
75
|
+
add(id: number, initFn?: ((obj: T) => T) | undefined): T;
|
|
76
|
+
remove(id: number): void;
|
|
77
|
+
get(id: number): T | null;
|
|
78
|
+
tryGet(id: number): T;
|
|
79
|
+
has(id: number): boolean;
|
|
80
|
+
size(): number;
|
|
81
|
+
forEach(cb: (id: number) => void): void;
|
|
82
|
+
private validateId;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type EntityID = number;
|
|
86
|
+
declare class UnregisteredComponentStorageError extends Error {
|
|
87
|
+
constructor(component: ComponentType);
|
|
88
|
+
}
|
|
89
|
+
declare class EntityMaskNotFoundError extends Error {
|
|
90
|
+
constructor(id: EntityID);
|
|
91
|
+
}
|
|
92
|
+
declare class EntitiesManager {
|
|
93
|
+
private id_;
|
|
94
|
+
private nextId;
|
|
95
|
+
create(): EntityID;
|
|
96
|
+
}
|
|
97
|
+
declare class EntityRef {
|
|
98
|
+
private world;
|
|
99
|
+
id: EntityID;
|
|
100
|
+
constructor(world: World, id: EntityID);
|
|
101
|
+
with<T extends ComponentType[], Result extends {
|
|
102
|
+
[K in keyof T]: InstanceType<T[K]>;
|
|
103
|
+
}>(...components: T): Result;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
declare class EventBuffer<T extends unknown> {
|
|
107
|
+
private readBuf;
|
|
108
|
+
private writeBuf;
|
|
109
|
+
write(event: T): void;
|
|
110
|
+
/**
|
|
111
|
+
* Advances the buffer to the next frame.
|
|
112
|
+
*
|
|
113
|
+
* Performs a double-buffer flip:
|
|
114
|
+
* - Promotes all events written during the previous frame (`writeBuf`)
|
|
115
|
+
* to be readable in the current frame (`readBuf`).
|
|
116
|
+
* - Reuses the previous `readBuf` as the new `writeBuf` and clears it
|
|
117
|
+
* to collect events for the next frame.
|
|
118
|
+
*
|
|
119
|
+
* After calling this method:
|
|
120
|
+
* - `get()` will return a stable snapshot of events produced in the previous frame.
|
|
121
|
+
* - `add()` will write into an empty buffer for the current frame.
|
|
122
|
+
*
|
|
123
|
+
* Guarantees:
|
|
124
|
+
* - No events written during the current frame are visible until the next `swap()`.
|
|
125
|
+
* - Readers observe a consistent, immutable snapshot within a frame.
|
|
126
|
+
*
|
|
127
|
+
* Expected to be called exactly once per frame, before system execution.
|
|
128
|
+
*/
|
|
129
|
+
swap(): void;
|
|
130
|
+
read(): ReadonlyArray<T>;
|
|
131
|
+
size(): number;
|
|
132
|
+
}
|
|
133
|
+
type EventKey<T> = symbol & {
|
|
134
|
+
__type?: T;
|
|
135
|
+
};
|
|
136
|
+
declare function createEventKey<T>(description?: string): EventKey<T>;
|
|
137
|
+
declare class EventBus {
|
|
138
|
+
private storage;
|
|
139
|
+
swapAll(): void;
|
|
140
|
+
getBuffer<T>(key: EventKey<T>): EventBuffer<T>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class ResourcesManager {
|
|
144
|
+
private readonly items_;
|
|
145
|
+
insert<T extends object>(type: ClassType<T>, value: T): T;
|
|
146
|
+
get<T extends object>(type: ClassType<T>): T;
|
|
147
|
+
getOrInsert<T extends object>(type: ClassType<T>, factory: () => T): T;
|
|
148
|
+
remove<T>(type: ClassType<T>): void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
type WorldCommand = (world: World) => void;
|
|
152
|
+
type ComponentInitFn<C extends ComponentType> = (component: InstanceType<C>) => void;
|
|
153
|
+
type CreateEntityComponentEntry<T extends ComponentType = ComponentType> = T extends unknown ? [T, ComponentInitFn<T>] : never;
|
|
154
|
+
declare function entry<T extends ComponentType>(component: T, init?: ComponentInitFn<T>): CreateEntityComponentEntry;
|
|
155
|
+
declare class Commands {
|
|
156
|
+
private readonly world;
|
|
157
|
+
private readonly commandsQueue_;
|
|
158
|
+
constructor(world: World);
|
|
159
|
+
add(cmd: WorldCommand): void;
|
|
160
|
+
flush(world: World): void;
|
|
161
|
+
createEntity(...entries: CreateEntityComponentEntry[]): number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
type QueryParameters = {
|
|
165
|
+
include?: ComponentType[];
|
|
166
|
+
exclude?: ComponentType[];
|
|
167
|
+
anyOf?: ComponentType[];
|
|
168
|
+
excludeEntitiesIds?: number[];
|
|
169
|
+
filter?: (id: number) => boolean;
|
|
170
|
+
};
|
|
171
|
+
declare class QueryManager {
|
|
172
|
+
private readonly world;
|
|
173
|
+
private cache;
|
|
174
|
+
constructor(world: World);
|
|
175
|
+
get(params: QueryParameters): EntityID[];
|
|
176
|
+
invalidate(component: ComponentType): void;
|
|
177
|
+
private getKey;
|
|
178
|
+
private ids;
|
|
179
|
+
private collectDeps;
|
|
180
|
+
private compute;
|
|
181
|
+
private combineBitmaps;
|
|
182
|
+
private applyExclusions;
|
|
183
|
+
private extractIds;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
type PluginID = string;
|
|
187
|
+
type PluginDependencies = {
|
|
188
|
+
components?: ComponentType$1[];
|
|
189
|
+
resources?: ClassType<any>[];
|
|
190
|
+
systems?: ClassType<SystemBase>[];
|
|
191
|
+
plugins?: Array<{
|
|
192
|
+
id: PluginID;
|
|
193
|
+
version?: string;
|
|
194
|
+
}>;
|
|
195
|
+
};
|
|
196
|
+
interface PluginMetadata {
|
|
197
|
+
id: PluginID;
|
|
198
|
+
version: string;
|
|
199
|
+
name: string;
|
|
200
|
+
dependencies?: PluginDependencies;
|
|
201
|
+
}
|
|
202
|
+
declare function Plugin(metadata: PluginMetadata): ClassDecorator;
|
|
203
|
+
declare function getPluginMetadata(plugin: ClassType<PluginBase>): PluginMetadata;
|
|
204
|
+
declare function isPlugin(ctor: Function): boolean;
|
|
205
|
+
declare abstract class PluginBase {
|
|
206
|
+
onPluginLoad?: (world: World) => void;
|
|
207
|
+
onPluginUnload?: (world: World) => void;
|
|
208
|
+
onAfterWorldInit?: (world: World) => void;
|
|
209
|
+
}
|
|
210
|
+
declare class PluginError extends Error {
|
|
211
|
+
constructor(pluginId: string);
|
|
212
|
+
}
|
|
213
|
+
declare class ErrNotAPlugin extends Error {
|
|
214
|
+
constructor(target: Function);
|
|
215
|
+
}
|
|
216
|
+
declare class ErrMissingPluginMetadata extends Error {
|
|
217
|
+
constructor(plugin: ClassType<PluginBase>);
|
|
218
|
+
}
|
|
219
|
+
declare class ErrUnknownPlugin extends PluginError {
|
|
220
|
+
constructor(pluginId: string);
|
|
221
|
+
}
|
|
222
|
+
declare class ErrPluginNotInit extends PluginError {
|
|
223
|
+
constructor(pluginId: string);
|
|
224
|
+
}
|
|
225
|
+
declare class PluginsManager {
|
|
226
|
+
private plugins_;
|
|
227
|
+
private isInitiated_;
|
|
228
|
+
install<T extends ClassType<PluginBase>>(plugin: T, ...constructorProps: ConstructorParameters<T>): void;
|
|
229
|
+
build(): void;
|
|
230
|
+
getPluginMetadata(pluginOrId: ClassType<PluginBase> | PluginID): PluginMetadata;
|
|
231
|
+
getPluginInstance<T extends PluginBase>(pluginOrId: ClassType<T> | PluginID): T;
|
|
232
|
+
private resolveId;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
declare class World {
|
|
236
|
+
readonly entities: EntitiesManager;
|
|
237
|
+
readonly components: ComponentsManager;
|
|
238
|
+
readonly systems: SystemsManager;
|
|
239
|
+
readonly events: EventBus;
|
|
240
|
+
readonly resources: ResourcesManager;
|
|
241
|
+
readonly commands: Commands;
|
|
242
|
+
readonly queries: QueryManager;
|
|
243
|
+
readonly plugins: PluginsManager;
|
|
244
|
+
private entityRefs_;
|
|
245
|
+
constructor(maxEntityCount?: number);
|
|
246
|
+
getEntityRef(id: number): EntityRef;
|
|
247
|
+
query(params: QueryParameters): number[];
|
|
248
|
+
removeComponent<T extends object>(ref: EntityRef, component: ComponentType$1<T>): void;
|
|
249
|
+
removeComponent<T extends object>(entity: EntityID, component: ComponentType$1<T>): void;
|
|
250
|
+
addComponent<T extends object>(id: EntityID, component: ClassType<T>, initFn?: (obj: T) => void): T;
|
|
251
|
+
addComponent<T extends object>(id: EntityRef, component: ClassType<T>, initFn?: (obj: T) => void): T;
|
|
252
|
+
update(dt: number): void;
|
|
253
|
+
build(): void;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
declare class SystemError extends Error {
|
|
257
|
+
constructor(target: Function);
|
|
258
|
+
}
|
|
259
|
+
declare class ErrNotASystem extends Error {
|
|
260
|
+
constructor(target: Function);
|
|
261
|
+
}
|
|
262
|
+
declare class ErrMissingSystemMetadata extends SystemError {
|
|
263
|
+
constructor(target: SystemCtor);
|
|
264
|
+
}
|
|
265
|
+
type SystemMetadata = {
|
|
266
|
+
/**
|
|
267
|
+
* ECS query definition used to select entities for this system execution.
|
|
268
|
+
*
|
|
269
|
+
* Determines the iteration set passed to {@link SystemBase.compute}.
|
|
270
|
+
* The ECS runtime resolves entities based on this query each update.
|
|
271
|
+
*/
|
|
272
|
+
query: Readonly<QueryParameters>;
|
|
273
|
+
/**
|
|
274
|
+
* Explicit list of component types required by the system but not necessarily
|
|
275
|
+
* part of the iteration query.
|
|
276
|
+
*
|
|
277
|
+
* Used for:
|
|
278
|
+
* - ensuring component storages are initialized in the world
|
|
279
|
+
* - safe access via `world.components.getStorage`
|
|
280
|
+
* - dependencies that should not affect entity selection
|
|
281
|
+
*
|
|
282
|
+
* This does NOT influence entity iteration; only runtime validation/setup.
|
|
283
|
+
*/
|
|
284
|
+
requiredComponents: Set<ComponentType$1>;
|
|
285
|
+
/**
|
|
286
|
+
* Systems that must run before this one. Pass constructor arguments
|
|
287
|
+
* `super(OtherSystemCtor, ...)` to add edges; each listed system is scheduled earlier than
|
|
288
|
+
* this instance. Used when {@link SystemsManager.build} computes a topological execution order.
|
|
289
|
+
*/
|
|
290
|
+
computeAfter?: Set<SystemCtor>;
|
|
291
|
+
};
|
|
292
|
+
type SystemDecoratorProps = {
|
|
293
|
+
query: SystemMetadata['query'];
|
|
294
|
+
requiredComponents?: ComponentType$1[];
|
|
295
|
+
computeAfter?: SystemCtor[];
|
|
296
|
+
};
|
|
297
|
+
declare function System(props: SystemDecoratorProps): ClassDecorator;
|
|
298
|
+
declare function getSystemMetadata(system: SystemCtor): SystemMetadata;
|
|
299
|
+
declare function isSystem(ctor: Function): boolean;
|
|
300
|
+
type SystemCtor<T extends SystemBase = SystemBase> = ClassType<T>;
|
|
301
|
+
/**
|
|
302
|
+
* Arguments passed to {@link SystemBase.compute} on each {@link SystemsManager.update} call.
|
|
303
|
+
*/
|
|
304
|
+
type SystemComputeContext = {
|
|
305
|
+
/** Entity IDs from the query for this {@link SystemBase.compute} invocation. */
|
|
306
|
+
entities: number[];
|
|
307
|
+
/** ECS world instance. */
|
|
308
|
+
world: World;
|
|
309
|
+
/** Delta time (seconds or your engine's convention) since the previous update. */
|
|
310
|
+
dt: number;
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* Base class for ECS systems executed by {@link SystemsManager}.
|
|
314
|
+
*
|
|
315
|
+
* Subclasses declare which components they iterate over (`queryComponents`), which component
|
|
316
|
+
* types must exist in the world for registration (`requiredComponents`), and optional ordering
|
|
317
|
+
* relative to other systems (`computeAfter` / `super(OtherSystem)`).
|
|
318
|
+
*/
|
|
319
|
+
declare abstract class SystemBase {
|
|
320
|
+
/**
|
|
321
|
+
* Logic for one systems pass: run for all entities in {@link SystemComputeContext.entities}.
|
|
322
|
+
*/
|
|
323
|
+
abstract compute(ctx: SystemComputeContext): void;
|
|
324
|
+
onInit?(world: World): void;
|
|
325
|
+
}
|
|
326
|
+
declare class SystemsManager {
|
|
327
|
+
private readonly world;
|
|
328
|
+
private systems_;
|
|
329
|
+
private executionOrder_;
|
|
330
|
+
private requiredComponents_;
|
|
331
|
+
private dirty_;
|
|
332
|
+
constructor(world: World);
|
|
333
|
+
getRequiredComponents(): ComponentType$1[];
|
|
334
|
+
register<T extends SystemBase>(sys: T): void;
|
|
335
|
+
build(): void;
|
|
336
|
+
private rebuild;
|
|
337
|
+
get<T extends SystemBase>(ctor: SystemCtor<T>): T;
|
|
338
|
+
update(dt: number): void;
|
|
339
|
+
private buildSystemsArray;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
interface TimeSource {
|
|
343
|
+
now(): number;
|
|
344
|
+
}
|
|
345
|
+
declare class Clock {
|
|
346
|
+
private readonly timeSource_;
|
|
347
|
+
private lastTimeMs_;
|
|
348
|
+
private elapsedTime_;
|
|
349
|
+
private dt_;
|
|
350
|
+
constructor(timeSource_: TimeSource);
|
|
351
|
+
get dt(): number;
|
|
352
|
+
get ellapsedTime(): number;
|
|
353
|
+
tick(): void;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
type StepFunction = (dt: number) => void;
|
|
357
|
+
declare class GameLoop {
|
|
358
|
+
private clock;
|
|
359
|
+
private stepFn;
|
|
360
|
+
private running;
|
|
361
|
+
constructor(clock: Clock, stepFn: StepFunction);
|
|
362
|
+
start(platformLoop: (callback: () => void) => void): void;
|
|
363
|
+
stop(): void;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
declare class Runtime {
|
|
367
|
+
readonly world: World;
|
|
368
|
+
readonly assets: AssetsManager;
|
|
369
|
+
constructor(world: World, assets: AssetsManager);
|
|
370
|
+
update(dt: number): void;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export { Clock, Commands, Component, ComponentAlreadyRegisteredError, type ComponentInitFn, ComponentStorage, ComponentsManager, type CreateEntityComponentEntry, EntitiesManager, type EntityID, EntityMaskNotFoundError, EntityRef, ErrMissingPluginMetadata, ErrMissingSystemMetadata, ErrNotAPlugin, ErrNotASystem, ErrPluginNotInit, ErrUnknownPlugin, EventBuffer, EventBus, GameLoop, type IStorage, Plugin, PluginBase, type PluginDependencies, PluginError, type PluginID, type PluginMetadata, PluginsManager, ResourcesManager, Runtime, SingletonStorage, type StepFunction, System, SystemBase, type SystemComputeContext, SystemError, SystemsManager, type TimeSource, UnregisteredComponentStorageError, World, type WorldCommand, createEventKey, entry, getPluginMetadata, getSystemMetadata, isPlugin, isSystem };
|