@latticexyz/recs 2.0.0-next.0 → 2.0.0-next.10
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/CHANGELOG.md +319 -0
- package/dist/chunk-EL5Z72NP.js +2 -0
- package/dist/chunk-EL5Z72NP.js.map +1 -0
- package/dist/deprecated/index.js +2 -0
- package/dist/deprecated/index.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +17 -6
- package/src/Component.spec.ts +275 -0
- package/src/Component.ts +20 -14
- package/src/Entity.spec.ts +45 -0
- package/src/Entity.ts +1 -1
- package/src/Indexer.spec.ts +288 -0
- package/src/Indexer.ts +1 -1
- package/src/Performance.spec.ts +152 -0
- package/src/Query.spec.ts +811 -0
- package/src/Query.ts +2 -15
- package/src/System.spec.ts +139 -0
- package/src/World.spec.ts +79 -0
- package/src/deprecated/constants.ts +9 -0
- package/src/deprecated/createActionSystem.spec.ts +501 -0
- package/src/deprecated/createActionSystem.ts +236 -0
- package/src/deprecated/defineActionComponent.ts +18 -0
- package/src/deprecated/index.ts +2 -0
- package/src/deprecated/types.ts +45 -0
- package/src/deprecated/waitForActionCompletion.ts +15 -0
- package/src/deprecated/waitForComponentValueIn.ts +38 -0
- package/src/types.ts +8 -9
@@ -0,0 +1,275 @@
|
|
1
|
+
import {
|
2
|
+
defineComponent,
|
3
|
+
setComponent,
|
4
|
+
removeComponent,
|
5
|
+
getComponentValue,
|
6
|
+
hasComponent,
|
7
|
+
withValue,
|
8
|
+
componentValueEquals,
|
9
|
+
getEntitiesWithValue,
|
10
|
+
overridableComponent,
|
11
|
+
} from "./Component";
|
12
|
+
import { Type } from "./constants";
|
13
|
+
import { createEntity, getEntitySymbol } from "./Entity";
|
14
|
+
import { AnyComponent, Entity, World } from "./types";
|
15
|
+
import { createWorld } from "./World";
|
16
|
+
|
17
|
+
describe("Component", () => {
|
18
|
+
let world: World;
|
19
|
+
|
20
|
+
beforeEach(() => {
|
21
|
+
world = createWorld();
|
22
|
+
});
|
23
|
+
|
24
|
+
it("emit changes to its stream", () => {
|
25
|
+
const entity = createEntity(world);
|
26
|
+
const component = defineComponent(world, { x: Type.Number, y: Type.Number });
|
27
|
+
|
28
|
+
const mock = jest.fn();
|
29
|
+
component.update$.subscribe((update) => {
|
30
|
+
mock(update);
|
31
|
+
});
|
32
|
+
|
33
|
+
setComponent(component, entity, { x: 1, y: 2 });
|
34
|
+
setComponent(component, entity, { x: 7, y: 2 });
|
35
|
+
setComponent(component, entity, { x: 7, y: 2 });
|
36
|
+
removeComponent(component, entity);
|
37
|
+
|
38
|
+
expect(mock).toHaveBeenNthCalledWith(1, { entity, value: [{ x: 1, y: 2 }, undefined], component });
|
39
|
+
expect(mock).toHaveBeenNthCalledWith(2, {
|
40
|
+
entity,
|
41
|
+
component,
|
42
|
+
value: [
|
43
|
+
{ x: 7, y: 2 },
|
44
|
+
{ x: 1, y: 2 },
|
45
|
+
],
|
46
|
+
});
|
47
|
+
expect(mock).toHaveBeenNthCalledWith(3, {
|
48
|
+
entity,
|
49
|
+
component,
|
50
|
+
value: [
|
51
|
+
{ x: 7, y: 2 },
|
52
|
+
{ x: 7, y: 2 },
|
53
|
+
],
|
54
|
+
});
|
55
|
+
expect(mock).toHaveBeenNthCalledWith(4, { entity, component, value: [undefined, { x: 7, y: 2 }] });
|
56
|
+
});
|
57
|
+
|
58
|
+
describe("defineComponent", () => {
|
59
|
+
it("should register the component in the world", () => {
|
60
|
+
expect(world.components.length).toBe(0);
|
61
|
+
defineComponent(world, { value: Type.Boolean });
|
62
|
+
expect(world.components.length).toBe(1);
|
63
|
+
});
|
64
|
+
});
|
65
|
+
|
66
|
+
describe("setComponent", () => {
|
67
|
+
let component: AnyComponent;
|
68
|
+
let entity: Entity;
|
69
|
+
let value: number;
|
70
|
+
|
71
|
+
beforeEach(() => {
|
72
|
+
component = defineComponent(world, { value: Type.Number });
|
73
|
+
entity = createEntity(world);
|
74
|
+
value = 1;
|
75
|
+
setComponent(component, entity, { value });
|
76
|
+
});
|
77
|
+
|
78
|
+
it("should store the component value", () => {
|
79
|
+
expect(component.values.value.get(getEntitySymbol(entity))).toBe(value);
|
80
|
+
});
|
81
|
+
|
82
|
+
it("should store the entity", () => {
|
83
|
+
expect(hasComponent(component, entity)).toBe(true);
|
84
|
+
});
|
85
|
+
|
86
|
+
it.todo("should store the value array");
|
87
|
+
});
|
88
|
+
|
89
|
+
describe("removeComponent", () => {
|
90
|
+
let component: AnyComponent;
|
91
|
+
let entity: Entity;
|
92
|
+
let value: number;
|
93
|
+
|
94
|
+
beforeEach(() => {
|
95
|
+
component = defineComponent(world, { value: Type.Number });
|
96
|
+
entity = createEntity(world);
|
97
|
+
value = 1;
|
98
|
+
setComponent(component, entity, { value });
|
99
|
+
removeComponent(component, entity);
|
100
|
+
});
|
101
|
+
|
102
|
+
it("should remove the component value", () => {
|
103
|
+
expect(component.values.value.get(getEntitySymbol(entity))).toBe(undefined);
|
104
|
+
});
|
105
|
+
|
106
|
+
it("should remove the entity", () => {
|
107
|
+
expect(hasComponent(component, entity)).toBe(false);
|
108
|
+
});
|
109
|
+
|
110
|
+
// it("shouldremove the component from the entity's component set", () => {
|
111
|
+
// expect(world.entities.get(entity)?.has(component)).toBe(false);
|
112
|
+
// });
|
113
|
+
});
|
114
|
+
|
115
|
+
describe("hasComponent", () => {
|
116
|
+
it("should return true if the entity has the component", () => {
|
117
|
+
const component = defineComponent(world, { x: Type.Number, y: Type.Number });
|
118
|
+
const entity = createEntity(world);
|
119
|
+
const value = { x: 1, y: 2 };
|
120
|
+
setComponent(component, entity, value);
|
121
|
+
|
122
|
+
expect(hasComponent(component, entity)).toEqual(true);
|
123
|
+
});
|
124
|
+
});
|
125
|
+
|
126
|
+
describe("getComponentValue", () => {
|
127
|
+
it("should return the correct component value", () => {
|
128
|
+
const component = defineComponent(world, { x: Type.Number, y: Type.Number });
|
129
|
+
const entity = createEntity(world);
|
130
|
+
const value = { x: 1, y: 2 };
|
131
|
+
setComponent(component, entity, value);
|
132
|
+
|
133
|
+
const receivedValue = getComponentValue(component, entity);
|
134
|
+
expect(receivedValue).toEqual(value);
|
135
|
+
});
|
136
|
+
});
|
137
|
+
|
138
|
+
describe("getComponentValueStrict", () => {
|
139
|
+
it.todo("should return the correct component value");
|
140
|
+
it.todo("should error if the component value does not exist");
|
141
|
+
});
|
142
|
+
|
143
|
+
describe("componentValueEquals", () => {
|
144
|
+
const value1 = { x: 1, y: 2, z: "x" };
|
145
|
+
const value2 = { x: 1, y: 2, z: "x" };
|
146
|
+
const value3 = { x: "1", y: 2, z: "x" };
|
147
|
+
|
148
|
+
expect(componentValueEquals(value1, value2)).toBe(true);
|
149
|
+
expect(componentValueEquals(value2, value3)).toBe(false);
|
150
|
+
});
|
151
|
+
|
152
|
+
describe("withValue", () => {
|
153
|
+
it("should return a ComponentWithValue", () => {
|
154
|
+
const component = defineComponent(world, { x: Type.Number, y: Type.Number });
|
155
|
+
const value = { x: 1, y: 2 };
|
156
|
+
const componentWithValue = withValue(component, value);
|
157
|
+
expect(componentWithValue).toEqual([component, value]);
|
158
|
+
});
|
159
|
+
});
|
160
|
+
|
161
|
+
describe("getEntitiesWithValue", () => {
|
162
|
+
it("Should return all and only entities with this value", () => {
|
163
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
164
|
+
const entity1 = createEntity(world, [withValue(Position, { x: 1, y: 2 })]);
|
165
|
+
createEntity(world, [withValue(Position, { x: 2, y: 1 })]);
|
166
|
+
createEntity(world);
|
167
|
+
const entity4 = createEntity(world, [withValue(Position, { x: 1, y: 2 })]);
|
168
|
+
|
169
|
+
expect(getEntitiesWithValue(Position, { x: 1, y: 2 })).toEqual(new Set([entity1, entity4]));
|
170
|
+
});
|
171
|
+
});
|
172
|
+
|
173
|
+
describe("overridableComponent", () => {
|
174
|
+
it("should return a overridable component", () => {
|
175
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
176
|
+
const OverridablePosition = overridableComponent(Position);
|
177
|
+
expect("addOverride" in OverridablePosition).toBe(true);
|
178
|
+
expect("addOverride" in OverridablePosition).toBe(true);
|
179
|
+
});
|
180
|
+
|
181
|
+
it("should mirror all values of the source component", () => {
|
182
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
183
|
+
const entity1 = createEntity(world);
|
184
|
+
setComponent(Position, entity1, { x: 1, y: 2 });
|
185
|
+
|
186
|
+
const OverridablePosition = overridableComponent(Position);
|
187
|
+
expect(getComponentValue(OverridablePosition, entity1)).toEqual({ x: 1, y: 2 });
|
188
|
+
});
|
189
|
+
|
190
|
+
it("the overridable component should be updated if the original component is updated", () => {
|
191
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
192
|
+
const entity1 = createEntity(world);
|
193
|
+
setComponent(Position, entity1, { x: 1, y: 2 });
|
194
|
+
|
195
|
+
const OverridableComponent = overridableComponent(Position);
|
196
|
+
|
197
|
+
setComponent(Position, entity1, { x: 2, y: 2 });
|
198
|
+
expect(getComponentValue(OverridableComponent, entity1)).toEqual({ x: 2, y: 2 });
|
199
|
+
|
200
|
+
const entity2 = createEntity(world, [withValue(Position, { x: 3, y: 3 })]);
|
201
|
+
expect(getComponentValue(OverridableComponent, entity2)).toEqual({ x: 3, y: 3 });
|
202
|
+
});
|
203
|
+
|
204
|
+
it("should return the updated component value if there is a relevant update for the given entity", () => {
|
205
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
206
|
+
const entity1 = createEntity(world);
|
207
|
+
const entity2 = createEntity(world);
|
208
|
+
setComponent(Position, entity1, { x: 1, y: 2 });
|
209
|
+
setComponent(Position, entity2, { x: 5, y: 6 });
|
210
|
+
|
211
|
+
const OverridableComponent = overridableComponent(Position);
|
212
|
+
OverridableComponent.addOverride("firstOverride", { entity: entity1, value: { x: 2, y: 3 } });
|
213
|
+
expect(getComponentValue(OverridableComponent, entity1)).toEqual({ x: 2, y: 3 });
|
214
|
+
expect(getComponentValue(OverridableComponent, entity2)).toEqual({ x: 5, y: 6 });
|
215
|
+
|
216
|
+
OverridableComponent.addOverride("secondOverride", { entity: entity1, value: { x: 3, y: 3 } });
|
217
|
+
expect(getComponentValue(OverridableComponent, entity1)).toEqual({ x: 3, y: 3 });
|
218
|
+
|
219
|
+
OverridableComponent.removeOverride("secondOverride");
|
220
|
+
expect(getComponentValue(OverridableComponent, entity1)).toEqual({ x: 2, y: 3 });
|
221
|
+
|
222
|
+
setComponent(Position, entity1, { x: 10, y: 20 });
|
223
|
+
expect(getComponentValue(OverridableComponent, entity1)).toEqual({ x: 2, y: 3 });
|
224
|
+
|
225
|
+
OverridableComponent.removeOverride("firstOverride");
|
226
|
+
expect(getComponentValue(OverridableComponent, entity1)).toEqual({ x: 10, y: 20 });
|
227
|
+
});
|
228
|
+
|
229
|
+
it("adding an override should trigger reactions depending on the getComponentValue of the overriden component", () => {
|
230
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
231
|
+
const entity1 = createEntity(world);
|
232
|
+
setComponent(Position, entity1, { x: 1, y: 2 });
|
233
|
+
|
234
|
+
const OverridablePosition = overridableComponent(Position);
|
235
|
+
|
236
|
+
const spy = jest.fn();
|
237
|
+
OverridablePosition.update$.subscribe(spy);
|
238
|
+
|
239
|
+
expect(spy).toHaveBeenCalledTimes(0);
|
240
|
+
|
241
|
+
OverridablePosition.addOverride("firstOverride", { entity: entity1, value: { x: 3, y: 3 } });
|
242
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
243
|
+
expect(spy).toHaveBeenLastCalledWith({
|
244
|
+
entity: entity1,
|
245
|
+
component: OverridablePosition,
|
246
|
+
value: [
|
247
|
+
{ x: 3, y: 3 },
|
248
|
+
{ x: 1, y: 2 },
|
249
|
+
],
|
250
|
+
});
|
251
|
+
|
252
|
+
OverridablePosition.removeOverride("firstOverride");
|
253
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
254
|
+
expect(spy).toHaveBeenLastCalledWith({
|
255
|
+
entity: entity1,
|
256
|
+
component: OverridablePosition,
|
257
|
+
value: [
|
258
|
+
{ x: 1, y: 2 },
|
259
|
+
{ x: 3, y: 3 },
|
260
|
+
],
|
261
|
+
});
|
262
|
+
|
263
|
+
OverridablePosition.addOverride("secondOverride", {
|
264
|
+
entity: "42" as Entity,
|
265
|
+
value: { x: 2, y: 3 },
|
266
|
+
});
|
267
|
+
expect(spy).toHaveBeenLastCalledWith({
|
268
|
+
entity: "42",
|
269
|
+
component: OverridablePosition,
|
270
|
+
value: [{ x: 2, y: 3 }, undefined],
|
271
|
+
});
|
272
|
+
expect(spy).toHaveBeenCalledTimes(3);
|
273
|
+
});
|
274
|
+
});
|
275
|
+
});
|
package/src/Component.ts
CHANGED
@@ -19,7 +19,13 @@ import { isFullComponentValue, isIndexer } from "./utils";
|
|
19
19
|
import { getEntityString, getEntitySymbol } from "./Entity";
|
20
20
|
|
21
21
|
function getComponentName(component: Component<any, any, any>) {
|
22
|
-
return
|
22
|
+
return (
|
23
|
+
component.metadata?.componentName ??
|
24
|
+
component.metadata?.tableName ??
|
25
|
+
component.metadata?.tableId ??
|
26
|
+
component.metadata?.contractId ??
|
27
|
+
component.id
|
28
|
+
);
|
23
29
|
}
|
24
30
|
|
25
31
|
/**
|
@@ -31,7 +37,7 @@ function getComponentName(component: Component<any, any, any>) {
|
|
31
37
|
* @param schema {@link Schema} of component values. Uses Type enum as bridge between typescript types and javascript accessible values.
|
32
38
|
* @param options Optional: {
|
33
39
|
* id: descriptive id for this component (otherwise an autogenerated id is used),
|
34
|
-
* metadata: arbitrary metadata
|
40
|
+
* metadata: arbitrary metadata,
|
35
41
|
* indexed: if this flag is set, an indexer is applied to this component (see {@link createIndexer})
|
36
42
|
* }
|
37
43
|
* @returns Component object linked to the provided World
|
@@ -41,7 +47,7 @@ function getComponentName(component: Component<any, any, any>) {
|
|
41
47
|
* const Position = defineComponent(world, { x: Type.Number, y: Type.Number }, { id: "Position" });
|
42
48
|
* ```
|
43
49
|
*/
|
44
|
-
export function defineComponent<S extends Schema, M extends Metadata, T =
|
50
|
+
export function defineComponent<S extends Schema, M extends Metadata, T = unknown>(
|
45
51
|
world: World,
|
46
52
|
schema: S,
|
47
53
|
options?: { id?: string; metadata?: M; indexed?: boolean }
|
@@ -71,7 +77,7 @@ export function defineComponent<S extends Schema, M extends Metadata, T = undefi
|
|
71
77
|
* setComponent(Position, entity, { x: 1, y: 2 });
|
72
78
|
* ```
|
73
79
|
*/
|
74
|
-
export function setComponent<S extends Schema, T =
|
80
|
+
export function setComponent<S extends Schema, T = unknown>(
|
75
81
|
component: Component<S, Metadata, T>,
|
76
82
|
entity: Entity,
|
77
83
|
value: ComponentValue<S, T>
|
@@ -122,7 +128,7 @@ export function setComponent<S extends Schema, T = undefined>(
|
|
122
128
|
* updateComponent(Position, entity, { x: 1 });
|
123
129
|
* ```
|
124
130
|
*/
|
125
|
-
export function updateComponent<S extends Schema, T =
|
131
|
+
export function updateComponent<S extends Schema, T = unknown>(
|
126
132
|
component: Component<S, Metadata, T>,
|
127
133
|
entity: Entity,
|
128
134
|
value: Partial<ComponentValue<S, T>>,
|
@@ -145,7 +151,7 @@ export function updateComponent<S extends Schema, T = undefined>(
|
|
145
151
|
* @param component {@link defineComponent Component} to be updated.
|
146
152
|
* @param entity {@link Entity} whose value should be removed from this component.
|
147
153
|
*/
|
148
|
-
export function removeComponent<S extends Schema, M extends Metadata, T>(
|
154
|
+
export function removeComponent<S extends Schema, M extends Metadata, T = unknown>(
|
149
155
|
component: Component<S, M, T>,
|
150
156
|
entity: Entity
|
151
157
|
) {
|
@@ -164,7 +170,7 @@ export function removeComponent<S extends Schema, M extends Metadata, T>(
|
|
164
170
|
* @param entity {@link Entity} to check whether it has a value in the given component.
|
165
171
|
* @returns true if the component contains a value for the given entity, else false.
|
166
172
|
*/
|
167
|
-
export function hasComponent<S extends Schema, T =
|
173
|
+
export function hasComponent<S extends Schema, T = unknown>(
|
168
174
|
component: Component<S, Metadata, T>,
|
169
175
|
entity: Entity
|
170
176
|
): boolean {
|
@@ -181,7 +187,7 @@ export function hasComponent<S extends Schema, T = undefined>(
|
|
181
187
|
* @param entity {@link Entity} to get the value for from the given component.
|
182
188
|
* @returns Value of the given entity in the given component or undefined if no value exists.
|
183
189
|
*/
|
184
|
-
export function getComponentValue<S extends Schema, T =
|
190
|
+
export function getComponentValue<S extends Schema, T = unknown>(
|
185
191
|
component: Component<S, Metadata, T>,
|
186
192
|
entity: Entity
|
187
193
|
): ComponentValue<S, T> | undefined {
|
@@ -210,7 +216,7 @@ export function getComponentValue<S extends Schema, T = undefined>(
|
|
210
216
|
* @remarks
|
211
217
|
* Throws an error if no value exists in the component for the given entity.
|
212
218
|
*/
|
213
|
-
export function getComponentValueStrict<S extends Schema, T =
|
219
|
+
export function getComponentValueStrict<S extends Schema, T = unknown>(
|
214
220
|
component: Component<S, Metadata, T>,
|
215
221
|
entity: Entity
|
216
222
|
): ComponentValue<S, T> {
|
@@ -233,7 +239,7 @@ export function getComponentValueStrict<S extends Schema, T = undefined>(
|
|
233
239
|
* componentValueEquals({ x: 1 }, { x: 1, y: 3 }) // returns true because x is equal and y is not present in a
|
234
240
|
* ```
|
235
241
|
*/
|
236
|
-
export function componentValueEquals<S extends Schema, T =
|
242
|
+
export function componentValueEquals<S extends Schema, T = unknown>(
|
237
243
|
a?: Partial<ComponentValue<S, T>>,
|
238
244
|
b?: ComponentValue<S, T>
|
239
245
|
): boolean {
|
@@ -256,7 +262,7 @@ export function componentValueEquals<S extends Schema, T = undefined>(
|
|
256
262
|
* @param value {@link ComponentValue} with {@link ComponentSchema} `S`
|
257
263
|
* @returns Tuple `[component, value]`
|
258
264
|
*/
|
259
|
-
export function withValue<S extends Schema, T =
|
265
|
+
export function withValue<S extends Schema, T = unknown>(
|
260
266
|
component: Component<S, Metadata, T>,
|
261
267
|
value: ComponentValue<S, T>
|
262
268
|
): [Component<S, Metadata, T>, ComponentValue<S, T>] {
|
@@ -296,7 +302,7 @@ export function getEntitiesWithValue<S extends Schema>(
|
|
296
302
|
* @param component {@link defineComponent Component} to get all entities from
|
297
303
|
* @returns Set of all entities in the given component.
|
298
304
|
*/
|
299
|
-
export function getComponentEntities<S extends Schema, T =
|
305
|
+
export function getComponentEntities<S extends Schema, T = unknown>(
|
300
306
|
component: Component<S, Metadata, T>
|
301
307
|
): IterableIterator<Entity> {
|
302
308
|
return component.entities();
|
@@ -316,7 +322,7 @@ export function getComponentEntities<S extends Schema, T = undefined>(
|
|
316
322
|
* @param component {@link defineComponent Component} to use as underlying source for the overridable component
|
317
323
|
* @returns overridable component
|
318
324
|
*/
|
319
|
-
export function overridableComponent<S extends Schema, M extends Metadata, T =
|
325
|
+
export function overridableComponent<S extends Schema, M extends Metadata, T = unknown>(
|
320
326
|
component: Component<S, M, T>
|
321
327
|
): OverridableComponent<S, M, T> {
|
322
328
|
let nonce = 0;
|
@@ -455,7 +461,7 @@ export function clearLocalCache(component: Component, uniqueWorldIdentifier?: st
|
|
455
461
|
}
|
456
462
|
|
457
463
|
// Note: Only proof of concept for now - use this only for component that do not update frequently
|
458
|
-
export function createLocalCache<S extends Schema, M extends Metadata, T =
|
464
|
+
export function createLocalCache<S extends Schema, M extends Metadata, T = unknown>(
|
459
465
|
component: Component<S, M, T>,
|
460
466
|
uniqueWorldIdentifier?: string
|
461
467
|
): Component<S, M, T> {
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { defineComponent, getComponentValue, hasComponent, withValue } from "./Component";
|
2
|
+
import { Type } from "./constants";
|
3
|
+
import { createEntity } from "./Entity";
|
4
|
+
import { World } from "./types";
|
5
|
+
import { createWorld } from "./World";
|
6
|
+
|
7
|
+
describe("Entity", () => {
|
8
|
+
let world: World;
|
9
|
+
|
10
|
+
beforeEach(() => {
|
11
|
+
world = createWorld();
|
12
|
+
});
|
13
|
+
|
14
|
+
describe("createEntity", () => {
|
15
|
+
it("should return a unique id", () => {
|
16
|
+
const firstEntity = createEntity(world);
|
17
|
+
const secondEntity = createEntity(world);
|
18
|
+
expect(firstEntity).not.toEqual(secondEntity);
|
19
|
+
});
|
20
|
+
|
21
|
+
it("should register the entity in the world", () => {
|
22
|
+
expect([...world.getEntities()].length).toEqual(0);
|
23
|
+
createEntity(world);
|
24
|
+
expect([...world.getEntities()].length).toEqual(1);
|
25
|
+
});
|
26
|
+
|
27
|
+
it("should create an entity with given components and values", () => {
|
28
|
+
const Position = defineComponent(world, { x: Type.Number, y: Type.Number });
|
29
|
+
const CanMove = defineComponent(world, { value: Type.Boolean });
|
30
|
+
|
31
|
+
const value1 = { x: 1, y: 1 };
|
32
|
+
const value2 = { x: 2, y: 1 };
|
33
|
+
|
34
|
+
const movableEntity = createEntity(world, [withValue(Position, value1), withValue(CanMove, { value: true })]);
|
35
|
+
|
36
|
+
const staticEntity = createEntity(world, [withValue(Position, value2)]);
|
37
|
+
|
38
|
+
expect(getComponentValue(Position, movableEntity)).toEqual(value1);
|
39
|
+
expect(hasComponent(CanMove, movableEntity)).toBe(true);
|
40
|
+
|
41
|
+
expect(getComponentValue(Position, staticEntity)).toEqual(value2);
|
42
|
+
expect(hasComponent(CanMove, staticEntity)).toBe(false);
|
43
|
+
});
|
44
|
+
});
|
45
|
+
});
|
package/src/Entity.ts
CHANGED
@@ -8,7 +8,7 @@ import { Component, ComponentValue, Entity, EntitySymbol, World } from "./types"
|
|
8
8
|
* @param components Array of [{@link defineComponent Component}, {@link ComponentValue}] tuples to be added to this entity.
|
9
9
|
* (Use {@link withValue} to generate these tuples with type safety.)
|
10
10
|
* @param options Optional: {
|
11
|
-
* id: {@link Entity} for this entity. Use this for entities that were created outside of recs
|
11
|
+
* id: {@link Entity} for this entity. Use this for entities that were created outside of recs.
|
12
12
|
* idSuffix: string to be appended to the auto-generated id. Use this for improved readability. Do not use this if the `id` option is provided.
|
13
13
|
* }
|
14
14
|
* @returns index of this entity in the {@link World}. This {@link Entity} is used to refer to this entity in other recs methods (eg {@link setComponent}).
|