@codehz/ecs 0.0.10 → 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/README.md CHANGED
@@ -38,12 +38,12 @@ const VelocityId = component<Velocity>(2);
38
38
  const world = new World();
39
39
 
40
40
  // 创建实体
41
- const entity = world.createEntity();
42
- world.addComponent(entity, PositionId, { x: 0, y: 0 });
43
- world.addComponent(entity, VelocityId, { x: 1, y: 0.5 });
41
+ const entity = world.new();
42
+ world.set(entity, PositionId, { x: 0, y: 0 });
43
+ world.set(entity, VelocityId, { x: 1, y: 0.5 });
44
44
 
45
45
  // 应用更改
46
- world.flushCommands();
46
+ world.sync();
47
47
 
48
48
  // 创建查询并更新
49
49
  const query = world.createQuery([PositionId, VelocityId]);
@@ -77,8 +77,8 @@ world.registerLifecycleHook(VelocityId, {
77
77
  });
78
78
 
79
79
  // 添加组件时会触发钩子
80
- world.addComponent(entity, PositionId, { x: 0, y: 0 });
81
- world.flushCommands(); // 钩子在这里被调用
80
+ world.set(entity, PositionId, { x: 0, y: 0 });
81
+ world.sync(); // 钩子在这里被调用
82
82
  ```
83
83
 
84
84
  ### 通配符关系生命周期钩子
@@ -98,7 +98,7 @@ const PositionId = component<Position>(1);
98
98
  const world = new World();
99
99
 
100
100
  // 创建实体
101
- const entity = world.createEntity();
101
+ const entity = world.new();
102
102
 
103
103
  // 创建通配符关系ID,用于监听所有 Position 相关的关系
104
104
  const wildcardPositionRelation = relation(PositionId, "*");
@@ -114,10 +114,10 @@ world.registerLifecycleHook(wildcardPositionRelation, {
114
114
  });
115
115
 
116
116
  // 创建实体间的关系
117
- const entity2 = world.createEntity();
117
+ const entity2 = world.new();
118
118
  const positionRelation = relation(PositionId, entity2);
119
- world.addComponent(entity, positionRelation, { x: 10, y: 20 });
120
- world.flushCommands(); // 通配符钩子会被触发
119
+ world.set(entity, positionRelation, { x: 10, y: 20 });
120
+ world.sync(); // 通配符钩子会被触发
121
121
  ```
122
122
 
123
123
  ### Exclusive Relations
@@ -137,20 +137,20 @@ const world = new World();
137
137
  world.setExclusive(ChildOf);
138
138
 
139
139
  // 创建实体
140
- const child = world.createEntity();
141
- const parent1 = world.createEntity();
142
- const parent2 = world.createEntity();
140
+ const child = world.new();
141
+ const parent1 = world.new();
142
+ const parent2 = world.new();
143
143
 
144
144
  // 添加第一个关系
145
- world.addComponent(child, relation(ChildOf, parent1));
146
- world.flushCommands();
147
- console.log(world.hasComponent(child, relation(ChildOf, parent1))); // true
145
+ world.set(child, relation(ChildOf, parent1));
146
+ world.sync();
147
+ console.log(world.has(child, relation(ChildOf, parent1))); // true
148
148
 
149
149
  // 添加第二个关系 - 会自动移除第一个
150
- world.addComponent(child, relation(ChildOf, parent2));
151
- world.flushCommands();
152
- console.log(world.hasComponent(child, relation(ChildOf, parent1))); // false
153
- console.log(world.hasComponent(child, relation(ChildOf, parent2))); // true
150
+ world.set(child, relation(ChildOf, parent2));
151
+ world.sync();
152
+ console.log(world.has(child, relation(ChildOf, parent1))); // false
153
+ console.log(world.has(child, relation(ChildOf, parent2))); // true
154
154
  ```
155
155
 
156
156
  ### 运行示例
@@ -169,16 +169,16 @@ bun run examples/simple/demo.ts
169
169
 
170
170
  ### World
171
171
 
172
- - `createEntity()`: 创建新实体
173
- - `addComponent(entity, componentId, data)`: 向实体添加组件
174
- - `removeComponent(entity, componentId)`: 从实体移除组件
172
+ - `new()`: 创建新实体
173
+ - `set(entity, componentId, data)`: 向实体添加组件
174
+ - `delete(entity, componentId)`: 从实体移除组件
175
175
  - `setExclusive(componentId)`: 将组件标记为独占关系
176
176
  - `createQuery(componentIds)`: 创建查询
177
177
  - `registerSystem(system)`: 注册系统
178
178
  - `registerLifecycleHook(componentId, hook)`: 注册组件或通配符关系生命周期钩子
179
179
  - `unregisterLifecycleHook(componentId, hook)`: 注销组件或通配符关系生命周期钩子
180
180
  - `update(...params)`: 更新世界(参数取决于泛型配置)
181
- - `flushCommands()`: 应用命令缓冲区
181
+ - `sync()`: 应用命令缓冲区
182
182
 
183
183
  ### Entity
184
184
 
package/archetype.d.ts CHANGED
@@ -59,27 +59,27 @@ export declare class Archetype {
59
59
  * Check if an entity is in this archetype
60
60
  * @param entityId The entity to check
61
61
  */
62
- hasEntity(entityId: EntityId): boolean;
62
+ exists(entityId: EntityId): boolean;
63
63
  /**
64
64
  * Get component data for a specific entity and wildcard relation type
65
65
  * Returns an array of all matching relation instances
66
66
  * @param entityId The entity
67
67
  * @param componentType The wildcard relation type
68
68
  */
69
- getComponent<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, any][];
69
+ get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, any][];
70
70
  /**
71
71
  * Get component data for a specific entity and component type
72
72
  * @param entityId The entity
73
73
  * @param componentType The component type
74
74
  */
75
- getComponent<T>(entityId: EntityId, componentType: EntityId<T>): T;
75
+ get<T>(entityId: EntityId, componentType: EntityId<T>): T;
76
76
  /**
77
77
  * Set component data for a specific entity and component type
78
78
  * @param entityId The entity
79
79
  * @param componentType The component type
80
80
  * @param data The component data
81
81
  */
82
- setComponent<T>(entityId: EntityId, componentType: EntityId<T>, data: T): void;
82
+ set<T>(entityId: EntityId, componentType: EntityId<T>, data: T): void;
83
83
  /**
84
84
  * Get all entities in this archetype
85
85
  */
package/changeset.d.ts CHANGED
@@ -8,11 +8,11 @@ export declare class ComponentChangeset {
8
8
  /**
9
9
  * Add a component to the changeset
10
10
  */
11
- addComponent<T>(componentType: EntityId<T>, component: T): void;
11
+ set<T>(componentType: EntityId<T>, component: T): void;
12
12
  /**
13
13
  * Remove a component from the changeset
14
14
  */
15
- removeComponent<T>(componentType: EntityId<T>): void;
15
+ delete<T>(componentType: EntityId<T>): void;
16
16
  /**
17
17
  * Check if the changeset has any changes
18
18
  */
@@ -3,7 +3,7 @@ import type { EntityId } from "./entity";
3
3
  * Command for deferred execution
4
4
  */
5
5
  export interface Command {
6
- type: "addComponent" | "removeComponent" | "destroyEntity";
6
+ type: "set" | "delete" | "destroy";
7
7
  entityId: EntityId;
8
8
  componentType?: EntityId<any>;
9
9
  component?: any;
@@ -21,16 +21,16 @@ export declare class CommandBuffer {
21
21
  /**
22
22
  * Add a component to an entity (deferred)
23
23
  */
24
- addComponent(entityId: EntityId, componentType: EntityId<void>): void;
25
- addComponent<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
24
+ set(entityId: EntityId, componentType: EntityId<void>): void;
25
+ set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
26
26
  /**
27
27
  * Remove a component from an entity (deferred)
28
28
  */
29
- removeComponent<T>(entityId: EntityId, componentType: EntityId<T>): void;
29
+ delete<T>(entityId: EntityId, componentType: EntityId<T>): void;
30
30
  /**
31
31
  * Destroy an entity (deferred)
32
32
  */
33
- destroyEntity(entityId: EntityId): void;
33
+ destroy(entityId: EntityId): void;
34
34
  /**
35
35
  * Execute all commands and clear the buffer
36
36
  */
package/index.js CHANGED
@@ -280,10 +280,10 @@ class Archetype {
280
280
  }
281
281
  return removedData;
282
282
  }
283
- hasEntity(entityId) {
283
+ exists(entityId) {
284
284
  return this.entityToIndex.has(entityId);
285
285
  }
286
- getComponent(entityId, componentType) {
286
+ get(entityId, componentType) {
287
287
  const index = this.entityToIndex.get(entityId);
288
288
  if (index === undefined) {
289
289
  throw new Error(`Entity ${entityId} is not in this archetype`);
@@ -308,7 +308,7 @@ class Archetype {
308
308
  return data === MISSING_COMPONENT ? undefined : data;
309
309
  }
310
310
  }
311
- setComponent(entityId, componentType, data) {
311
+ set(entityId, componentType, data) {
312
312
  if (!this.componentData.has(componentType)) {
313
313
  throw new Error(`Component type ${componentType} is not in this archetype`);
314
314
  }
@@ -392,11 +392,11 @@ class Archetype {
392
392
  class ComponentChangeset {
393
393
  adds = new Map;
394
394
  removes = new Set;
395
- addComponent(componentType, component2) {
395
+ set(componentType, component2) {
396
396
  this.adds.set(componentType, component2);
397
397
  this.removes.delete(componentType);
398
398
  }
399
- removeComponent(componentType) {
399
+ delete(componentType) {
400
400
  this.removes.add(componentType);
401
401
  this.adds.delete(componentType);
402
402
  }
@@ -440,14 +440,14 @@ class CommandBuffer {
440
440
  constructor(executeEntityCommands) {
441
441
  this.executeEntityCommands = executeEntityCommands;
442
442
  }
443
- addComponent(entityId, componentType, component2) {
444
- this.commands.push({ type: "addComponent", entityId, componentType, component: component2 });
443
+ set(entityId, componentType, component2) {
444
+ this.commands.push({ type: "set", entityId, componentType, component: component2 });
445
445
  }
446
- removeComponent(entityId, componentType) {
447
- this.commands.push({ type: "removeComponent", entityId, componentType });
446
+ delete(entityId, componentType) {
447
+ this.commands.push({ type: "delete", entityId, componentType });
448
448
  }
449
- destroyEntity(entityId) {
450
- this.commands.push({ type: "destroyEntity", entityId });
449
+ destroy(entityId) {
450
+ this.commands.push({ type: "destroy", entityId });
451
451
  }
452
452
  execute() {
453
453
  const MAX_ITERATIONS = 100;
@@ -664,7 +664,7 @@ class World {
664
664
  getComponentTypesHash(componentTypes) {
665
665
  return componentTypes.join(",");
666
666
  }
667
- createEntity() {
667
+ new() {
668
668
  const entityId = this.entityIdManager.allocate();
669
669
  let emptyArchetype = this.getOrCreateArchetype([]);
670
670
  emptyArchetype.addEntity(entityId, new Map);
@@ -683,7 +683,7 @@ class World {
683
683
  const currentComponents = new Map;
684
684
  for (const compType of sourceArchetype.componentTypes) {
685
685
  if (compType !== componentType) {
686
- const data = sourceArchetype.getComponent(sourceEntityId, compType);
686
+ const data = sourceArchetype.get(sourceEntityId, compType);
687
687
  if (data !== undefined) {
688
688
  currentComponents.set(compType, data);
689
689
  }
@@ -709,11 +709,11 @@ class World {
709
709
  this.entityToArchetype.delete(entityId);
710
710
  this.entityIdManager.deallocate(entityId);
711
711
  }
712
- hasEntity(entityId) {
712
+ exists(entityId) {
713
713
  return this.entityToArchetype.has(entityId);
714
714
  }
715
- addComponent(entityId, componentType, component2) {
716
- if (!this.hasEntity(entityId)) {
715
+ set(entityId, componentType, component2) {
716
+ if (!this.exists(entityId)) {
717
717
  throw new Error(`Entity ${entityId} does not exist`);
718
718
  }
719
719
  const detailedType = getDetailedIdType(componentType);
@@ -723,31 +723,31 @@ class World {
723
723
  if (detailedType.type === "wildcard-relation") {
724
724
  throw new Error(`Cannot directly add wildcard relation components: ${componentType}`);
725
725
  }
726
- this.commandBuffer.addComponent(entityId, componentType, component2);
726
+ this.commandBuffer.set(entityId, componentType, component2);
727
727
  }
728
- removeComponent(entityId, componentType) {
729
- if (!this.hasEntity(entityId)) {
728
+ delete(entityId, componentType) {
729
+ if (!this.exists(entityId)) {
730
730
  throw new Error(`Entity ${entityId} does not exist`);
731
731
  }
732
732
  const detailedType = getDetailedIdType(componentType);
733
733
  if (detailedType.type === "invalid") {
734
734
  throw new Error(`Invalid component type: ${componentType}`);
735
735
  }
736
- this.commandBuffer.removeComponent(entityId, componentType);
736
+ this.commandBuffer.delete(entityId, componentType);
737
737
  }
738
- destroyEntity(entityId) {
739
- this.commandBuffer.destroyEntity(entityId);
738
+ destroy(entityId) {
739
+ this.commandBuffer.destroy(entityId);
740
740
  }
741
- hasComponent(entityId, componentType) {
741
+ has(entityId, componentType) {
742
742
  const archetype = this.entityToArchetype.get(entityId);
743
743
  return archetype ? archetype.componentTypes.includes(componentType) : false;
744
744
  }
745
- getComponent(entityId, componentType) {
745
+ get(entityId, componentType) {
746
746
  const archetype = this.entityToArchetype.get(entityId);
747
747
  if (!archetype) {
748
748
  throw new Error(`Entity ${entityId} does not exist`);
749
749
  }
750
- return archetype.getComponent(entityId, componentType);
750
+ return archetype.get(entityId, componentType);
751
751
  }
752
752
  registerSystem(system) {
753
753
  this.systemScheduler.addSystem(system);
@@ -777,7 +777,7 @@ class World {
777
777
  }
778
778
  this.commandBuffer.execute();
779
779
  }
780
- flushCommands() {
780
+ sync() {
781
781
  this.commandBuffer.execute();
782
782
  }
783
783
  createQuery(componentTypes, filter = {}) {
@@ -895,7 +895,7 @@ class World {
895
895
  }
896
896
  executeEntityCommands(entityId, commands) {
897
897
  const changeset = new ComponentChangeset;
898
- const hasDestroy = commands.some((cmd) => cmd.type === "destroyEntity");
898
+ const hasDestroy = commands.some((cmd) => cmd.type === "destroy");
899
899
  if (hasDestroy) {
900
900
  this._destroyEntity(entityId);
901
901
  return changeset;
@@ -906,26 +906,26 @@ class World {
906
906
  }
907
907
  const currentComponents = new Map;
908
908
  for (const componentType of currentArchetype.componentTypes) {
909
- const data = currentArchetype.getComponent(entityId, componentType);
909
+ const data = currentArchetype.get(entityId, componentType);
910
910
  currentComponents.set(componentType, data);
911
911
  }
912
912
  for (const cmd of commands) {
913
913
  switch (cmd.type) {
914
- case "addComponent":
914
+ case "set":
915
915
  if (cmd.componentType) {
916
916
  const detailedType = getDetailedIdType(cmd.componentType);
917
917
  if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && this.exclusiveComponents.has(detailedType.componentId)) {
918
918
  for (const componentType of currentArchetype.componentTypes) {
919
919
  const componentDetailedType = getDetailedIdType(componentType);
920
920
  if ((componentDetailedType.type === "entity-relation" || componentDetailedType.type === "component-relation") && componentDetailedType.componentId === detailedType.componentId) {
921
- changeset.removeComponent(componentType);
921
+ changeset.delete(componentType);
922
922
  }
923
923
  }
924
924
  }
925
- changeset.addComponent(cmd.componentType, cmd.component);
925
+ changeset.set(cmd.componentType, cmd.component);
926
926
  }
927
927
  break;
928
- case "removeComponent":
928
+ case "delete":
929
929
  if (cmd.componentType) {
930
930
  const detailedType = getDetailedIdType(cmd.componentType);
931
931
  if (detailedType.type === "wildcard-relation") {
@@ -934,12 +934,12 @@ class World {
934
934
  const componentDetailedType = getDetailedIdType(componentType);
935
935
  if (componentDetailedType.type === "entity-relation" || componentDetailedType.type === "component-relation") {
936
936
  if (componentDetailedType.componentId === baseComponentId) {
937
- changeset.removeComponent(componentType);
937
+ changeset.delete(componentType);
938
938
  }
939
939
  }
940
940
  }
941
941
  } else {
942
- changeset.removeComponent(cmd.componentType);
942
+ changeset.delete(cmd.componentType);
943
943
  }
944
944
  }
945
945
  break;
@@ -956,7 +956,7 @@ class World {
956
956
  this.entityToArchetype.set(entityId, newArchetype);
957
957
  } else {
958
958
  for (const [componentType, component2] of changeset.adds) {
959
- currentArchetype.setComponent(entityId, componentType, component2);
959
+ currentArchetype.set(entityId, componentType, component2);
960
960
  }
961
961
  }
962
962
  for (const componentType of changeset.removes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codehz/ecs",
3
- "version": "0.0.10",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
package/world.d.ts CHANGED
@@ -43,7 +43,7 @@ export declare class World<UpdateParams extends any[] = []> {
43
43
  /**
44
44
  * Create a new entity
45
45
  */
46
- createEntity(): EntityId;
46
+ new(): EntityId;
47
47
  /**
48
48
  * Destroy an entity and remove all its components (immediate execution)
49
49
  */
@@ -51,37 +51,37 @@ export declare class World<UpdateParams extends any[] = []> {
51
51
  /**
52
52
  * Check if an entity exists
53
53
  */
54
- hasEntity(entityId: EntityId): boolean;
54
+ exists(entityId: EntityId): boolean;
55
55
  /**
56
56
  * Add a component to an entity (deferred)
57
57
  */
58
- addComponent(entityId: EntityId, componentType: EntityId<void>): void;
59
- addComponent<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
58
+ set(entityId: EntityId, componentType: EntityId<void>): void;
59
+ set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
60
60
  /**
61
61
  * Remove a component from an entity (deferred)
62
62
  */
63
- removeComponent<T>(entityId: EntityId, componentType: EntityId<T>): void;
63
+ delete<T>(entityId: EntityId, componentType: EntityId<T>): void;
64
64
  /**
65
65
  * Destroy an entity and remove all its components (deferred)
66
66
  */
67
- destroyEntity(entityId: EntityId): void;
67
+ destroy(entityId: EntityId): void;
68
68
  /**
69
69
  * Check if an entity has a specific component
70
70
  */
71
- hasComponent<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
71
+ has<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
72
72
  /**
73
73
  * Get component data for a specific entity and wildcard relation type
74
74
  * Returns an array of all matching relation instances
75
75
  * @param entityId The entity
76
76
  * @param componentType The wildcard relation type
77
77
  */
78
- getComponent<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];
78
+ get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];
79
79
  /**
80
80
  * Get component data for a specific entity and component type
81
81
  * @param entityId The entity
82
82
  * @param componentType The component type
83
83
  */
84
- getComponent<T>(entityId: EntityId, componentType: EntityId<T>): T;
84
+ get<T>(entityId: EntityId, componentType: EntityId<T>): T;
85
85
  /**
86
86
  * Register a system with optional dependencies
87
87
  */
@@ -106,7 +106,7 @@ export declare class World<UpdateParams extends any[] = []> {
106
106
  /**
107
107
  * Execute all deferred commands immediately without running systems
108
108
  */
109
- flushCommands(): void;
109
+ sync(): void;
110
110
  /**
111
111
  * Create a cached query for efficient entity lookups
112
112
  */