@multiplekex/shallot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/builder.d.ts +25 -0
- package/dist/core/builder.d.ts.map +1 -0
- package/dist/core/builder.js +88 -0
- package/dist/core/builder.js.map +1 -0
- package/dist/core/component.d.ts +29 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/component.js +36 -0
- package/dist/core/component.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/math.d.ts +32 -0
- package/dist/core/math.d.ts.map +1 -0
- package/dist/core/math.js +39 -0
- package/dist/core/math.js.map +1 -0
- package/dist/core/relation.d.ts +16 -0
- package/dist/core/relation.d.ts.map +1 -0
- package/dist/core/relation.js +32 -0
- package/dist/core/relation.js.map +1 -0
- package/dist/core/resource.d.ts +9 -0
- package/dist/core/resource.d.ts.map +1 -0
- package/dist/core/resource.js +12 -0
- package/dist/core/resource.js.map +1 -0
- package/dist/core/runtime.d.ts +13 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +118 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/scheduler.d.ts +47 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +138 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/state.d.ts +62 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +185 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/strings.d.ts +3 -0
- package/dist/core/strings.d.ts.map +1 -0
- package/dist/core/strings.js +11 -0
- package/dist/core/strings.js.map +1 -0
- package/dist/core/types.d.ts +33 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/xml.d.ts +42 -0
- package/dist/core/xml.d.ts.map +1 -0
- package/dist/core/xml.js +349 -0
- package/dist/core/xml.js.map +1 -0
- package/dist/extras/arrows/index.d.ts +33 -0
- package/dist/extras/arrows/index.d.ts.map +1 -0
- package/dist/extras/arrows/index.js +288 -0
- package/dist/extras/arrows/index.js.map +1 -0
- package/dist/extras/index.d.ts +5 -0
- package/dist/extras/index.d.ts.map +1 -0
- package/dist/extras/index.js +31 -0
- package/dist/extras/index.js.map +1 -0
- package/dist/extras/lines/index.d.ts +36 -0
- package/dist/extras/lines/index.d.ts.map +1 -0
- package/dist/extras/lines/index.js +288 -0
- package/dist/extras/lines/index.js.map +1 -0
- package/dist/extras/orbit/index.d.ts +20 -0
- package/dist/extras/orbit/index.d.ts.map +1 -0
- package/dist/extras/orbit/index.js +93 -0
- package/dist/extras/orbit/index.js.map +1 -0
- package/dist/extras/text/index.d.ts +64 -0
- package/dist/extras/text/index.d.ts.map +1 -0
- package/dist/extras/text/index.js +423 -0
- package/dist/extras/text/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +187 -0
- package/dist/index.js.map +1 -0
- package/dist/rust/transforms/pkg/shallot_transforms.js +107 -0
- package/dist/rust/transforms/pkg/shallot_transforms.js.map +1 -0
- package/dist/standard/compute/graph.d.ts +37 -0
- package/dist/standard/compute/graph.d.ts.map +1 -0
- package/dist/standard/compute/graph.js +85 -0
- package/dist/standard/compute/graph.js.map +1 -0
- package/dist/standard/compute/index.d.ts +21 -0
- package/dist/standard/compute/index.d.ts.map +1 -0
- package/dist/standard/compute/index.js +81 -0
- package/dist/standard/compute/index.js.map +1 -0
- package/dist/standard/defaults.d.ts +3 -0
- package/dist/standard/defaults.d.ts.map +1 -0
- package/dist/standard/defaults.js +18 -0
- package/dist/standard/defaults.js.map +1 -0
- package/dist/standard/index.d.ts +8 -0
- package/dist/standard/index.d.ts.map +1 -0
- package/dist/standard/input/index.d.ts +5 -0
- package/dist/standard/input/index.d.ts.map +1 -0
- package/dist/standard/input/index.js +70 -0
- package/dist/standard/input/index.js.map +1 -0
- package/dist/standard/loading/index.d.ts +7 -0
- package/dist/standard/loading/index.d.ts.map +1 -0
- package/dist/standard/loading/index.js +91 -0
- package/dist/standard/loading/index.js.map +1 -0
- package/dist/standard/render/camera.d.ts +36 -0
- package/dist/standard/render/camera.d.ts.map +1 -0
- package/dist/standard/render/camera.js +71 -0
- package/dist/standard/render/camera.js.map +1 -0
- package/dist/standard/render/forward.d.ts +30 -0
- package/dist/standard/render/forward.d.ts.map +1 -0
- package/dist/standard/render/forward.js +158 -0
- package/dist/standard/render/forward.js.map +1 -0
- package/dist/standard/render/index.d.ts +22 -0
- package/dist/standard/render/index.d.ts.map +1 -0
- package/dist/standard/render/index.js +153 -0
- package/dist/standard/render/index.js.map +1 -0
- package/dist/standard/render/light.d.ts +25 -0
- package/dist/standard/render/light.d.ts.map +1 -0
- package/dist/standard/render/light.js +48 -0
- package/dist/standard/render/light.js.map +1 -0
- package/dist/standard/render/mesh/box.d.ts +3 -0
- package/dist/standard/render/mesh/box.d.ts.map +1 -0
- package/dist/standard/render/mesh/box.js +190 -0
- package/dist/standard/render/mesh/box.js.map +1 -0
- package/dist/standard/render/mesh/index.d.ts +52 -0
- package/dist/standard/render/mesh/index.d.ts.map +1 -0
- package/dist/standard/render/mesh/index.js +158 -0
- package/dist/standard/render/mesh/index.js.map +1 -0
- package/dist/standard/render/mesh/plane.d.ts +3 -0
- package/dist/standard/render/mesh/plane.d.ts.map +1 -0
- package/dist/standard/render/mesh/plane.js +33 -0
- package/dist/standard/render/mesh/plane.js.map +1 -0
- package/dist/standard/render/mesh/sphere.d.ts +3 -0
- package/dist/standard/render/mesh/sphere.d.ts.map +1 -0
- package/dist/standard/render/mesh/sphere.js +25 -0
- package/dist/standard/render/mesh/sphere.js.map +1 -0
- package/dist/standard/render/postprocess.d.ts +11 -0
- package/dist/standard/render/postprocess.d.ts.map +1 -0
- package/dist/standard/render/postprocess.js +190 -0
- package/dist/standard/render/postprocess.js.map +1 -0
- package/dist/standard/render/scene.d.ts +8 -0
- package/dist/standard/render/scene.d.ts.map +1 -0
- package/dist/standard/render/scene.js +67 -0
- package/dist/standard/render/scene.js.map +1 -0
- package/dist/standard/transforms/index.d.ts +27 -0
- package/dist/standard/transforms/index.d.ts.map +1 -0
- package/dist/standard/transforms/index.js +122 -0
- package/dist/standard/transforms/index.js.map +1 -0
- package/dist/standard/transforms/wasm.d.ts +17 -0
- package/dist/standard/transforms/wasm.d.ts.map +1 -0
- package/dist/standard/transforms/wasm.js +31 -0
- package/dist/standard/transforms/wasm.js.map +1 -0
- package/dist/standard/tween/easing.d.ts +5 -0
- package/dist/standard/tween/easing.d.ts.map +1 -0
- package/dist/standard/tween/easing.js +80 -0
- package/dist/standard/tween/easing.js.map +1 -0
- package/dist/standard/tween/index.d.ts +4 -0
- package/dist/standard/tween/index.d.ts.map +1 -0
- package/dist/standard/tween/sequence.d.ts +20 -0
- package/dist/standard/tween/sequence.d.ts.map +1 -0
- package/dist/standard/tween/sequence.js +95 -0
- package/dist/standard/tween/sequence.js.map +1 -0
- package/dist/standard/tween/tween.d.ts +28 -0
- package/dist/standard/tween/tween.d.ts.map +1 -0
- package/dist/standard/tween/tween.js +136 -0
- package/dist/standard/tween/tween.js.map +1 -0
- package/package.json +63 -0
- package/src/core/builder.ts +148 -0
- package/src/core/component.ts +71 -0
- package/src/core/index.ts +92 -0
- package/src/core/math.ts +128 -0
- package/src/core/relation.ts +46 -0
- package/src/core/resource.ts +18 -0
- package/src/core/runtime.ts +185 -0
- package/src/core/scheduler.ts +238 -0
- package/src/core/state.ts +295 -0
- package/src/core/strings.ts +10 -0
- package/src/core/types.ts +37 -0
- package/src/core/xml.ts +676 -0
- package/src/extras/arrows/index.ts +363 -0
- package/src/extras/index.ts +4 -0
- package/src/extras/lines/index.ts +368 -0
- package/src/extras/orbit/index.ts +133 -0
- package/src/extras/text/index.ts +641 -0
- package/src/index.ts +3 -0
- package/src/standard/compute/graph.ts +165 -0
- package/src/standard/compute/index.ts +116 -0
- package/src/standard/defaults.ts +17 -0
- package/src/standard/index.ts +7 -0
- package/src/standard/input/index.ts +142 -0
- package/src/standard/loading/index.ts +136 -0
- package/src/standard/render/camera.ts +87 -0
- package/src/standard/render/forward.ts +212 -0
- package/src/standard/render/index.ts +175 -0
- package/src/standard/render/light.ts +81 -0
- package/src/standard/render/mesh/box.ts +20 -0
- package/src/standard/render/mesh/index.ts +227 -0
- package/src/standard/render/mesh/plane.ts +11 -0
- package/src/standard/render/mesh/sphere.ts +40 -0
- package/src/standard/render/postprocess.ts +235 -0
- package/src/standard/render/scene.ts +116 -0
- package/src/standard/transforms/index.ts +184 -0
- package/src/standard/transforms/wasm.ts +61 -0
- package/src/standard/tween/easing.ts +169 -0
- package/src/standard/tween/index.ts +13 -0
- package/src/standard/tween/sequence.ts +142 -0
- package/src/standard/tween/tween.ts +265 -0
- package/src/vite-env.d.ts +6 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addComponent,
|
|
3
|
+
addEntity,
|
|
4
|
+
createWorld,
|
|
5
|
+
entityExists,
|
|
6
|
+
getAllEntities,
|
|
7
|
+
getComponent,
|
|
8
|
+
getEntityComponents,
|
|
9
|
+
getRelationTargets,
|
|
10
|
+
hasComponent,
|
|
11
|
+
query,
|
|
12
|
+
removeComponent,
|
|
13
|
+
removeComponents,
|
|
14
|
+
removeEntity,
|
|
15
|
+
type ComponentRef,
|
|
16
|
+
type World,
|
|
17
|
+
} from "bitecs";
|
|
18
|
+
import { Scheduler, Time, type GameTime, type System } from "./scheduler";
|
|
19
|
+
import type { RelationDef } from "./relation";
|
|
20
|
+
import type { Plugin } from "./types";
|
|
21
|
+
import type { StateBuilder } from "./builder";
|
|
22
|
+
import { initRuntime, type Runtime } from "./runtime";
|
|
23
|
+
import {
|
|
24
|
+
registerComponent,
|
|
25
|
+
getTraits,
|
|
26
|
+
getRegisteredComponent,
|
|
27
|
+
directAccessor,
|
|
28
|
+
type ComponentData,
|
|
29
|
+
type FieldAccessor,
|
|
30
|
+
} from "./component";
|
|
31
|
+
import { type ResourceKey } from "./resource";
|
|
32
|
+
import { toCamelCase } from "./strings";
|
|
33
|
+
|
|
34
|
+
export const MAX_ENTITIES = 65536;
|
|
35
|
+
|
|
36
|
+
export class State {
|
|
37
|
+
readonly world: World;
|
|
38
|
+
readonly scheduler = new Scheduler();
|
|
39
|
+
readonly canvas: HTMLCanvasElement | null;
|
|
40
|
+
|
|
41
|
+
private _resources = new Map<symbol, unknown>();
|
|
42
|
+
private _disposed = false;
|
|
43
|
+
private _running = false;
|
|
44
|
+
private _runtime: Runtime | null = null;
|
|
45
|
+
private _lastTime = 0;
|
|
46
|
+
private _fieldAccessors: Map<number, FieldAccessor> | null = null;
|
|
47
|
+
|
|
48
|
+
get time(): Readonly<GameTime> {
|
|
49
|
+
return this.scheduler.time;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get running(): boolean {
|
|
53
|
+
return this._running;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static Builder: (new () => StateBuilder) | null = null;
|
|
57
|
+
|
|
58
|
+
static new(): StateBuilder {
|
|
59
|
+
if (!State.Builder) {
|
|
60
|
+
throw new Error("StateBuilder not injected. Import from 'shallot' or 'shallot/core'.");
|
|
61
|
+
}
|
|
62
|
+
return new State.Builder();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
constructor(canvas: HTMLCanvasElement | null = null) {
|
|
66
|
+
this.world = createWorld();
|
|
67
|
+
this.canvas = canvas;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setResource<T>(key: ResourceKey<T>, value: T): void {
|
|
71
|
+
this._resources.set(key, value);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getResource<T>(key: ResourceKey<T>): T | undefined {
|
|
75
|
+
return this._resources.get(key) as T | undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
deleteResource<T>(key: ResourceKey<T>): boolean {
|
|
79
|
+
return this._resources.delete(key);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async start(runtime?: Runtime): Promise<void> {
|
|
83
|
+
if (this._running) return;
|
|
84
|
+
this._runtime = runtime ?? (await initRuntime());
|
|
85
|
+
this._running = true;
|
|
86
|
+
this._lastTime = this._runtime.now();
|
|
87
|
+
this.scheduleFrame();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
stop(): void {
|
|
91
|
+
this._running = false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private scheduleFrame(): void {
|
|
95
|
+
if (!this._running || !this._runtime) return;
|
|
96
|
+
this._runtime.requestFrame(() => this.tick());
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private tick(): void {
|
|
100
|
+
if (!this._running || !this._runtime) return;
|
|
101
|
+
const now = this._runtime.now();
|
|
102
|
+
const dt = (now - this._lastTime) / 1000;
|
|
103
|
+
this._lastTime = now;
|
|
104
|
+
this.step(dt);
|
|
105
|
+
this.scheduleFrame();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
register(pluginOrSystem: Plugin | System): void {
|
|
109
|
+
if (
|
|
110
|
+
"update" in pluginOrSystem ||
|
|
111
|
+
"setup" in pluginOrSystem ||
|
|
112
|
+
"dispose" in pluginOrSystem
|
|
113
|
+
) {
|
|
114
|
+
this.scheduler.register(pluginOrSystem as System);
|
|
115
|
+
} else {
|
|
116
|
+
const plugin = pluginOrSystem as Plugin;
|
|
117
|
+
if (plugin.components) {
|
|
118
|
+
for (const [name, component] of Object.entries(plugin.components)) {
|
|
119
|
+
registerComponent(name, component);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (plugin.systems) {
|
|
123
|
+
for (const system of plugin.systems) {
|
|
124
|
+
this.scheduler.register(system);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
unregister(system: System): void {
|
|
131
|
+
this.scheduler.unregister(system);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
step(deltaTime = Time.DEFAULT_DT): void {
|
|
135
|
+
this.scheduler.step(this, deltaTime);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
addEntity(): number {
|
|
139
|
+
const eid = addEntity(this.world);
|
|
140
|
+
if (eid >= MAX_ENTITIES) {
|
|
141
|
+
throw new Error(`Entity limit exceeded: ${eid} >= ${MAX_ENTITIES}`);
|
|
142
|
+
}
|
|
143
|
+
return eid;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
removeEntity(eid: number): void {
|
|
147
|
+
this._fieldAccessors?.delete(eid);
|
|
148
|
+
removeEntity(this.world, eid);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
entityExists(eid: number): boolean {
|
|
152
|
+
return entityExists(this.world, eid);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
getAllEntities(): readonly number[] {
|
|
156
|
+
return getAllEntities(this.world);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
query(terms: ComponentRef[]): Iterable<number> {
|
|
160
|
+
return query(this.world, terms);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
getEntityComponents(eid: number): ComponentRef[] {
|
|
164
|
+
return getEntityComponents(this.world, eid);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
addComponent<T extends ComponentRef>(eid: number, component: T): void {
|
|
168
|
+
addComponent(this.world, eid, component);
|
|
169
|
+
|
|
170
|
+
const traits = getTraits(component as ComponentData);
|
|
171
|
+
if (traits?.defaults) {
|
|
172
|
+
const defaults = traits.defaults();
|
|
173
|
+
const comp = component as ComponentData;
|
|
174
|
+
for (const [field, value] of Object.entries(defaults)) {
|
|
175
|
+
const arr = comp[field];
|
|
176
|
+
if (arr != null) {
|
|
177
|
+
arr[eid] = value;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
addComponents(eid: number, ...components: ComponentRef[]): void {
|
|
184
|
+
for (const component of components) {
|
|
185
|
+
this.addComponent(eid, component);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
removeComponent(eid: number, ...components: ComponentRef[]): void {
|
|
190
|
+
removeComponent(this.world, eid, ...components);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
removeComponents(eid: number, ...components: ComponentRef[]): void {
|
|
194
|
+
removeComponents(this.world, eid, ...components);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
hasComponent<T extends ComponentRef>(eid: number, component: T): boolean {
|
|
198
|
+
return hasComponent(this.world, eid, component);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
getComponent<T extends ComponentRef>(eid: number, component: T) {
|
|
202
|
+
return getComponent(this.world, eid, component);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
setComponent<T extends ComponentRef>(
|
|
206
|
+
eid: number,
|
|
207
|
+
component: T,
|
|
208
|
+
data: Record<string, number>
|
|
209
|
+
): void {
|
|
210
|
+
this.addComponent(eid, component);
|
|
211
|
+
const comp = component as Record<string, number[]>;
|
|
212
|
+
for (const [field, value] of Object.entries(data)) {
|
|
213
|
+
const arr = comp[field];
|
|
214
|
+
if (arr != null) {
|
|
215
|
+
arr[eid] = value;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
addRelation(subject: number, relation: RelationDef, target: number): void {
|
|
221
|
+
addComponent(this.world, subject, relation.relation(target));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
hasRelation(subject: number, relation: RelationDef, target: number): boolean {
|
|
225
|
+
return hasComponent(this.world, subject, relation.relation(target));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
getRelationTargets(subject: number, relation: RelationDef): number[] {
|
|
229
|
+
return getRelationTargets(this.world, subject, relation.relation);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
getFirstRelationTarget(subject: number, relation: RelationDef): number {
|
|
233
|
+
const targets = getRelationTargets(this.world, subject, relation.relation);
|
|
234
|
+
return targets.length > 0 ? targets[0] : -1;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private ensureFieldAccessors(): Map<number, FieldAccessor> {
|
|
238
|
+
if (!this._fieldAccessors) {
|
|
239
|
+
this._fieldAccessors = new Map();
|
|
240
|
+
}
|
|
241
|
+
return this._fieldAccessors;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
resolveFieldPath(path: string): { component: string; field: string } | null {
|
|
245
|
+
const dotIndex = path.lastIndexOf(".");
|
|
246
|
+
if (dotIndex === -1) return null;
|
|
247
|
+
return {
|
|
248
|
+
component: path.slice(0, dotIndex),
|
|
249
|
+
field: path.slice(dotIndex + 1),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
bindFieldAccessor(
|
|
254
|
+
bindingId: number,
|
|
255
|
+
componentName: string,
|
|
256
|
+
fieldPath: string
|
|
257
|
+
): FieldAccessor | null {
|
|
258
|
+
const registered = getRegisteredComponent(componentName);
|
|
259
|
+
if (!registered) return null;
|
|
260
|
+
|
|
261
|
+
const camelPath = toCamelCase(fieldPath);
|
|
262
|
+
|
|
263
|
+
const traits = getTraits(registered.component);
|
|
264
|
+
if (traits?.accessors?.[camelPath]) {
|
|
265
|
+
const accessor = traits.accessors[camelPath];
|
|
266
|
+
this.ensureFieldAccessors().set(bindingId, accessor);
|
|
267
|
+
return accessor;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const array = registered.component[camelPath];
|
|
271
|
+
if (array == null) return null;
|
|
272
|
+
|
|
273
|
+
const accessor = directAccessor(array, 1, 0);
|
|
274
|
+
this.ensureFieldAccessors().set(bindingId, accessor);
|
|
275
|
+
return accessor;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
getFieldAccessor(bindingId: number): FieldAccessor | undefined {
|
|
279
|
+
return this._fieldAccessors?.get(bindingId);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
removeFieldAccessor(bindingId: number): boolean {
|
|
283
|
+
return this._fieldAccessors?.delete(bindingId) ?? false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
dispose(): void {
|
|
287
|
+
if (this._disposed) return;
|
|
288
|
+
this.stop();
|
|
289
|
+
this._fieldAccessors = null;
|
|
290
|
+
for (const system of this.scheduler.systems) {
|
|
291
|
+
system.dispose?.(this);
|
|
292
|
+
}
|
|
293
|
+
this._disposed = true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function toKebabCase(str: string): string {
|
|
2
|
+
return str
|
|
3
|
+
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
|
4
|
+
.replace(/[\s_]+/g, "-")
|
|
5
|
+
.toLowerCase();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function toCamelCase(str: string): string {
|
|
9
|
+
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
10
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { System } from "./scheduler";
|
|
2
|
+
import type { ComponentData } from "./component";
|
|
3
|
+
import type { RelationDef } from "./relation";
|
|
4
|
+
import type { State } from "./state";
|
|
5
|
+
|
|
6
|
+
export interface Plugin {
|
|
7
|
+
readonly systems?: readonly System[];
|
|
8
|
+
readonly components?: Record<string, ComponentData>;
|
|
9
|
+
readonly relations?: readonly RelationDef[];
|
|
10
|
+
readonly dependencies?: readonly Plugin[];
|
|
11
|
+
readonly initialize?: (state: State) => void | Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Loading {
|
|
15
|
+
show(): (() => void) | void;
|
|
16
|
+
update(progress: number): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface MouseState {
|
|
20
|
+
deltaX: number;
|
|
21
|
+
deltaY: number;
|
|
22
|
+
scrollDelta: number;
|
|
23
|
+
left: boolean;
|
|
24
|
+
right: boolean;
|
|
25
|
+
middle: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface InputState {
|
|
29
|
+
readonly mouse: Readonly<MouseState>;
|
|
30
|
+
isKeyDown(code: string): boolean;
|
|
31
|
+
isKeyPressed(code: string): boolean;
|
|
32
|
+
isKeyReleased(code: string): boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface RenderContext {
|
|
36
|
+
readonly gpu: unknown;
|
|
37
|
+
}
|