@codehz/ecs 0.1.6 → 0.1.8
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 +3 -3
- package/index.js +29 -8
- package/package.json +1 -1
- package/system-scheduler.d.ts +5 -2
- package/system.d.ts +1 -1
- package/world.d.ts +4 -2
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ bun run examples/simple/demo.ts
|
|
|
176
176
|
- `delete(entity, componentId)`: 从实体移除组件
|
|
177
177
|
- `setExclusive(componentId)`: 将组件标记为独占关系
|
|
178
178
|
- `createQuery(componentIds)`: 创建查询
|
|
179
|
-
- `registerSystem(system)`: 注册系统
|
|
179
|
+
- `registerSystem(system, dependencies?)`: 注册系统
|
|
180
180
|
- `registerLifecycleHook(componentId, hook)`: 注册组件或通配符关系生命周期钩子
|
|
181
181
|
- `unregisterLifecycleHook(componentId, hook)`: 注销组件或通配符关系生命周期钩子
|
|
182
182
|
- `update(...params)`: 更新世界(参数取决于泛型配置)
|
|
@@ -289,7 +289,7 @@ class MovementSystem implements System<[deltaTime: number]> {
|
|
|
289
289
|
}
|
|
290
290
|
```
|
|
291
291
|
|
|
292
|
-
|
|
292
|
+
系统支持依赖关系排序,确保正确的执行顺序。依赖关系可以通过系统的 `dependencies` 属性指定:
|
|
293
293
|
|
|
294
294
|
```typescript
|
|
295
295
|
class InputSystem implements System<[deltaTime: number]> {
|
|
@@ -314,7 +314,7 @@ class MovementSystem implements System<[deltaTime: number]> {
|
|
|
314
314
|
// 注册系统
|
|
315
315
|
const inputSystem = new InputSystem();
|
|
316
316
|
world.registerSystem(inputSystem);
|
|
317
|
-
world.registerSystem(new MovementSystem(inputSystem));
|
|
317
|
+
world.registerSystem(new MovementSystem(inputSystem), [inputSystem]); // 也可以在注册时指定额外依赖
|
|
318
318
|
```
|
|
319
319
|
|
|
320
320
|
系统将按照拓扑排序执行,依赖系统始终在被依赖系统之前运行。
|
package/index.js
CHANGED
|
@@ -617,12 +617,14 @@ class Query {
|
|
|
617
617
|
// src/system-scheduler.ts
|
|
618
618
|
class SystemScheduler {
|
|
619
619
|
systems = new Set;
|
|
620
|
+
systemDependencies = new Map;
|
|
620
621
|
cachedExecutionOrder = null;
|
|
621
|
-
addSystem(system) {
|
|
622
|
+
addSystem(system, additionalDeps = []) {
|
|
622
623
|
this.systems.add(system);
|
|
623
624
|
for (const dep of system.dependencies || []) {
|
|
624
625
|
this.systems.add(dep);
|
|
625
626
|
}
|
|
627
|
+
this.systemDependencies.set(system, new Set([...additionalDeps, ...system.dependencies || []]));
|
|
626
628
|
this.cachedExecutionOrder = null;
|
|
627
629
|
}
|
|
628
630
|
getExecutionOrder() {
|
|
@@ -639,7 +641,7 @@ class SystemScheduler {
|
|
|
639
641
|
throw new Error("Circular dependency detected in system scheduling");
|
|
640
642
|
}
|
|
641
643
|
visiting.add(system);
|
|
642
|
-
for (const dep of system
|
|
644
|
+
for (const dep of this.systemDependencies.get(system) || []) {
|
|
643
645
|
visit(dep);
|
|
644
646
|
}
|
|
645
647
|
visiting.delete(system);
|
|
@@ -654,6 +656,24 @@ class SystemScheduler {
|
|
|
654
656
|
this.cachedExecutionOrder = result;
|
|
655
657
|
return result;
|
|
656
658
|
}
|
|
659
|
+
update(...params) {
|
|
660
|
+
const executionOrder = this.getExecutionOrder();
|
|
661
|
+
const systemPromises = new Map;
|
|
662
|
+
for (const system of executionOrder) {
|
|
663
|
+
const deps = Array.from(this.systemDependencies.get(system) || []);
|
|
664
|
+
const depPromises = deps.map((dep) => systemPromises.get(dep)).filter(Boolean);
|
|
665
|
+
if (depPromises.length > 0) {
|
|
666
|
+
const promise = Promise.all(depPromises).then(() => system.update(...params));
|
|
667
|
+
systemPromises.set(system, promise);
|
|
668
|
+
} else {
|
|
669
|
+
const result = system.update(...params);
|
|
670
|
+
if (result instanceof Promise) {
|
|
671
|
+
systemPromises.set(system, result);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return Promise.all(systemPromises.values());
|
|
676
|
+
}
|
|
657
677
|
clear() {
|
|
658
678
|
this.systems.clear();
|
|
659
679
|
this.cachedExecutionOrder = null;
|
|
@@ -801,8 +821,8 @@ class World {
|
|
|
801
821
|
}
|
|
802
822
|
return archetype.get(entityId, componentType);
|
|
803
823
|
}
|
|
804
|
-
registerSystem(system) {
|
|
805
|
-
this.systemScheduler.addSystem(system);
|
|
824
|
+
registerSystem(system, additionalDeps = []) {
|
|
825
|
+
this.systemScheduler.addSystem(system, additionalDeps);
|
|
806
826
|
}
|
|
807
827
|
registerLifecycleHook(componentType, hook) {
|
|
808
828
|
if (!this.lifecycleHooks.has(componentType)) {
|
|
@@ -823,11 +843,12 @@ class World {
|
|
|
823
843
|
this.exclusiveComponents.add(componentId);
|
|
824
844
|
}
|
|
825
845
|
update(...params) {
|
|
826
|
-
const
|
|
827
|
-
|
|
828
|
-
|
|
846
|
+
const result = this.systemScheduler.update(...params);
|
|
847
|
+
if (result instanceof Promise) {
|
|
848
|
+
return result.then(() => this.commandBuffer.execute());
|
|
849
|
+
} else {
|
|
850
|
+
this.commandBuffer.execute();
|
|
829
851
|
}
|
|
830
|
-
this.commandBuffer.execute();
|
|
831
852
|
}
|
|
832
853
|
sync() {
|
|
833
854
|
this.commandBuffer.execute();
|
package/package.json
CHANGED
package/system-scheduler.d.ts
CHANGED
|
@@ -2,19 +2,22 @@ import type { System } from "./system";
|
|
|
2
2
|
/**
|
|
3
3
|
* System Scheduler for managing system dependencies and execution order
|
|
4
4
|
*/
|
|
5
|
-
export declare class SystemScheduler<UpdateParams extends any[] = [
|
|
5
|
+
export declare class SystemScheduler<UpdateParams extends any[] = []> {
|
|
6
6
|
private systems;
|
|
7
|
+
private systemDependencies;
|
|
7
8
|
private cachedExecutionOrder;
|
|
8
9
|
/**
|
|
9
10
|
* Add a system with optional dependencies
|
|
10
11
|
* @param system The system to add
|
|
12
|
+
* @param additionalDeps Additional dependencies for the system
|
|
11
13
|
*/
|
|
12
|
-
addSystem(system: System<UpdateParams>): void;
|
|
14
|
+
addSystem(system: System<UpdateParams>, additionalDeps?: System<UpdateParams>[]): void;
|
|
13
15
|
/**
|
|
14
16
|
* Get the execution order of systems based on dependencies
|
|
15
17
|
* Uses topological sort
|
|
16
18
|
*/
|
|
17
19
|
getExecutionOrder(): System<UpdateParams>[];
|
|
20
|
+
update(...params: UpdateParams): Promise<void[]> | void;
|
|
18
21
|
/**
|
|
19
22
|
* Clear all systems and dependencies
|
|
20
23
|
*/
|
package/system.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface System<UpdateParams extends any[] = []> {
|
|
|
5
5
|
/**
|
|
6
6
|
* Update the system
|
|
7
7
|
*/
|
|
8
|
-
update(...params: UpdateParams): void
|
|
8
|
+
update(...params: UpdateParams): void | Promise<void>;
|
|
9
9
|
/**
|
|
10
10
|
* Dependencies of this system (systems that must run before this one)
|
|
11
11
|
*/
|
package/world.d.ts
CHANGED
|
@@ -94,7 +94,7 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
94
94
|
/**
|
|
95
95
|
* Register a system with optional dependencies
|
|
96
96
|
*/
|
|
97
|
-
registerSystem(system: System<UpdateParams>): void;
|
|
97
|
+
registerSystem(system: System<UpdateParams>, additionalDeps?: System<UpdateParams>[]): void;
|
|
98
98
|
/**
|
|
99
99
|
* Register a lifecycle hook for component or wildcard relation events
|
|
100
100
|
*/
|
|
@@ -110,8 +110,10 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
110
110
|
setExclusive(componentId: EntityId): void;
|
|
111
111
|
/**
|
|
112
112
|
* Update the world (run all systems in dependency order)
|
|
113
|
+
* This function is synchronous when all systems are synchronous,
|
|
114
|
+
* and asynchronous (returns a Promise) when any system is asynchronous.
|
|
113
115
|
*/
|
|
114
|
-
update(...params: UpdateParams): void;
|
|
116
|
+
update(...params: UpdateParams): Promise<void> | void;
|
|
115
117
|
/**
|
|
116
118
|
* Execute all deferred commands immediately without running systems
|
|
117
119
|
*/
|