@dcl/react-ecs 7.28.1-34907286167.commit-d2f06b5 → 7.28.1-34955459026.commit-7db2d46
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/reconciler/index.js +37 -47
- package/dist/system.d.ts +0 -10
- package/dist/system.js +14 -44
- package/package.json +3 -3
package/dist/reconciler/index.js
CHANGED
|
@@ -46,10 +46,7 @@ export function createReconciler(engine, pointerEvents) {
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
function updateTree(instance, props) {
|
|
49
|
-
|
|
50
|
-
// neighbour is written as 0 so the first child of any parent (the canvas root
|
|
51
|
-
// included) serializes the same way as an explicit `rightOf: 0`.
|
|
52
|
-
upsertComponent(instance, { ...props, rightOf: props.rightOf ?? 0 }, 'uiTransform');
|
|
49
|
+
upsertComponent(instance, props, 'uiTransform');
|
|
53
50
|
}
|
|
54
51
|
function upsertListener(instance, update) {
|
|
55
52
|
if (update.type === 'delete' || !update.props) {
|
|
@@ -150,6 +147,8 @@ export function createReconciler(engine, pointerEvents) {
|
|
|
150
147
|
}
|
|
151
148
|
}
|
|
152
149
|
function appendChild(parent, child) {
|
|
150
|
+
if (!child || !Object.keys(parent).length)
|
|
151
|
+
return;
|
|
153
152
|
const isReorder = parent._child.find((c) => c.entity === child.entity);
|
|
154
153
|
// If its a reorder its seems that its a mutation of an array with key prop
|
|
155
154
|
// We need to move the child to the end of the array
|
|
@@ -192,36 +191,6 @@ export function createReconciler(engine, pointerEvents) {
|
|
|
192
191
|
}
|
|
193
192
|
removeChildEntity(child);
|
|
194
193
|
}
|
|
195
|
-
function insertBefore(parentInstance, child, beforeChild) {
|
|
196
|
-
// Handle reorder: if child already exists in this parent, remove it from its old position
|
|
197
|
-
// and fix up the old neighbor's rightOf before inserting at the new position.
|
|
198
|
-
const existingIndex = parentInstance._child.findIndex((c) => c.entity === child.entity);
|
|
199
|
-
if (existingIndex !== -1) {
|
|
200
|
-
// If beforeChild.rightOf already points to child, child is already in the correct
|
|
201
|
-
// position in the rightOf chain. Setting child.rightOf = beforeChild.rightOf would
|
|
202
|
-
// produce a self-cycle (child.rightOf = child.entity).
|
|
203
|
-
if (beforeChild.rightOf === child.entity) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const oldNextSibling = parentInstance._child[existingIndex + 1];
|
|
207
|
-
if (oldNextSibling) {
|
|
208
|
-
oldNextSibling.rightOf = child.rightOf;
|
|
209
|
-
updateTree(oldNextSibling, { rightOf: oldNextSibling.rightOf });
|
|
210
|
-
}
|
|
211
|
-
parentInstance._child.splice(existingIndex, 1);
|
|
212
|
-
}
|
|
213
|
-
const beforeChildIndex = parentInstance._child.findIndex((c) => c.entity === beforeChild.entity);
|
|
214
|
-
parentInstance._child = [
|
|
215
|
-
...parentInstance._child.slice(0, beforeChildIndex),
|
|
216
|
-
child,
|
|
217
|
-
...parentInstance._child.slice(beforeChildIndex)
|
|
218
|
-
];
|
|
219
|
-
child.rightOf = beforeChild.rightOf;
|
|
220
|
-
beforeChild.rightOf = child.entity;
|
|
221
|
-
child.parent = parentInstance.entity;
|
|
222
|
-
updateTree(child, { rightOf: child.rightOf, parent: child.parent });
|
|
223
|
-
updateTree(beforeChild, { rightOf: beforeChild.rightOf });
|
|
224
|
-
}
|
|
225
194
|
function updateOnChange(entity, componentId, state) {
|
|
226
195
|
const hasEvent = changeEvents.has(entity);
|
|
227
196
|
const event = changeEvents.get(entity) || changeEvents.set(entity, new Map()).get(entity);
|
|
@@ -276,7 +245,6 @@ export function createReconciler(engine, pointerEvents) {
|
|
|
276
245
|
appendChild,
|
|
277
246
|
appendChildToContainer: appendChild,
|
|
278
247
|
appendInitialChild: appendChild,
|
|
279
|
-
insertInContainerBefore: insertBefore,
|
|
280
248
|
removeChild: removeChild,
|
|
281
249
|
prepareUpdate(_instance, _type, oldProps, newProps) {
|
|
282
250
|
return componentKeys
|
|
@@ -297,20 +265,42 @@ export function createReconciler(engine, pointerEvents) {
|
|
|
297
265
|
}
|
|
298
266
|
}
|
|
299
267
|
},
|
|
300
|
-
insertBefore,
|
|
301
|
-
|
|
268
|
+
insertBefore(parentInstance, child, beforeChild) {
|
|
269
|
+
// Handle reorder: if child already exists in this parent, remove it from its old position
|
|
270
|
+
// and fix up the old neighbor's rightOf before inserting at the new position.
|
|
271
|
+
const existingIndex = parentInstance._child.findIndex((c) => c.entity === child.entity);
|
|
272
|
+
if (existingIndex !== -1) {
|
|
273
|
+
// If beforeChild.rightOf already points to child, child is already in the correct
|
|
274
|
+
// position in the rightOf chain. Setting child.rightOf = beforeChild.rightOf would
|
|
275
|
+
// produce a self-cycle (child.rightOf = child.entity).
|
|
276
|
+
if (beforeChild.rightOf === child.entity) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const oldNextSibling = parentInstance._child[existingIndex + 1];
|
|
280
|
+
if (oldNextSibling) {
|
|
281
|
+
oldNextSibling.rightOf = child.rightOf;
|
|
282
|
+
updateTree(oldNextSibling, { rightOf: oldNextSibling.rightOf });
|
|
283
|
+
}
|
|
284
|
+
parentInstance._child.splice(existingIndex, 1);
|
|
285
|
+
}
|
|
286
|
+
const beforeChildIndex = parentInstance._child.findIndex((c) => c.entity === beforeChild.entity);
|
|
287
|
+
parentInstance._child = [
|
|
288
|
+
...parentInstance._child.slice(0, beforeChildIndex),
|
|
289
|
+
child,
|
|
290
|
+
...parentInstance._child.slice(beforeChildIndex)
|
|
291
|
+
];
|
|
292
|
+
child.rightOf = beforeChild.rightOf;
|
|
293
|
+
beforeChild.rightOf = child.entity;
|
|
294
|
+
child.parent = parentInstance.entity;
|
|
295
|
+
updateTree(child, { rightOf: child.rightOf, parent: child.parent });
|
|
296
|
+
updateTree(beforeChild, { rightOf: beforeChild.rightOf });
|
|
297
|
+
},
|
|
298
|
+
removeChildFromContainer(parenInstance, child) {
|
|
299
|
+
removeChildEntity(child);
|
|
300
|
+
}
|
|
302
301
|
};
|
|
303
302
|
const reconciler = Reconciler(hostConfig);
|
|
304
|
-
|
|
305
|
-
// top-level elements get the same parent/rightOf bookkeeping as any other
|
|
306
|
-
// sibling group. It is never rendered itself.
|
|
307
|
-
const containerInstance = {
|
|
308
|
-
entity: CANVAS_ROOT_ENTITY,
|
|
309
|
-
_child: [],
|
|
310
|
-
parent: undefined,
|
|
311
|
-
rightOf: undefined
|
|
312
|
-
};
|
|
313
|
-
const root = reconciler.createContainer(containerInstance, 0, null, false, null, '',
|
|
303
|
+
const root = reconciler.createContainer({}, 0, null, false, null, '',
|
|
314
304
|
/* istanbul ignore next */
|
|
315
305
|
function () { }, null);
|
|
316
306
|
return {
|
package/dist/system.d.ts
CHANGED
|
@@ -27,16 +27,6 @@ export type UiRendererOptions = {
|
|
|
27
27
|
* can use different insets simultaneously.
|
|
28
28
|
*/
|
|
29
29
|
screenInset?: UiScreenInset;
|
|
30
|
-
/**
|
|
31
|
-
* Stacking order of this renderer's UI relative to the other renderers (the main
|
|
32
|
-
* one and every `addUiRenderer`). Higher values render in front. When omitted,
|
|
33
|
-
* renderers stack in the order they first render, later ones on top; among those
|
|
34
|
-
* first rendered in the same tick the main UI goes at the back.
|
|
35
|
-
*
|
|
36
|
-
* It is applied to the renderer's root container entity, so it only orders whole
|
|
37
|
-
* renderers against each other; elements inside a renderer keep their own `zIndex`.
|
|
38
|
-
*/
|
|
39
|
-
zIndex?: number;
|
|
40
30
|
};
|
|
41
31
|
/**
|
|
42
32
|
* @public
|
package/dist/system.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as ecsComponents from '@dcl/ecs/dist/components';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { createReconciler } from './reconciler';
|
|
5
5
|
import { getUiScaleFactor, resetInteractableArea, resetScreenInsetArea, resetUiScaleFactor, setInteractableArea, setScreenInsetArea, setUiScaleFactor } from './components/utils';
|
|
6
|
-
import { InteractableArea, ScreenInsetArea
|
|
6
|
+
import { InteractableArea, ScreenInsetArea } from './components';
|
|
7
7
|
import { isMobile } from './platform';
|
|
8
8
|
/**
|
|
9
9
|
* Default virtual screen size used on mobile platforms, and the size 16:9
|
|
@@ -47,14 +47,6 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
47
47
|
let uiComponent = undefined;
|
|
48
48
|
let mainOptions = undefined;
|
|
49
49
|
const additionalRenderers = new Map();
|
|
50
|
-
// Renderers are laid out in the order they first render, later ones on top, with
|
|
51
|
-
// the main UI first among those first rendered in the same tick. That is the order
|
|
52
|
-
// their entities were created in before the stacking was explicit, so scenes that
|
|
53
|
-
// set no zIndex keep the stacking they had. A renderer gets its sequence number the
|
|
54
|
-
// first time it renders and keeps it when replaced; the Map iterates in insertion
|
|
55
|
-
// order, so it is already sorted by `order` and only the main UI has to be slotted in.
|
|
56
|
-
let nextOrder = 0;
|
|
57
|
-
let mainOrder = undefined;
|
|
58
50
|
const UiCanvasInformation = ecsComponents.UiCanvasInformation(engine);
|
|
59
51
|
// Unique owner to prevent other UI systems resetting this scale factor.
|
|
60
52
|
const uiScaleFactorOwner = Symbol('react-ecs-ui-scale');
|
|
@@ -127,58 +119,37 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
127
119
|
/**
|
|
128
120
|
* Wraps a renderer's component in a container positioned within the selected
|
|
129
121
|
* screen inset area. `'none'` adds no wrapper, leaving the UI on the whole
|
|
130
|
-
* screen
|
|
131
|
-
* renderer, so each renderer can use a different inset.
|
|
122
|
+
* screen. Applied per renderer, so each renderer can use a different inset.
|
|
132
123
|
*/
|
|
133
|
-
function wrapWithScreenInset(ui,
|
|
134
|
-
const zIndex = options?.zIndex;
|
|
135
|
-
// Only forward a provided zIndex: `{ zIndex: undefined }` would override the
|
|
136
|
-
// transform parser default and change what is written for every renderer.
|
|
137
|
-
const wrapperProps = zIndex === undefined ? { key } : { key, uiTransform: { zIndex } };
|
|
124
|
+
function wrapWithScreenInset(ui, inset, key) {
|
|
138
125
|
// An omitted inset is resolved to DEFAULT_SCREEN_INSET ('device') before the
|
|
139
126
|
// switch, so it lands on `case 'device'`. Only an explicit 'none' reaches the
|
|
140
127
|
// `default` clause below — the two are unrelated despite sharing a name.
|
|
141
|
-
switch (
|
|
128
|
+
switch (inset ?? DEFAULT_SCREEN_INSET) {
|
|
142
129
|
case 'device':
|
|
143
|
-
return React.createElement(ScreenInsetArea,
|
|
130
|
+
return React.createElement(ScreenInsetArea, { key }, React.createElement(ui));
|
|
144
131
|
case 'interactable':
|
|
145
|
-
return React.createElement(InteractableArea,
|
|
132
|
+
return React.createElement(InteractableArea, { key }, React.createElement(ui));
|
|
146
133
|
// 'none' — the whole screen, no wrapper entity
|
|
147
134
|
default:
|
|
148
|
-
|
|
149
|
-
return React.createElement(ui, { key });
|
|
150
|
-
// A whole-screen container: absolutely positioned on every edge so it
|
|
151
|
-
// fills the canvas, with the zIndex the renderer is stacked by.
|
|
152
|
-
return React.createElement(UiEntity, {
|
|
153
|
-
key,
|
|
154
|
-
uiTransform: { positionType: 'absolute', position: { top: 0, left: 0, right: 0, bottom: 0 }, zIndex }
|
|
155
|
-
}, React.createElement(ui));
|
|
135
|
+
return React.createElement(ui, { key });
|
|
156
136
|
}
|
|
157
137
|
}
|
|
158
138
|
function ReactBasedUiSystem() {
|
|
159
139
|
const components = [];
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
140
|
+
// Add main UI component
|
|
141
|
+
if (uiComponent) {
|
|
142
|
+
components.push(wrapWithScreenInset(uiComponent, mainOptions?.screenInset, '__main__'));
|
|
143
|
+
}
|
|
163
144
|
const entitiesToRemove = [];
|
|
164
145
|
for (const [entity, entry] of additionalRenderers) {
|
|
165
146
|
// Check for entity-based cleanup
|
|
166
147
|
if (engine.getEntityState(entity) === EntityState.Removed) {
|
|
167
148
|
entitiesToRemove.push(entity);
|
|
168
|
-
continue;
|
|
169
149
|
}
|
|
170
|
-
|
|
171
|
-
entry.
|
|
172
|
-
// The main UI goes right before the first renderer that rendered after it.
|
|
173
|
-
if (!mainPushed && mainOrder < entry.order) {
|
|
174
|
-
components.push(wrapWithScreenInset(uiComponent, mainOptions, '__main__'));
|
|
175
|
-
mainPushed = true;
|
|
150
|
+
else {
|
|
151
|
+
components.push(wrapWithScreenInset(entry.ui, entry.options?.screenInset, `__entity_${entity}__`));
|
|
176
152
|
}
|
|
177
|
-
components.push(wrapWithScreenInset(entry.ui, entry.options, `__entity_${entity}__`));
|
|
178
|
-
}
|
|
179
|
-
// Main UI first rendered after every other renderer (or alone): it goes on top.
|
|
180
|
-
if (!mainPushed) {
|
|
181
|
-
components.push(wrapWithScreenInset(uiComponent, mainOptions, '__main__'));
|
|
182
153
|
}
|
|
183
154
|
// Entity-based cleanup
|
|
184
155
|
for (const entity of entitiesToRemove) {
|
|
@@ -254,8 +225,7 @@ export function createReactBasedUiSystem(engine, pointerSystem) {
|
|
|
254
225
|
mainOptions = options;
|
|
255
226
|
},
|
|
256
227
|
addUiRenderer(entity, ui, options) {
|
|
257
|
-
|
|
258
|
-
additionalRenderers.set(entity, { ui, options, order: additionalRenderers.get(entity)?.order });
|
|
228
|
+
additionalRenderers.set(entity, { ui, options });
|
|
259
229
|
},
|
|
260
230
|
removeUiRenderer(entity) {
|
|
261
231
|
additionalRenderers.delete(entity);
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/react-ecs",
|
|
3
3
|
"description": "Decentraland ECS",
|
|
4
|
-
"version": "7.28.1-
|
|
4
|
+
"version": "7.28.1-34955459026.commit-7db2d46",
|
|
5
5
|
"author": "DCL",
|
|
6
6
|
"bugs": "https://github.com/decentraland/js-sdk-toolchain/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@dcl/ecs": "7.28.1-
|
|
8
|
+
"@dcl/ecs": "7.28.1-34955459026.commit-7db2d46",
|
|
9
9
|
"react": "^18.2.0",
|
|
10
10
|
"react-reconciler": "^0.29.0"
|
|
11
11
|
},
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"tsconfig": "./tsconfig.json"
|
|
41
41
|
},
|
|
42
42
|
"types": "./dist/index.d.ts",
|
|
43
|
-
"commit": "
|
|
43
|
+
"commit": "7db2d4613572a8d72af9166b3df228a3b8f8c427"
|
|
44
44
|
}
|