@dcl/ecs 7.1.1-4387338275.commit-167a7e2 → 7.1.1
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/engine/component.d.ts +6 -0
- package/dist/engine/grow-only-value-set-component-definition.js +10 -1
- package/dist/engine/index.d.ts +7 -0
- package/dist/engine/index.js +3 -1
- package/dist/engine/lww-element-set-component-definition.d.ts +2 -0
- package/dist/engine/lww-element-set-component-definition.js +19 -2
- package/dist/engine/types.d.ts +7 -0
- package/dist/serialization/crdt/appendValue.d.ts +15 -1
- package/dist/serialization/crdt/appendValue.js +1 -1
- package/dist/serialization/crdt/crdtMessageProtocol.d.ts +30 -1
- package/dist/serialization/crdt/crdtMessageProtocol.js +1 -1
- package/dist/serialization/crdt/deleteComponent.d.ts +14 -1
- package/dist/serialization/crdt/deleteComponent.js +1 -1
- package/dist/serialization/crdt/deleteEntity.d.ts +11 -1
- package/dist/serialization/crdt/deleteEntity.js +1 -1
- package/dist/serialization/crdt/putComponent.d.ts +15 -1
- package/dist/serialization/crdt/putComponent.js +1 -1
- package/dist/systems/crdt/index.js +5 -0
- package/package.json +3 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ISchema } from '../schemas';
|
|
2
|
+
import { ByteBuffer } from '../serialization/ByteBuffer';
|
|
2
3
|
import { CrdtMessageBody, DeleteComponentMessageBody, PutComponentMessageBody } from '../serialization/crdt';
|
|
3
4
|
import { Entity } from './entity';
|
|
4
5
|
import { DeepReadonly, DeepReadonlySet } from './readonly';
|
|
@@ -38,6 +39,11 @@ export interface BaseComponent<T> {
|
|
|
38
39
|
* @public
|
|
39
40
|
*/
|
|
40
41
|
getCrdtUpdates(): Iterable<CrdtMessageBody>;
|
|
42
|
+
/**
|
|
43
|
+
* This function writes the whole state of the component into a ByteBuffer
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
dumpCrdtState(buffer: ByteBuffer): void;
|
|
41
47
|
/**
|
|
42
48
|
* @public
|
|
43
49
|
* Marks the entity as deleted and signals it cannot be used ever again. It must
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReadWriteByteBuffer } from '../serialization/ByteBuffer';
|
|
2
|
-
import { CrdtMessageType } from '../serialization/crdt';
|
|
2
|
+
import { AppendValueOperation, CrdtMessageType } from '../serialization/crdt';
|
|
3
3
|
import { __DEV__ } from '../runtime/invariant';
|
|
4
4
|
const emptyReadonlySet = freezeSet(new Set());
|
|
5
5
|
function frozenError() {
|
|
@@ -126,6 +126,15 @@ export function createValueSetComponentDefinitionFromSchema(componentName, compo
|
|
|
126
126
|
append(_body.entityId, schema.deserialize(buf));
|
|
127
127
|
}
|
|
128
128
|
return [null, undefined];
|
|
129
|
+
},
|
|
130
|
+
dumpCrdtState: function (buffer) {
|
|
131
|
+
for (const [entity, { raw }] of data) {
|
|
132
|
+
for (const it of raw) {
|
|
133
|
+
const buf = new ReadWriteByteBuffer();
|
|
134
|
+
schema.serialize(it.value, buf);
|
|
135
|
+
AppendValueOperation.write(entity, 0, componentId, buf.toBinary(), buffer);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
129
138
|
}
|
|
130
139
|
};
|
|
131
140
|
return ret;
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -2,7 +2,14 @@ import { ByteBuffer } from '../serialization/ByteBuffer';
|
|
|
2
2
|
import { OnChangeFunction } from '../systems/crdt';
|
|
3
3
|
import { Entity } from './entity';
|
|
4
4
|
import { SystemItem } from './systems';
|
|
5
|
+
import type { IEngine, IEngineOptions } from './types';
|
|
5
6
|
export * from './input';
|
|
6
7
|
export * from './readonly';
|
|
7
8
|
export * from './types';
|
|
8
9
|
export { Entity, ByteBuffer, SystemItem, OnChangeFunction };
|
|
10
|
+
/**
|
|
11
|
+
* Internal constructor of new engines, this is an internal API
|
|
12
|
+
* @public
|
|
13
|
+
* @deprecated Prevent manual usage prefer "engine" for scene development
|
|
14
|
+
*/
|
|
15
|
+
export declare function Engine(options?: IEngineOptions): IEngine;
|
package/dist/engine/index.js
CHANGED
|
@@ -187,7 +187,9 @@ function preEngine() {
|
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
189
|
/**
|
|
190
|
-
*
|
|
190
|
+
* Internal constructor of new engines, this is an internal API
|
|
191
|
+
* @public
|
|
192
|
+
* @deprecated Prevent manual usage prefer "engine" for scene development
|
|
191
193
|
*/
|
|
192
194
|
export function Engine(options) {
|
|
193
195
|
const partialEngine = preEngine();
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ISchema } from '../schemas';
|
|
2
|
+
import { ByteBuffer } from '../serialization/ByteBuffer';
|
|
2
3
|
import { PutComponentMessageBody, DeleteComponentMessageBody, CrdtMessageBody } from '../serialization/crdt';
|
|
3
4
|
import { Entity } from './entity';
|
|
4
5
|
export declare function incrementTimestamp(entity: Entity, timestamps: Map<Entity, number>): number;
|
|
6
|
+
export declare function createDumpLwwFunctionFromCrdt(componentId: number, timestamps: Map<Entity, number>, schema: Pick<ISchema<any>, 'serialize' | 'deserialize'>, data: Map<Entity, unknown>): (buffer: ByteBuffer) => void;
|
|
5
7
|
export declare function createUpdateLwwFromCrdt(componentId: number, timestamps: Map<Entity, number>, schema: Pick<ISchema<any>, 'serialize' | 'deserialize'>, data: Map<Entity, unknown>): (msg: CrdtMessageBody) => [null | PutComponentMessageBody | DeleteComponentMessageBody, any];
|
|
6
8
|
export declare function createGetCrdtMessagesForLww(componentId: number, timestamps: Map<Entity, number>, dirtyIterator: Set<Entity>, schema: Pick<ISchema<any>, 'serialize'>, data: Map<Entity, unknown>): () => Generator<PutComponentMessageBody | DeleteComponentMessageBody, void, unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReadWriteByteBuffer } from '../serialization/ByteBuffer';
|
|
2
|
-
import { ProcessMessageResultType, CrdtMessageType } from '../serialization/crdt';
|
|
2
|
+
import { ProcessMessageResultType, CrdtMessageType, PutComponentOperation, DeleteComponent } from '../serialization/crdt';
|
|
3
3
|
import { dataCompare } from '../systems/crdt/utils';
|
|
4
4
|
import { deepReadonly } from './readonly';
|
|
5
5
|
export function incrementTimestamp(entity, timestamps) {
|
|
@@ -7,6 +7,22 @@ export function incrementTimestamp(entity, timestamps) {
|
|
|
7
7
|
timestamps.set(entity, newTimestamp);
|
|
8
8
|
return newTimestamp;
|
|
9
9
|
}
|
|
10
|
+
export function createDumpLwwFunctionFromCrdt(componentId, timestamps, schema, data) {
|
|
11
|
+
return function dumpCrdtState(buffer) {
|
|
12
|
+
for (const [entity, timestamp] of timestamps) {
|
|
13
|
+
/* istanbul ignore else */
|
|
14
|
+
if (data.has(entity)) {
|
|
15
|
+
const it = data.get(entity);
|
|
16
|
+
const buf = new ReadWriteByteBuffer();
|
|
17
|
+
schema.serialize(it, buf);
|
|
18
|
+
PutComponentOperation.write(entity, timestamp, componentId, buf.toBinary(), buffer);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
DeleteComponent.write(entity, componentId, timestamp, buffer);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
10
26
|
export function createUpdateLwwFromCrdt(componentId, timestamps, schema, data) {
|
|
11
27
|
/**
|
|
12
28
|
* Process the received message only if the lamport number recieved is higher
|
|
@@ -224,6 +240,7 @@ export function createComponentDefinitionFromSchema(componentName, componentId,
|
|
|
224
240
|
}
|
|
225
241
|
},
|
|
226
242
|
getCrdtUpdates: createGetCrdtMessagesForLww(componentId, timestamps, dirtyIterator, schema, data),
|
|
227
|
-
updateFromCrdt: createUpdateLwwFromCrdt(componentId, timestamps, schema, data)
|
|
243
|
+
updateFromCrdt: createUpdateLwwFromCrdt(componentId, timestamps, schema, data),
|
|
244
|
+
dumpCrdtState: createDumpLwwFunctionFromCrdt(componentId, timestamps, schema, data)
|
|
228
245
|
};
|
|
229
246
|
}
|
package/dist/engine/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ISchema } from '../schemas/ISchema';
|
|
2
2
|
import { MapResult, Spec } from '../schemas/Map';
|
|
3
|
+
import { OnChangeFunction } from '../systems/crdt';
|
|
3
4
|
import { Transport } from '../systems/crdt/types';
|
|
4
5
|
import { ComponentDefinition, GrowOnlyValueSetComponentDefinition, LastWriteWinElementSetComponentDefinition } from './component';
|
|
5
6
|
import { Entity, EntityState } from './entity';
|
|
@@ -32,6 +33,12 @@ export interface MapComponentDefinition<T> extends LastWriteWinElementSetCompone
|
|
|
32
33
|
*/
|
|
33
34
|
createOrReplace(entity: Entity, val?: Partial<T>): T;
|
|
34
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export interface IEngineOptions {
|
|
40
|
+
onChangeFunction: OnChangeFunction;
|
|
41
|
+
}
|
|
35
42
|
/**
|
|
36
43
|
* @public
|
|
37
44
|
*/
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import { Entity } from '../../engine/entity';
|
|
2
|
+
import { ByteBuffer } from '../ByteBuffer';
|
|
3
|
+
import { AppendValueMessage } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare namespace AppendValueOperation {
|
|
8
|
+
const MESSAGE_HEADER_LENGTH = 16;
|
|
9
|
+
/**
|
|
10
|
+
* Call this function for an optimal writing data passing the ByteBuffer
|
|
11
|
+
* already allocated
|
|
12
|
+
*/
|
|
13
|
+
function write(entity: Entity, timestamp: number, componentId: number, data: Uint8Array, buf: ByteBuffer): void;
|
|
14
|
+
function read(buf: ByteBuffer): AppendValueMessage | null;
|
|
15
|
+
}
|
|
@@ -1 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
import { ByteBuffer } from '../ByteBuffer';
|
|
2
|
+
import { CrdtMessageHeader } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare namespace CrdtMessageProtocol {
|
|
7
|
+
/**
|
|
8
|
+
* Validate if the message incoming is completed
|
|
9
|
+
* @param buf - ByteBuffer
|
|
10
|
+
*/
|
|
11
|
+
function validate(buf: ByteBuffer): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Get the current header, consuming the bytes involved.
|
|
14
|
+
* @param buf - ByteBuffer
|
|
15
|
+
* @returns header or null if there is no validated message
|
|
16
|
+
*/
|
|
17
|
+
function readHeader(buf: ByteBuffer): CrdtMessageHeader | null;
|
|
18
|
+
/**
|
|
19
|
+
* Get the current header, without consuming the bytes involved.
|
|
20
|
+
* @param buf - ByteBuffer
|
|
21
|
+
* @returns header or null if there is no validated message
|
|
22
|
+
*/
|
|
23
|
+
function getHeader(buf: ByteBuffer): CrdtMessageHeader | null;
|
|
24
|
+
/**
|
|
25
|
+
* Consume the incoming message without processing it.
|
|
26
|
+
* @param buf - ByteBuffer
|
|
27
|
+
* @returns true in case of success or false if there is no valid message.
|
|
28
|
+
*/
|
|
29
|
+
function consumeMessage(buf: ByteBuffer): boolean;
|
|
30
|
+
}
|
|
@@ -1 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { Entity } from '../../engine/entity';
|
|
2
|
+
import { ByteBuffer } from '../ByteBuffer';
|
|
3
|
+
import { DeleteComponentMessage } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare namespace DeleteComponent {
|
|
8
|
+
const MESSAGE_HEADER_LENGTH = 12;
|
|
9
|
+
/**
|
|
10
|
+
* Write DeleteComponent message
|
|
11
|
+
*/
|
|
12
|
+
function write(entity: Entity, componentId: number, timestamp: number, buf: ByteBuffer): void;
|
|
13
|
+
function read(buf: ByteBuffer): DeleteComponentMessage | null;
|
|
14
|
+
}
|
|
@@ -1 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { Entity } from '../../engine/entity';
|
|
2
|
+
import { ByteBuffer } from '../ByteBuffer';
|
|
3
|
+
import { DeleteEntityMessage } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare namespace DeleteEntity {
|
|
8
|
+
const MESSAGE_HEADER_LENGTH = 4;
|
|
9
|
+
function write(entity: Entity, buf: ByteBuffer): void;
|
|
10
|
+
function read(buf: ByteBuffer): DeleteEntityMessage | null;
|
|
11
|
+
}
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import { Entity } from '../../engine/entity';
|
|
2
|
+
import { ByteBuffer } from '../ByteBuffer';
|
|
3
|
+
import { PutComponentMessage } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare namespace PutComponentOperation {
|
|
8
|
+
const MESSAGE_HEADER_LENGTH = 16;
|
|
9
|
+
/**
|
|
10
|
+
* Call this function for an optimal writing data passing the ByteBuffer
|
|
11
|
+
* already allocated
|
|
12
|
+
*/
|
|
13
|
+
function write(entity: Entity, timestamp: number, componentId: number, data: Uint8Array, buf: ByteBuffer): void;
|
|
14
|
+
function read(buf: ByteBuffer): PutComponentMessage | null;
|
|
15
|
+
}
|
|
@@ -103,6 +103,7 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
|
|
|
103
103
|
engine.entityContainer.updateUsedEntity(msg.entityId);
|
|
104
104
|
}
|
|
105
105
|
const component = engine.getComponentOrNull(msg.componentId);
|
|
106
|
+
/* istanbul ignore else */
|
|
106
107
|
if (component) {
|
|
107
108
|
const [conflictMessage, value] = component.updateFromCrdt(msg);
|
|
108
109
|
if (conflictMessage) {
|
|
@@ -124,6 +125,10 @@ export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
|
|
|
124
125
|
onProcessEntityComponentChange && onProcessEntityComponentChange(msg.entityId, msg.type, component, value);
|
|
125
126
|
}
|
|
126
127
|
}
|
|
128
|
+
else {
|
|
129
|
+
// TODO: test this line, it is fundammental to make the editor work
|
|
130
|
+
broadcastMessages.push(msg);
|
|
131
|
+
}
|
|
127
132
|
}
|
|
128
133
|
}
|
|
129
134
|
// the last stage of the syncrhonization is to delete the entities
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/ecs",
|
|
3
|
-
"version": "7.1.1
|
|
3
|
+
"version": "7.1.1",
|
|
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/js-runtime": "7.1.1
|
|
30
|
+
"@dcl/js-runtime": "7.1.1",
|
|
31
31
|
"@dcl/protocol": "1.0.0-4177500465.commit-247c87f"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"displayName": "ECS",
|
|
41
41
|
"tsconfig": "./tsconfig.json"
|
|
42
42
|
},
|
|
43
|
-
"commit": "
|
|
43
|
+
"commit": "d41e42b3708afee075cd36ec8ab5649b119f88ad"
|
|
44
44
|
}
|