@dcl/ecs 7.0.6-3939099974.commit-727d673 → 7.0.6-3987590195.commit-4fc1536

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.
@@ -0,0 +1,7 @@
1
+ export declare const MAX_STATIC_COMPONENT: number;
2
+ /**
3
+ * All components that are not part of the coreComponentMappings MUST yield
4
+ * a componentNumber (componentId) greather than MAX_STATIC_COMPONENT.
5
+ * For that reason, we simply add MAX_STATIC_COMPONENT and trim to the domain 2^32
6
+ */
7
+ export declare function componentNumberFromName(componentName: string): number;
@@ -0,0 +1,17 @@
1
+ import { coreComponentMappings } from './generated/component-names.gen';
2
+ import * as utf8 from '@protobufjs/utf8';
3
+ import { unsignedCRC32 } from '../runtime/crc';
4
+ // Max possible pre-defined (static) component.
5
+ export const MAX_STATIC_COMPONENT = 1 << 11; // 2048
6
+ /**
7
+ * All components that are not part of the coreComponentMappings MUST yield
8
+ * a componentNumber (componentId) greather than MAX_STATIC_COMPONENT.
9
+ * For that reason, we simply add MAX_STATIC_COMPONENT and trim to the domain 2^32
10
+ */
11
+ export function componentNumberFromName(componentName) {
12
+ if (coreComponentMappings[componentName])
13
+ return coreComponentMappings[componentName];
14
+ const bytes = new Uint8Array(128);
15
+ utf8.write(componentName, bytes, 0);
16
+ return ((unsignedCRC32(bytes) + MAX_STATIC_COMPONENT) & 4294967295) >>> 0;
17
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Autogenerated mapping of core components to their component numbers
3
+ */
4
+ export declare const coreComponentMappings: Record<string, number>;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Autogenerated mapping of core components to their component numbers
3
+ */
4
+ export const coreComponentMappings = {
5
+ "core::Transform": 1,
6
+ "core::Animator": 1042,
7
+ "core::AudioSource": 1020,
8
+ "core::AudioStream": 1021,
9
+ "core::AvatarAttach": 1073,
10
+ "core::AvatarModifierArea": 1070,
11
+ "core::AvatarShape": 1080,
12
+ "core::Billboard": 1090,
13
+ "core::CameraMode": 1072,
14
+ "core::CameraModeArea": 1071,
15
+ "core::GltfContainer": 1041,
16
+ "core::Material": 1017,
17
+ "core::MeshCollider": 1019,
18
+ "core::MeshRenderer": 1018,
19
+ "core::NftShape": 1040,
20
+ "core::PointerEvents": 1062,
21
+ "core::PointerEventsResult": 1063,
22
+ "core::PointerLock": 1074,
23
+ "core::Raycast": 1067,
24
+ "core::RaycastResult": 1068,
25
+ "core::TextShape": 1030,
26
+ "core::UiBackground": 1053,
27
+ "core::UiDropdown": 1094,
28
+ "core::UiDropdownResult": 1096,
29
+ "core::UiInput": 1093,
30
+ "core::UiInputResult": 1095,
31
+ "core::UiText": 1052,
32
+ "core::UiTransform": 1050,
33
+ "core::VisibilityComponent": 1081
34
+ };
@@ -54,31 +54,31 @@ export * from './pb/decentraland/sdk/components/ui_input_result.gen';
54
54
  export * from './pb/decentraland/sdk/components/ui_text.gen';
55
55
  export * from './pb/decentraland/sdk/components/ui_transform.gen';
56
56
  export * from './pb/decentraland/sdk/components/visibility_component.gen';
57
- /** @public */ /*#__PURE__*/ export const Animator = engine => engine.defineComponentFromSchema(AnimatorSchema, AnimatorSchema.COMPONENT_ID);
58
- /** @public */ /*#__PURE__*/ export const AudioSource = engine => engine.defineComponentFromSchema(AudioSourceSchema, AudioSourceSchema.COMPONENT_ID);
59
- /** @public */ /*#__PURE__*/ export const AudioStream = engine => engine.defineComponentFromSchema(AudioStreamSchema, AudioStreamSchema.COMPONENT_ID);
60
- /** @public */ /*#__PURE__*/ export const AvatarAttach = engine => engine.defineComponentFromSchema(AvatarAttachSchema, AvatarAttachSchema.COMPONENT_ID);
61
- /** @public */ /*#__PURE__*/ export const AvatarModifierArea = engine => engine.defineComponentFromSchema(AvatarModifierAreaSchema, AvatarModifierAreaSchema.COMPONENT_ID);
62
- /** @public */ /*#__PURE__*/ export const AvatarShape = engine => engine.defineComponentFromSchema(AvatarShapeSchema, AvatarShapeSchema.COMPONENT_ID);
63
- /** @public */ /*#__PURE__*/ export const Billboard = engine => engine.defineComponentFromSchema(BillboardSchema, BillboardSchema.COMPONENT_ID);
64
- /** @public */ /*#__PURE__*/ export const CameraMode = engine => engine.defineComponentFromSchema(CameraModeSchema, CameraModeSchema.COMPONENT_ID);
65
- /** @public */ /*#__PURE__*/ export const CameraModeArea = engine => engine.defineComponentFromSchema(CameraModeAreaSchema, CameraModeAreaSchema.COMPONENT_ID);
66
- /** @public */ /*#__PURE__*/ export const GltfContainer = engine => engine.defineComponentFromSchema(GltfContainerSchema, GltfContainerSchema.COMPONENT_ID);
67
- /** @public */ /*#__PURE__*/ export const Material = engine => engine.defineComponentFromSchema(MaterialSchema, MaterialSchema.COMPONENT_ID);
68
- /** @public */ /*#__PURE__*/ export const MeshCollider = engine => engine.defineComponentFromSchema(MeshColliderSchema, MeshColliderSchema.COMPONENT_ID);
69
- /** @public */ /*#__PURE__*/ export const MeshRenderer = engine => engine.defineComponentFromSchema(MeshRendererSchema, MeshRendererSchema.COMPONENT_ID);
70
- /** @public */ /*#__PURE__*/ export const NftShape = engine => engine.defineComponentFromSchema(NftShapeSchema, NftShapeSchema.COMPONENT_ID);
71
- /** @public */ /*#__PURE__*/ export const PointerEvents = engine => engine.defineComponentFromSchema(PointerEventsSchema, PointerEventsSchema.COMPONENT_ID);
72
- /** @public */ /*#__PURE__*/ export const PointerEventsResult = engine => engine.defineComponentFromSchema(PointerEventsResultSchema, PointerEventsResultSchema.COMPONENT_ID);
73
- /** @public */ /*#__PURE__*/ export const PointerLock = engine => engine.defineComponentFromSchema(PointerLockSchema, PointerLockSchema.COMPONENT_ID);
74
- /** @public */ /*#__PURE__*/ export const Raycast = engine => engine.defineComponentFromSchema(RaycastSchema, RaycastSchema.COMPONENT_ID);
75
- /** @public */ /*#__PURE__*/ export const RaycastResult = engine => engine.defineComponentFromSchema(RaycastResultSchema, RaycastResultSchema.COMPONENT_ID);
76
- /** @public */ /*#__PURE__*/ export const TextShape = engine => engine.defineComponentFromSchema(TextShapeSchema, TextShapeSchema.COMPONENT_ID);
77
- /** @public */ /*#__PURE__*/ export const UiBackground = engine => engine.defineComponentFromSchema(UiBackgroundSchema, UiBackgroundSchema.COMPONENT_ID);
78
- /** @public */ /*#__PURE__*/ export const UiDropdown = engine => engine.defineComponentFromSchema(UiDropdownSchema, UiDropdownSchema.COMPONENT_ID);
79
- /** @public */ /*#__PURE__*/ export const UiDropdownResult = engine => engine.defineComponentFromSchema(UiDropdownResultSchema, UiDropdownResultSchema.COMPONENT_ID);
80
- /** @public */ /*#__PURE__*/ export const UiInput = engine => engine.defineComponentFromSchema(UiInputSchema, UiInputSchema.COMPONENT_ID);
81
- /** @public */ /*#__PURE__*/ export const UiInputResult = engine => engine.defineComponentFromSchema(UiInputResultSchema, UiInputResultSchema.COMPONENT_ID);
82
- /** @public */ /*#__PURE__*/ export const UiText = engine => engine.defineComponentFromSchema(UiTextSchema, UiTextSchema.COMPONENT_ID);
83
- /** @public */ /*#__PURE__*/ export const UiTransform = engine => engine.defineComponentFromSchema(UiTransformSchema, UiTransformSchema.COMPONENT_ID);
84
- /** @public */ /*#__PURE__*/ export const VisibilityComponent = engine => engine.defineComponentFromSchema(VisibilityComponentSchema, VisibilityComponentSchema.COMPONENT_ID);
57
+ /** @public */ /*#__PURE__*/ export const Animator = engine => engine.defineComponentFromSchema("core::Animator", AnimatorSchema);
58
+ /** @public */ /*#__PURE__*/ export const AudioSource = engine => engine.defineComponentFromSchema("core::AudioSource", AudioSourceSchema);
59
+ /** @public */ /*#__PURE__*/ export const AudioStream = engine => engine.defineComponentFromSchema("core::AudioStream", AudioStreamSchema);
60
+ /** @public */ /*#__PURE__*/ export const AvatarAttach = engine => engine.defineComponentFromSchema("core::AvatarAttach", AvatarAttachSchema);
61
+ /** @public */ /*#__PURE__*/ export const AvatarModifierArea = engine => engine.defineComponentFromSchema("core::AvatarModifierArea", AvatarModifierAreaSchema);
62
+ /** @public */ /*#__PURE__*/ export const AvatarShape = engine => engine.defineComponentFromSchema("core::AvatarShape", AvatarShapeSchema);
63
+ /** @public */ /*#__PURE__*/ export const Billboard = engine => engine.defineComponentFromSchema("core::Billboard", BillboardSchema);
64
+ /** @public */ /*#__PURE__*/ export const CameraMode = engine => engine.defineComponentFromSchema("core::CameraMode", CameraModeSchema);
65
+ /** @public */ /*#__PURE__*/ export const CameraModeArea = engine => engine.defineComponentFromSchema("core::CameraModeArea", CameraModeAreaSchema);
66
+ /** @public */ /*#__PURE__*/ export const GltfContainer = engine => engine.defineComponentFromSchema("core::GltfContainer", GltfContainerSchema);
67
+ /** @public */ /*#__PURE__*/ export const Material = engine => engine.defineComponentFromSchema("core::Material", MaterialSchema);
68
+ /** @public */ /*#__PURE__*/ export const MeshCollider = engine => engine.defineComponentFromSchema("core::MeshCollider", MeshColliderSchema);
69
+ /** @public */ /*#__PURE__*/ export const MeshRenderer = engine => engine.defineComponentFromSchema("core::MeshRenderer", MeshRendererSchema);
70
+ /** @public */ /*#__PURE__*/ export const NftShape = engine => engine.defineComponentFromSchema("core::NftShape", NftShapeSchema);
71
+ /** @public */ /*#__PURE__*/ export const PointerEvents = engine => engine.defineComponentFromSchema("core::PointerEvents", PointerEventsSchema);
72
+ /** @public */ /*#__PURE__*/ export const PointerEventsResult = engine => engine.defineComponentFromSchema("core::PointerEventsResult", PointerEventsResultSchema);
73
+ /** @public */ /*#__PURE__*/ export const PointerLock = engine => engine.defineComponentFromSchema("core::PointerLock", PointerLockSchema);
74
+ /** @public */ /*#__PURE__*/ export const Raycast = engine => engine.defineComponentFromSchema("core::Raycast", RaycastSchema);
75
+ /** @public */ /*#__PURE__*/ export const RaycastResult = engine => engine.defineComponentFromSchema("core::RaycastResult", RaycastResultSchema);
76
+ /** @public */ /*#__PURE__*/ export const TextShape = engine => engine.defineComponentFromSchema("core::TextShape", TextShapeSchema);
77
+ /** @public */ /*#__PURE__*/ export const UiBackground = engine => engine.defineComponentFromSchema("core::UiBackground", UiBackgroundSchema);
78
+ /** @public */ /*#__PURE__*/ export const UiDropdown = engine => engine.defineComponentFromSchema("core::UiDropdown", UiDropdownSchema);
79
+ /** @public */ /*#__PURE__*/ export const UiDropdownResult = engine => engine.defineComponentFromSchema("core::UiDropdownResult", UiDropdownResultSchema);
80
+ /** @public */ /*#__PURE__*/ export const UiInput = engine => engine.defineComponentFromSchema("core::UiInput", UiInputSchema);
81
+ /** @public */ /*#__PURE__*/ export const UiInputResult = engine => engine.defineComponentFromSchema("core::UiInputResult", UiInputResultSchema);
82
+ /** @public */ /*#__PURE__*/ export const UiText = engine => engine.defineComponentFromSchema("core::UiText", UiTextSchema);
83
+ /** @public */ /*#__PURE__*/ export const UiTransform = engine => engine.defineComponentFromSchema("core::UiTransform", UiTransformSchema);
84
+ /** @public */ /*#__PURE__*/ export const VisibilityComponent = engine => engine.defineComponentFromSchema("core::VisibilityComponent", VisibilityComponentSchema);
@@ -59,7 +59,7 @@ export const TransformSchema = {
59
59
  }
60
60
  };
61
61
  export function defineTransformComponent(engine) {
62
- const transformDef = engine.defineComponentFromSchema(TransformSchema, COMPONENT_ID);
62
+ const transformDef = engine.defineComponentFromSchema('core::Transform', TransformSchema);
63
63
  return {
64
64
  ...transformDef,
65
65
  create(entity, val) {
@@ -6,7 +6,8 @@ import { DeepReadonly } from './readonly';
6
6
  * @public
7
7
  */
8
8
  export declare type ComponentDefinition<T> = {
9
- _id: number;
9
+ readonly componentId: number;
10
+ readonly componentName: string;
10
11
  /**
11
12
  * Return the default value of the current component
12
13
  */
@@ -62,4 +63,4 @@ export declare type ComponentDefinition<T> = {
62
63
  getMutableOrNull(entity: Entity): T | null;
63
64
  writeToByteBuffer(entity: Entity, buffer: ByteBuffer): void;
64
65
  };
65
- export declare function defineComponent<T>(componentId: number, spec: ISchema<T>): ComponentDefinition<T>;
66
+ export declare function createComponentDefinitionFromSchema<T>(componentName: string, componentId: number, schema: ISchema<T>): ComponentDefinition<T>;
@@ -1,14 +1,17 @@
1
1
  import { ReadWriteByteBuffer } from '../serialization/ByteBuffer';
2
2
  import { deepReadonly } from './readonly';
3
- export function defineComponent(componentId, spec
4
- // meta: { syncFlags }
5
- ) {
3
+ export function createComponentDefinitionFromSchema(componentName, componentId, schema) {
6
4
  const data = new Map();
7
5
  const dirtyIterator = new Set();
8
6
  return {
9
- _id: componentId,
7
+ get componentId() {
8
+ return componentId;
9
+ },
10
+ get componentName() {
11
+ return componentName;
12
+ },
10
13
  default() {
11
- return spec.create();
14
+ return schema.create();
12
15
  },
13
16
  isDirty(entity) {
14
17
  return dirtyIterator.has(entity);
@@ -34,19 +37,19 @@ export function defineComponent(componentId, spec
34
37
  get(entity) {
35
38
  const component = data.get(entity);
36
39
  if (!component) {
37
- throw new Error(`[getFrom] Component ${componentId} for entity #${entity} not found`);
40
+ throw new Error(`[getFrom] Component ${componentName} for entity #${entity} not found`);
38
41
  }
39
42
  return deepReadonly(component);
40
43
  },
41
44
  create(entity, value) {
42
45
  const component = data.get(entity);
43
46
  if (component) {
44
- throw new Error(`[create] Component ${componentId} for ${entity} already exists`);
47
+ throw new Error(`[create] Component ${componentName} for ${entity} already exists`);
45
48
  }
46
49
  const usedValue = value === undefined
47
- ? spec.create()
48
- : spec.extend
49
- ? spec.extend(value)
50
+ ? schema.create()
51
+ : schema.extend
52
+ ? schema.extend(value)
50
53
  : value;
51
54
  data.set(entity, usedValue);
52
55
  dirtyIterator.add(entity);
@@ -54,9 +57,9 @@ export function defineComponent(componentId, spec
54
57
  },
55
58
  createOrReplace(entity, value) {
56
59
  const usedValue = value === undefined
57
- ? spec.create()
58
- : spec.extend
59
- ? spec.extend(value)
60
+ ? schema.create()
61
+ : schema.extend
62
+ ? schema.extend(value)
60
63
  : value;
61
64
  data.set(entity, usedValue);
62
65
  dirtyIterator.add(entity);
@@ -73,7 +76,7 @@ export function defineComponent(componentId, spec
73
76
  getMutable(entity) {
74
77
  const component = this.getMutableOrNull(entity);
75
78
  if (component === null) {
76
- throw new Error(`[mutable] Component ${componentId} for ${entity} not found`);
79
+ throw new Error(`[mutable] Component ${componentName} for ${entity} not found`);
77
80
  }
78
81
  return component;
79
82
  },
@@ -90,10 +93,10 @@ export function defineComponent(componentId, spec
90
93
  toBinary(entity) {
91
94
  const component = data.get(entity);
92
95
  if (!component) {
93
- throw new Error(`[toBinary] Component ${componentId} for ${entity} not found`);
96
+ throw new Error(`[toBinary] Component ${componentName} for ${entity} not found`);
94
97
  }
95
98
  const writeBuffer = new ReadWriteByteBuffer();
96
- spec.serialize(component, writeBuffer);
99
+ schema.serialize(component, writeBuffer);
97
100
  return writeBuffer;
98
101
  },
99
102
  toBinaryOrNull(entity) {
@@ -102,25 +105,25 @@ export function defineComponent(componentId, spec
102
105
  return null;
103
106
  }
104
107
  const writeBuffer = new ReadWriteByteBuffer();
105
- spec.serialize(component, writeBuffer);
108
+ schema.serialize(component, writeBuffer);
106
109
  return writeBuffer;
107
110
  },
108
111
  writeToByteBuffer(entity, buffer) {
109
112
  const component = data.get(entity);
110
113
  if (!component) {
111
- throw new Error(`[writeToByteBuffer] Component ${componentId} for entity #${entity} not found`);
114
+ throw new Error(`[writeToByteBuffer] Component ${componentName} for entity #${entity} not found`);
112
115
  }
113
- spec.serialize(component, buffer);
116
+ schema.serialize(component, buffer);
114
117
  },
115
118
  updateFromBinary(entity, buffer, markAsDirty = true) {
116
119
  const component = data.get(entity);
117
120
  if (!component) {
118
- throw new Error(`[updateFromBinary] Component ${componentId} for ${entity} not found`);
121
+ throw new Error(`[updateFromBinary] Component ${componentName} for ${entity} not found`);
119
122
  }
120
123
  return this.upsertFromBinary(entity, buffer, markAsDirty);
121
124
  },
122
125
  upsertFromBinary(entity, buffer, markAsDirty = true) {
123
- const newValue = spec.deserialize(buffer);
126
+ const newValue = schema.deserialize(buffer);
124
127
  data.set(entity, newValue);
125
128
  if (markAsDirty) {
126
129
  dirtyIterator.add(entity);
@@ -131,7 +134,7 @@ export function defineComponent(componentId, spec
131
134
  return newValue;
132
135
  },
133
136
  deserialize(buffer) {
134
- return spec.deserialize(buffer);
137
+ return schema.deserialize(buffer);
135
138
  },
136
139
  clearDirty() {
137
140
  dirtyIterator.clear();
@@ -1,8 +1,9 @@
1
1
  import * as components from '../components';
2
+ import { componentNumberFromName } from '../components/component-number';
2
3
  import { checkNotThenable } from '../runtime/invariant';
3
4
  import { Schemas } from '../schemas';
4
5
  import { crdtSceneSystem } from '../systems/crdt';
5
- import { defineComponent as defComponent } from './component';
6
+ import { createComponentDefinitionFromSchema } from './component';
6
7
  import { EntityContainer } from './entity';
7
8
  import { SystemContainer, SYSTEMS_REGULAR_PRIORITY } from './systems';
8
9
  export * from './input';
@@ -12,6 +13,7 @@ function preEngine() {
12
13
  const entityContainer = EntityContainer();
13
14
  const componentsDefinition = new Map();
14
15
  const systems = SystemContainer();
16
+ let sealed = false;
15
17
  function addSystem(fn, priority = SYSTEMS_REGULAR_PRIORITY, name) {
16
18
  systems.add(fn, priority, name);
17
19
  }
@@ -30,32 +32,51 @@ function preEngine() {
30
32
  }
31
33
  return entityContainer.removeEntity(entity);
32
34
  }
33
- function registerCustomComponent(component, componentId) {
35
+ function registerComponentDefinition(componentName, component) {
36
+ /* istanbul ignore next */
37
+ if (sealed)
38
+ throw new Error('Engine is already sealed. No components can be added at this stage');
39
+ const componentId = componentNumberFromName(componentName);
34
40
  const prev = componentsDefinition.get(componentId);
35
41
  if (prev) {
36
42
  throw new Error(`Component number ${componentId} was already registered.`);
37
43
  }
44
+ /* istanbul ignore next */
45
+ if (component.componentName !== componentName) {
46
+ throw new Error(`Component name doesn't match componentDefinition.componentName ${componentName} != ${component.componentName}`);
47
+ }
48
+ /* istanbul ignore next */
49
+ if (component.componentId !== componentId) {
50
+ throw new Error(`Component number doesn't match componentDefinition.componentId ${componentId} != ${component.componentId}`);
51
+ }
38
52
  componentsDefinition.set(componentId, component);
39
53
  return component;
40
54
  }
41
- function defineComponentFromSchema(spec, componentId) {
55
+ function defineComponentFromSchema(componentName, schema) {
56
+ /* istanbul ignore next */
57
+ if (sealed)
58
+ throw new Error('Engine is already sealed. No components can be added at this stage');
59
+ const componentId = componentNumberFromName(componentName);
42
60
  const prev = componentsDefinition.get(componentId);
43
61
  if (prev) {
44
62
  // TODO: assert spec === prev.spec
45
63
  return prev;
46
64
  }
47
- const newComponent = defComponent(componentId, spec);
65
+ const newComponent = createComponentDefinitionFromSchema(componentName, componentId, schema);
48
66
  componentsDefinition.set(componentId, newComponent);
49
67
  return newComponent;
50
68
  }
51
- function defineComponent(mapSpec, componentId, constructorDefault) {
69
+ function defineComponent(componentName, mapSpec, constructorDefault) {
70
+ if (sealed)
71
+ throw new Error('Engine is already sealed. No components can be added at this stage');
72
+ const componentId = componentNumberFromName(componentName);
52
73
  const prev = componentsDefinition.get(componentId);
53
74
  if (prev) {
54
75
  // TODO: assert spec === prev.spec
55
76
  return prev;
56
77
  }
57
78
  const schemaSpec = Schemas.Map(mapSpec, constructorDefault);
58
- const def = defComponent(componentId, schemaSpec);
79
+ const def = createComponentDefinitionFromSchema(componentName, componentId, schemaSpec);
59
80
  const newComponent = {
60
81
  ...def,
61
82
  create(entity, val) {
@@ -127,6 +148,11 @@ function preEngine() {
127
148
  removeEntity(entity);
128
149
  }
129
150
  }
151
+ function seal() {
152
+ if (!sealed) {
153
+ sealed = true;
154
+ }
155
+ }
130
156
  return {
131
157
  addEntity,
132
158
  removeEntity,
@@ -140,9 +166,10 @@ function preEngine() {
140
166
  getComponentOrNull,
141
167
  removeComponentDefinition,
142
168
  removeEntityWithChildren,
143
- registerCustomComponent,
169
+ registerComponentDefinition,
144
170
  entityContainer,
145
- componentsIter
171
+ componentsIter,
172
+ seal
146
173
  };
147
174
  }
148
175
  /**
@@ -172,12 +199,13 @@ export function Engine(options) {
172
199
  removeSystem: engine.removeSystem,
173
200
  defineComponent: engine.defineComponent,
174
201
  defineComponentFromSchema: engine.defineComponentFromSchema,
175
- registerCustomComponent: engine.registerCustomComponent,
202
+ registerComponentDefinition: engine.registerComponentDefinition,
176
203
  getEntitiesWith: engine.getEntitiesWith,
177
204
  getComponent: engine.getComponent,
178
205
  getComponentOrNull: engine.getComponentOrNull,
179
206
  removeComponentDefinition: engine.removeComponentDefinition,
180
207
  componentsIter: engine.componentsIter,
208
+ seal: engine.seal,
181
209
  update,
182
210
  RootEntity: 0,
183
211
  PlayerEntity: 1,
@@ -23,12 +23,11 @@ const InternalInputStateSchema = {
23
23
  ts: Schemas.Number
24
24
  }))
25
25
  };
26
- const InternalInputStateComponentId = 1500;
27
26
  const TimestampUpdateSystemPriority = 1 << 20;
28
27
  const ButtonStateUpdateSystemPriority = 0;
29
28
  export function createInputSystem(engine) {
30
29
  const PointerEventsResult = components.PointerEventsResult(engine);
31
- const InternalInputStateComponent = engine.defineComponent(InternalInputStateSchema, InternalInputStateComponentId);
30
+ const InternalInputStateComponent = engine.defineComponent('@dcl/sdk/InternalInputStateSchema', InternalInputStateSchema);
32
31
  InternalInputStateComponent.create(engine.RootEntity, {
33
32
  buttonState: Array.from({ length: InputCommands.length }, () => ({
34
33
  ts: 0,
@@ -84,42 +84,40 @@ export declare type IEngine = {
84
84
  removeSystem(selector: string | SystemFn): boolean;
85
85
  /**
86
86
  * Registers a custom component definition.
87
- * @param component - The component definition
88
- * @param componentId - unique id to identify the component, if the component id already exist, it will fail.
87
+ * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions.
88
+ * @param componentDefinition - The component definition
89
89
  */
90
- registerCustomComponent<T>(component: ComponentDefinition<T>, componentId: number): ComponentDefinition<T>;
90
+ registerComponentDefinition<T>(componentName: string, componentDefinition: ComponentDefinition<T>): ComponentDefinition<T>;
91
91
  /**
92
92
  * Define a component and add it to the engine.
93
93
  * @param spec - An object with schema fields
94
- * @param componentId - unique id to identify the component, if the component id already exist, it will fail.
94
+ * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions.
95
95
  * @param constructorDefault - the initial value prefilled when a component is created without a value
96
96
  * @returns The component definition
97
97
  *
98
98
  * ```ts
99
- * const DoorComponentId = 10017
100
- * const Door = engine.defineComponent({
99
+ * const Door = engine.defineComponent("my-scene::Door", {
101
100
  * id: Schemas.Int,
102
101
  * name: Schemas.String
103
- * }, DoorComponentId)
104
- *
102
+ * })
105
103
  * ```
106
104
  */
107
- defineComponent<T extends Spec>(spec: T, componentId: number, constructorDefault?: Partial<MapResult<T>>): MapComponentDefinition<MapResult<T>>;
105
+ defineComponent<T extends Spec>(componentName: string, spec: T, constructorDefault?: Partial<MapResult<T>>): MapComponentDefinition<MapResult<T>>;
108
106
  /**
109
107
  * Define a component and add it to the engine.
108
+ * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions.
110
109
  * @param spec - An object with schema fields
111
- * @param componentId - unique id to identify the component, if the component id already exist, it will fail.
112
110
  * @returns The component definition
113
111
  *
114
112
  * ```ts
115
113
  * const StateComponentId = 10023
116
- * const StateComponent = engine.defineComponent(Schemas.Bool, VisibleComponentId)
114
+ * const StateComponent = engine.defineComponentFromSchema("my-lib::VisibleComponent", Schemas.Bool)
117
115
  * ```
118
116
  */
119
- defineComponentFromSchema<T>(spec: ISchema<T>, componentId: number): ComponentDefinition<T>;
117
+ defineComponentFromSchema<T>(componentName: string, spec: ISchema<T>): ComponentDefinition<T>;
120
118
  /**
121
119
  * Get the component definition from the component id.
122
- * @param componentId - component number used to identify the component descriptor
120
+ * @param componentId - component number or name used to identify the component descriptor
123
121
  * @returns the component definition, throw an error if it doesn't exist
124
122
  * ```ts
125
123
  * const StateComponentId = 10023
@@ -129,7 +127,7 @@ export declare type IEngine = {
129
127
  getComponent<T>(componentId: number): ComponentDefinition<T>;
130
128
  /**
131
129
  * Get the component definition from the component id.
132
- * @param componentId - component number used to identify the component descriptor
130
+ * @param componentId - component number or name used to identify the component descriptor
133
131
  * @returns the component definition or null if its not founded
134
132
  * ```ts
135
133
  * const StateComponentId = 10023
@@ -181,4 +179,9 @@ export declare type IEngine = {
181
179
  * Iterator of registered components
182
180
  */
183
181
  componentsIter(): Iterable<ComponentDefinition<unknown>>;
182
+ /**
183
+ * Seals the engine components. It is used to clearly define the scope of the
184
+ * components that will be available to this engine and to run optimizations.
185
+ */
186
+ seal(): void;
184
187
  };
@@ -0,0 +1 @@
1
+ export declare function unsignedCRC32(data: Uint8Array, prev?: number): number;
@@ -0,0 +1,55 @@
1
+ const CRC_TABLE = new Int32Array([
2
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
3
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
4
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
5
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
6
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
7
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
8
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
9
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
10
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
11
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
12
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
13
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
14
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
15
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
16
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
18
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
19
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
20
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
21
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
22
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
23
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
24
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
25
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
26
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
27
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
28
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
29
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
30
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
31
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
32
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
33
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
34
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
35
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
36
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
37
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
38
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
39
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
40
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
41
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
42
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
43
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
44
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
45
+ ]);
46
+ function _crc32(buf, previous) {
47
+ let crc = ~~previous ^ -1;
48
+ for (let n = 0; n < buf.length; n++) {
49
+ crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8);
50
+ }
51
+ return crc ^ -1;
52
+ }
53
+ export function unsignedCRC32(data, prev = 0) {
54
+ return _crc32(data, prev) >>> 0;
55
+ }
@@ -187,7 +187,7 @@ export class ReadWriteByteBuffer {
187
187
  return this.view.getUint16(offset);
188
188
  }
189
189
  getUint32(offset) {
190
- return this.view.getUint32(offset);
190
+ return this.view.getUint32(offset) >>> 0;
191
191
  }
192
192
  getUint64(offset) {
193
193
  return this.view.getBigUint64(offset);
@@ -34,7 +34,7 @@ export var DeleteComponent;
34
34
  const msg = {
35
35
  ...header,
36
36
  entityId: buf.readUint32(),
37
- componentId: buf.readInt32(),
37
+ componentId: buf.readUint32(),
38
38
  timestamp: Number(buf.readUint64())
39
39
  };
40
40
  // TODO: remove buffer length
@@ -18,7 +18,7 @@ export var PutComponentOperation;
18
18
  buf.setUint32(startMessageOffset + 4, CrdtMessageType.PUT_COMPONENT);
19
19
  // Write ComponentOperation header
20
20
  buf.setUint32(startMessageOffset + 8, entity);
21
- buf.setUint32(startMessageOffset + 12, componentDefinition._id);
21
+ buf.setUint32(startMessageOffset + 12, componentDefinition.componentId);
22
22
  buf.setUint64(startMessageOffset + 16, BigInt(timestamp));
23
23
  const newLocal = messageLength - PutComponentOperation.MESSAGE_HEADER_LENGTH - CRDT_MESSAGE_HEADER_LENGTH;
24
24
  buf.setUint32(startMessageOffset + 24, newLocal);
@@ -35,7 +35,7 @@ export var PutComponentOperation;
35
35
  return {
36
36
  ...header,
37
37
  entityId: buf.readUint32(),
38
- componentId: buf.readInt32(),
38
+ componentId: buf.readUint32(),
39
39
  timestamp: Number(buf.readUint64()),
40
40
  data: buf.readBuffer()
41
41
  };
@@ -122,7 +122,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
122
122
  // The state isn't updated because the dirty was set
123
123
  // out of the block of systems update between `receiveMessage` and `updateState`
124
124
  if (component?.isDirty(msg.entityId)) {
125
- crdtClient.createComponentDataEvent(component._id, msg.entityId, component.toBinaryOrNull(msg.entityId)?.toBinary() || null);
125
+ crdtClient.createComponentDataEvent(component.componentId, msg.entityId, component.toBinaryOrNull(msg.entityId)?.toBinary() || null);
126
126
  }
127
127
  const processResult = crdtClient.processMessage(crdtMessage);
128
128
  if (!component) {
@@ -159,7 +159,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
159
159
  PutComponentOperation.write(msg.entityId, ts, component, bufferForOutdated);
160
160
  }
161
161
  else {
162
- DeleteComponent.write(msg.entityId, component._id, ts, bufferForOutdated);
162
+ DeleteComponent.write(msg.entityId, component.componentId, ts, bufferForOutdated);
163
163
  }
164
164
  outdatedMessages.push({
165
165
  ...msg,
@@ -211,7 +211,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
211
211
  const componentValue = component.toBinaryOrNull(entity)?.toBinary() ?? null;
212
212
  // TODO: do not emit event if componentValue equals the value didn't change
213
213
  // if update goes bad, the entity doesn't accept put anymore (it's added to deleted entities set)
214
- if (crdtClient.createComponentDataEvent(component._id, entity, componentValue) === null) {
214
+ if (crdtClient.createComponentDataEvent(component.componentId, entity, componentValue) === null) {
215
215
  component.deleteFrom(entity, false);
216
216
  }
217
217
  else {
@@ -238,7 +238,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
238
238
  // Component will be always defined here since dirtyMap its an iterator of engine.componentsDefinition
239
239
  const { timestamp } = crdtClient
240
240
  .getState()
241
- .components.get(component._id)
241
+ .components.get(component.componentId)
242
242
  .get(entity);
243
243
  const offset = buffer.currentWriteOffset();
244
244
  const type = component.has(entity)
@@ -247,7 +247,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
247
247
  const transportMessage = {
248
248
  type,
249
249
  entityId: entity,
250
- componentId: component._id,
250
+ componentId: component.componentId,
251
251
  timestamp
252
252
  };
253
253
  // Avoid creating messages if there is no transport that will handle it
@@ -256,7 +256,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
256
256
  PutComponentOperation.write(entity, timestamp, component, buffer);
257
257
  }
258
258
  else {
259
- DeleteComponent.write(entity, component._id, timestamp, buffer);
259
+ DeleteComponent.write(entity, component.componentId, timestamp, buffer);
260
260
  }
261
261
  crdtMessages.push({
262
262
  ...transportMessage,
@@ -1,6 +1,6 @@
1
1
  import { ComponentDefinition } from '../../engine/component';
2
2
  export declare namespace CrdtUtils {
3
- type ComponentID = ComponentDefinition<any>['_id'];
3
+ type ComponentID = ComponentDefinition<any>['componentId'];
4
4
  enum SynchronizedEntityType {
5
5
  NETWORKED = 0,
6
6
  RENDERER = 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcl/ecs",
3
- "version": "7.0.6-3939099974.commit-727d673",
3
+ "version": "7.0.6-3987590195.commit-4fc1536",
4
4
  "description": "Decentraland ECS",
5
5
  "main": "./dist/index.js",
6
6
  "typings": "./dist/index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "ts-proto": "^1.112.0"
28
28
  },
29
29
  "dependencies": {
30
- "@dcl/crdt": "7.0.6-3939099974.commit-727d673",
30
+ "@dcl/crdt": "7.0.6-3987590195.commit-4fc1536",
31
31
  "@dcl/js-runtime": "file:../js-runtime",
32
32
  "@dcl/protocol": "^1.0.0-3939040004.commit-2c2721f"
33
33
  },
@@ -41,5 +41,5 @@
41
41
  "displayName": "ECS",
42
42
  "tsconfig": "./tsconfig.json"
43
43
  },
44
- "commit": "727d673f8e1a299bf65a92b41a6fb76f2e9c4711"
44
+ "commit": "4fc1536e9bdd2501b3d9918ec7345084f7a49aca"
45
45
  }
@@ -1,32 +0,0 @@
1
- /** @public */
2
- export declare enum ECSComponentIDs {
3
- Transform = 1,
4
- Animator = 1042,
5
- AudioSource = 1020,
6
- AudioStream = 1021,
7
- AvatarAttach = 1073,
8
- AvatarModifierArea = 1070,
9
- AvatarShape = 1080,
10
- Billboard = 1090,
11
- CameraMode = 1072,
12
- CameraModeArea = 1071,
13
- GltfContainer = 1041,
14
- Material = 1017,
15
- MeshCollider = 1019,
16
- MeshRenderer = 1018,
17
- NftShape = 1040,
18
- PointerEvents = 1062,
19
- PointerEventsResult = 1063,
20
- PointerLock = 1074,
21
- Raycast = 1067,
22
- RaycastResult = 1068,
23
- TextShape = 1030,
24
- UiBackground = 1053,
25
- UiDropdown = 1094,
26
- UiDropdownResult = 1096,
27
- UiInput = 1093,
28
- UiInputResult = 1095,
29
- UiText = 1052,
30
- UiTransform = 1050,
31
- VisibilityComponent = 1081
32
- }
@@ -1,33 +0,0 @@
1
- /** @public */
2
- export var ECSComponentIDs;
3
- (function (ECSComponentIDs) {
4
- ECSComponentIDs[ECSComponentIDs["Transform"] = 1] = "Transform";
5
- ECSComponentIDs[ECSComponentIDs["Animator"] = 1042] = "Animator";
6
- ECSComponentIDs[ECSComponentIDs["AudioSource"] = 1020] = "AudioSource";
7
- ECSComponentIDs[ECSComponentIDs["AudioStream"] = 1021] = "AudioStream";
8
- ECSComponentIDs[ECSComponentIDs["AvatarAttach"] = 1073] = "AvatarAttach";
9
- ECSComponentIDs[ECSComponentIDs["AvatarModifierArea"] = 1070] = "AvatarModifierArea";
10
- ECSComponentIDs[ECSComponentIDs["AvatarShape"] = 1080] = "AvatarShape";
11
- ECSComponentIDs[ECSComponentIDs["Billboard"] = 1090] = "Billboard";
12
- ECSComponentIDs[ECSComponentIDs["CameraMode"] = 1072] = "CameraMode";
13
- ECSComponentIDs[ECSComponentIDs["CameraModeArea"] = 1071] = "CameraModeArea";
14
- ECSComponentIDs[ECSComponentIDs["GltfContainer"] = 1041] = "GltfContainer";
15
- ECSComponentIDs[ECSComponentIDs["Material"] = 1017] = "Material";
16
- ECSComponentIDs[ECSComponentIDs["MeshCollider"] = 1019] = "MeshCollider";
17
- ECSComponentIDs[ECSComponentIDs["MeshRenderer"] = 1018] = "MeshRenderer";
18
- ECSComponentIDs[ECSComponentIDs["NftShape"] = 1040] = "NftShape";
19
- ECSComponentIDs[ECSComponentIDs["PointerEvents"] = 1062] = "PointerEvents";
20
- ECSComponentIDs[ECSComponentIDs["PointerEventsResult"] = 1063] = "PointerEventsResult";
21
- ECSComponentIDs[ECSComponentIDs["PointerLock"] = 1074] = "PointerLock";
22
- ECSComponentIDs[ECSComponentIDs["Raycast"] = 1067] = "Raycast";
23
- ECSComponentIDs[ECSComponentIDs["RaycastResult"] = 1068] = "RaycastResult";
24
- ECSComponentIDs[ECSComponentIDs["TextShape"] = 1030] = "TextShape";
25
- ECSComponentIDs[ECSComponentIDs["UiBackground"] = 1053] = "UiBackground";
26
- ECSComponentIDs[ECSComponentIDs["UiDropdown"] = 1094] = "UiDropdown";
27
- ECSComponentIDs[ECSComponentIDs["UiDropdownResult"] = 1096] = "UiDropdownResult";
28
- ECSComponentIDs[ECSComponentIDs["UiInput"] = 1093] = "UiInput";
29
- ECSComponentIDs[ECSComponentIDs["UiInputResult"] = 1095] = "UiInputResult";
30
- ECSComponentIDs[ECSComponentIDs["UiText"] = 1052] = "UiText";
31
- ECSComponentIDs[ECSComponentIDs["UiTransform"] = 1050] = "UiTransform";
32
- ECSComponentIDs[ECSComponentIDs["VisibilityComponent"] = 1081] = "VisibilityComponent";
33
- })(ECSComponentIDs || (ECSComponentIDs = {}));