@dcl/ecs 7.0.6-3808988484.commit-63d3e2c → 7.0.6-3823801200.commit-32470bd
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/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ByteBuffer } from '../serialization/ByteBuffer';
|
|
2
|
+
import { OnChangeFunction } from '../systems/crdt';
|
|
2
3
|
import { ComponentDefinition } from './component';
|
|
3
4
|
import { Entity } from './entity';
|
|
4
5
|
import { SystemItem } from './systems';
|
|
@@ -6,8 +7,14 @@ import type { IEngine } from './types';
|
|
|
6
7
|
export * from './input';
|
|
7
8
|
export * from './readonly';
|
|
8
9
|
export * from './types';
|
|
9
|
-
export { Entity, ByteBuffer, ComponentDefinition, SystemItem };
|
|
10
|
+
export { Entity, ByteBuffer, ComponentDefinition, SystemItem, OnChangeFunction };
|
|
10
11
|
/**
|
|
11
12
|
* @public
|
|
12
13
|
*/
|
|
13
|
-
export declare
|
|
14
|
+
export declare type IEngineOptions = {
|
|
15
|
+
onChangeFunction: OnChangeFunction;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export declare function Engine(options?: IEngineOptions): IEngine;
|
package/dist/engine/index.js
CHANGED
|
@@ -106,6 +106,9 @@ function preEngine() {
|
|
|
106
106
|
function getSystems() {
|
|
107
107
|
return systems.getSystems();
|
|
108
108
|
}
|
|
109
|
+
function componentsIter() {
|
|
110
|
+
return componentsDefinition.values();
|
|
111
|
+
}
|
|
109
112
|
function removeComponentDefinition(componentId) {
|
|
110
113
|
componentsDefinition.delete(componentId);
|
|
111
114
|
}
|
|
@@ -142,15 +145,16 @@ function preEngine() {
|
|
|
142
145
|
getComponentOrNull,
|
|
143
146
|
removeComponentDefinition,
|
|
144
147
|
removeEntityWithChildren,
|
|
145
|
-
registerCustomComponent
|
|
148
|
+
registerCustomComponent,
|
|
149
|
+
componentsIter
|
|
146
150
|
};
|
|
147
151
|
}
|
|
148
152
|
/**
|
|
149
153
|
* @public
|
|
150
154
|
*/
|
|
151
|
-
export function Engine() {
|
|
155
|
+
export function Engine(options) {
|
|
152
156
|
const engine = preEngine();
|
|
153
|
-
const crdtSystem = crdtSceneSystem(engine);
|
|
157
|
+
const crdtSystem = crdtSceneSystem(engine, options?.onChangeFunction || null);
|
|
154
158
|
async function update(dt) {
|
|
155
159
|
await crdtSystem.receiveMessages();
|
|
156
160
|
for (const system of engine.getSystems()) {
|
|
@@ -176,6 +180,7 @@ export function Engine() {
|
|
|
176
180
|
getComponent: engine.getComponent,
|
|
177
181
|
getComponentOrNull: engine.getComponentOrNull,
|
|
178
182
|
removeComponentDefinition: engine.removeComponentDefinition,
|
|
183
|
+
componentsIter: engine.componentsIter,
|
|
179
184
|
update,
|
|
180
185
|
RootEntity: 0,
|
|
181
186
|
PlayerEntity: 1,
|
package/dist/engine/types.d.ts
CHANGED
|
@@ -173,4 +173,8 @@ export declare type IEngine = {
|
|
|
173
173
|
* @param transport - transport which changes its onmessage to process CRDT messages
|
|
174
174
|
*/
|
|
175
175
|
addTransport(transport: Transport): void;
|
|
176
|
+
/**
|
|
177
|
+
* Iterator of registered components
|
|
178
|
+
*/
|
|
179
|
+
componentsIter(): Iterable<ComponentDefinition<unknown>>;
|
|
176
180
|
};
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import type { IEngine } from '../../engine';
|
|
1
|
+
import type { ComponentDefinition, IEngine } from '../../engine';
|
|
2
2
|
import { Entity } from '../../engine/entity';
|
|
3
|
+
import WireMessage from '../../serialization/wireMessage';
|
|
3
4
|
import { Transport } from './types';
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare type OnChangeFunction = (entity: Entity, component: ComponentDefinition<any>, operation: WireMessage.Enum) => void;
|
|
9
|
+
export declare function crdtSceneSystem(engine: Pick<IEngine, 'getComponentOrNull' | 'getComponent' | 'componentsIter'>, onProcessEntityComponentChange: OnChangeFunction | null): {
|
|
5
10
|
getCrdt: () => import("@dcl/crdt").State<Uint8Array>;
|
|
6
|
-
sendMessages: (dirtyEntities: Map<
|
|
11
|
+
sendMessages: (dirtyEntities: Map<ComponentDefinition<unknown>, Array<Entity>>) => Promise<void>;
|
|
7
12
|
receiveMessages: () => Promise<void>;
|
|
8
13
|
addTransport: (transport: Transport) => void;
|
|
9
|
-
updateState: () => Map<Entity
|
|
14
|
+
updateState: () => Map<ComponentDefinition<unknown>, Entity[]>;
|
|
10
15
|
};
|
|
@@ -2,7 +2,7 @@ import { crdtProtocol } from '@dcl/crdt';
|
|
|
2
2
|
import { createByteBuffer } from '../../serialization/ByteBuffer';
|
|
3
3
|
import { ComponentOperation as Message } from '../../serialization/crdt/componentOperation';
|
|
4
4
|
import WireMessage from '../../serialization/wireMessage';
|
|
5
|
-
export function crdtSceneSystem(engine) {
|
|
5
|
+
export function crdtSceneSystem(engine, onProcessEntityComponentChange) {
|
|
6
6
|
const transports = [];
|
|
7
7
|
// CRDT Client
|
|
8
8
|
const crdtClient = crdtProtocol();
|
|
@@ -106,34 +106,38 @@ export function crdtSceneSystem(engine) {
|
|
|
106
106
|
const data = createByteBuffer(opts);
|
|
107
107
|
component.upsertFromBinary(message.entity, data, false);
|
|
108
108
|
}
|
|
109
|
+
onProcessEntityComponentChange &&
|
|
110
|
+
onProcessEntityComponentChange(entity, component, type);
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
|
-
function getDirtyMap() {
|
|
113
|
-
const dirtySet = new Map();
|
|
114
|
-
for (const [componentId, definition] of engine.componentsDefinition) {
|
|
115
|
-
for (const entity of definition.dirtyIterator()) {
|
|
116
|
-
if (!dirtySet.has(entity)) {
|
|
117
|
-
dirtySet.set(entity, new Set());
|
|
118
|
-
}
|
|
119
|
-
dirtySet.get(entity).add(componentId);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return dirtySet;
|
|
123
|
-
}
|
|
124
114
|
/**
|
|
125
115
|
* Updates CRDT state of the current engine dirty components
|
|
116
|
+
*
|
|
117
|
+
* TODO: optimize this function allocations using a bitmap
|
|
118
|
+
* TODO: unify this function with sendMessages
|
|
126
119
|
*/
|
|
127
120
|
function updateState() {
|
|
128
|
-
const
|
|
129
|
-
for (const
|
|
130
|
-
|
|
131
|
-
|
|
121
|
+
const dirtyMap = new Map();
|
|
122
|
+
for (const component of engine.componentsIter()) {
|
|
123
|
+
let entitySet = null;
|
|
124
|
+
for (const entity of component.dirtyIterator()) {
|
|
125
|
+
if (!entitySet) {
|
|
126
|
+
entitySet = [];
|
|
127
|
+
dirtyMap.set(component, entitySet);
|
|
128
|
+
}
|
|
129
|
+
entitySet.push(entity);
|
|
130
|
+
// TODO: reuse shared writer to prevent extra allocations of toBinary
|
|
132
131
|
const componentValue = component.toBinaryOrNull(entity)?.toBinary() ?? null;
|
|
133
|
-
|
|
132
|
+
// TODO: do not emit event if componentValue equals the value didn't change
|
|
133
|
+
crdtClient.createEvent(entity, component._id, componentValue);
|
|
134
|
+
onProcessEntityComponentChange &&
|
|
135
|
+
onProcessEntityComponentChange(entity, component, componentValue === null
|
|
136
|
+
? WireMessage.Enum.DELETE_COMPONENT
|
|
137
|
+
: WireMessage.Enum.PUT_COMPONENT);
|
|
134
138
|
}
|
|
135
139
|
}
|
|
136
|
-
return
|
|
140
|
+
return dirtyMap;
|
|
137
141
|
}
|
|
138
142
|
/**
|
|
139
143
|
* Iterates the dirty map and generates crdt messages to be send
|
|
@@ -143,19 +147,18 @@ export function crdtSceneSystem(engine) {
|
|
|
143
147
|
const crdtMessages = getMessages(broadcastMessages);
|
|
144
148
|
const outdatedMessagesBkp = getMessages(outdatedMessages);
|
|
145
149
|
const buffer = createByteBuffer();
|
|
146
|
-
for (const [
|
|
147
|
-
for (const
|
|
150
|
+
for (const [component, entities] of dirtyEntities) {
|
|
151
|
+
for (const entity of entities) {
|
|
148
152
|
// Component will be always defined here since dirtyMap its an iterator of engine.componentsDefinition
|
|
149
|
-
const component = engine.getComponent(componentId);
|
|
150
153
|
const { timestamp } = crdtClient
|
|
151
154
|
.getState()
|
|
152
155
|
.get(entity)
|
|
153
|
-
.get(
|
|
156
|
+
.get(component._id);
|
|
154
157
|
const offset = buffer.currentWriteOffset();
|
|
155
158
|
const type = WireMessage.getType(component, entity);
|
|
156
159
|
const transportMessage = {
|
|
157
160
|
type,
|
|
158
|
-
componentId,
|
|
161
|
+
componentId: component._id,
|
|
159
162
|
entity,
|
|
160
163
|
timestamp
|
|
161
164
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/ecs",
|
|
3
|
-
"version": "7.0.6-
|
|
3
|
+
"version": "7.0.6-3823801200.commit-32470bd",
|
|
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-
|
|
30
|
+
"@dcl/crdt": "7.0.6-3823801200.commit-32470bd",
|
|
31
31
|
"@dcl/js-runtime": "file:../js-runtime",
|
|
32
32
|
"@dcl/protocol": "^1.0.0-3808528053.commit-d66d462"
|
|
33
33
|
},
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"displayName": "ECS",
|
|
42
42
|
"tsconfig": "./tsconfig.json"
|
|
43
43
|
},
|
|
44
|
-
"commit": "
|
|
44
|
+
"commit": "32470bdb44a9d3c8663f432e0d3262a09c4201cf"
|
|
45
45
|
}
|