@energy8platform/game-engine 0.14.5 → 0.14.7
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/index.cjs.js +4 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +4 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/react.cjs.js +96 -12
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.esm.js +96 -12
- package/dist/react.esm.js.map +1 -1
- package/dist/ui.cjs.js +4 -3
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +4 -3
- package/dist/ui.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/react/applyProps.ts +47 -2
- package/src/react/reconciler.ts +35 -8
- package/src/ui/Modal.ts +3 -4
package/dist/react.esm.js
CHANGED
|
@@ -23,6 +23,11 @@ function extend(components) {
|
|
|
23
23
|
const RESERVED = new Set(['children', 'key', 'ref']);
|
|
24
24
|
/** Props handled by the reconciler as flex item config, not forwarded to components */
|
|
25
25
|
const FLEX_ITEM_PROPS$1 = new Set(['flexGrow', 'flexShrink', 'layoutWidth', 'layoutHeight', 'alignSelf', 'flexExclude', 'top', 'right', 'bottom', 'left']);
|
|
26
|
+
/** Base Container props applied directly to the instance (not via config) */
|
|
27
|
+
const CONTAINER_PROPS = new Set([
|
|
28
|
+
'x', 'y', 'alpha', 'visible', 'rotation', 'angle', 'zIndex',
|
|
29
|
+
'label', 'cursor', 'eventMode',
|
|
30
|
+
]);
|
|
26
31
|
// ─── UI Component helpers ────────────────────────────────
|
|
27
32
|
/**
|
|
28
33
|
* Extract a config object from React props.
|
|
@@ -32,7 +37,7 @@ const FLEX_ITEM_PROPS$1 = new Set(['flexGrow', 'flexShrink', 'layoutWidth', 'lay
|
|
|
32
37
|
function extractConfig(props) {
|
|
33
38
|
const config = {};
|
|
34
39
|
for (const key in props) {
|
|
35
|
-
if (RESERVED.has(key) || FLEX_ITEM_PROPS$1.has(key) || isEventProp(key))
|
|
40
|
+
if (RESERVED.has(key) || FLEX_ITEM_PROPS$1.has(key) || CONTAINER_PROPS.has(key) || isEventProp(key))
|
|
36
41
|
continue;
|
|
37
42
|
if (key.includes('-')) {
|
|
38
43
|
const parts = key.split('-');
|
|
@@ -57,7 +62,7 @@ function diffConfig(newProps, oldProps) {
|
|
|
57
62
|
const changed = {};
|
|
58
63
|
// New or changed props
|
|
59
64
|
for (const key in newProps) {
|
|
60
|
-
if (RESERVED.has(key) || FLEX_ITEM_PROPS$1.has(key) || isEventProp(key))
|
|
65
|
+
if (RESERVED.has(key) || FLEX_ITEM_PROPS$1.has(key) || CONTAINER_PROPS.has(key) || isEventProp(key))
|
|
61
66
|
continue;
|
|
62
67
|
if (newProps[key] !== oldProps[key]) {
|
|
63
68
|
if (key.includes('-')) {
|
|
@@ -153,6 +158,50 @@ function setNestedValue(target, path, value) {
|
|
|
153
158
|
}
|
|
154
159
|
obj[path[path.length - 1]] = value;
|
|
155
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Apply base Container props (x, y, alpha, visible, etc.) directly to the instance.
|
|
163
|
+
* Called for ALL elements — both UI components and standard PixiJS elements.
|
|
164
|
+
* Also handles scale, pivot, position, anchor via dash-notation.
|
|
165
|
+
*/
|
|
166
|
+
function applyContainerProps(instance, newProps, oldProps = {}) {
|
|
167
|
+
for (const key of CONTAINER_PROPS) {
|
|
168
|
+
if (key in newProps && newProps[key] !== oldProps[key]) {
|
|
169
|
+
try {
|
|
170
|
+
instance[key] = newProps[key];
|
|
171
|
+
}
|
|
172
|
+
catch { /* read-only */ }
|
|
173
|
+
}
|
|
174
|
+
else if (key in oldProps && !(key in newProps)) {
|
|
175
|
+
// Prop removed — reset to undefined (PixiJS defaults)
|
|
176
|
+
try {
|
|
177
|
+
instance[key] = undefined;
|
|
178
|
+
}
|
|
179
|
+
catch { /* read-only */ }
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Handle scale as uniform number or {x,y} object
|
|
183
|
+
if ('scale' in newProps && newProps.scale !== oldProps.scale) {
|
|
184
|
+
const s = newProps.scale;
|
|
185
|
+
if (typeof s === 'number') {
|
|
186
|
+
instance.scale?.set?.(s, s);
|
|
187
|
+
}
|
|
188
|
+
else if (s && typeof s === 'object') {
|
|
189
|
+
instance.scale?.set?.(s.x ?? 1, s.y ?? 1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Handle dash-notation container props: scale-x, scale-y, pivot-x, pivot-y, position-x, position-y, anchor-x, anchor-y
|
|
193
|
+
for (const key in newProps) {
|
|
194
|
+
if (!key.includes('-'))
|
|
195
|
+
continue;
|
|
196
|
+
const parts = key.split('-');
|
|
197
|
+
const root = parts[0];
|
|
198
|
+
if (root === 'scale' || root === 'pivot' || root === 'position' || root === 'anchor') {
|
|
199
|
+
if (newProps[key] !== oldProps[key]) {
|
|
200
|
+
setNestedValue(instance, parts, newProps[key]);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
156
205
|
function applyProps(instance, newProps, oldProps = {}) {
|
|
157
206
|
// Remove old props not in newProps
|
|
158
207
|
for (const key in oldProps) {
|
|
@@ -818,6 +867,17 @@ function isSuspendable(obj) {
|
|
|
818
867
|
}
|
|
819
868
|
/** Layout containers that need flush after commit phase */
|
|
820
869
|
const pendingLayoutFlush = new Set();
|
|
870
|
+
/** Suspend a layout container and all its suspendable ancestors, add them to pending flush */
|
|
871
|
+
function suspendWithAncestors(instance) {
|
|
872
|
+
let current = instance;
|
|
873
|
+
while (current) {
|
|
874
|
+
if (isSuspendable(current)) {
|
|
875
|
+
current.suspendLayout();
|
|
876
|
+
pendingLayoutFlush.add(current);
|
|
877
|
+
}
|
|
878
|
+
current = current.parent;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
821
881
|
/** Extract FlexItemConfig from props if any flex item props are present */
|
|
822
882
|
function extractFlexItemConfig(props) {
|
|
823
883
|
let config;
|
|
@@ -860,6 +920,7 @@ const hostConfig = {
|
|
|
860
920
|
// Config-based UI component: pass props as constructor config
|
|
861
921
|
const config = extractConfig(props);
|
|
862
922
|
instance = new Ctor(config);
|
|
923
|
+
applyContainerProps(instance, props);
|
|
863
924
|
applyEventProps(instance, props);
|
|
864
925
|
}
|
|
865
926
|
else {
|
|
@@ -965,11 +1026,18 @@ const hostConfig = {
|
|
|
965
1026
|
}
|
|
966
1027
|
},
|
|
967
1028
|
commitUpdate(instance, _updatePayload, _type, oldProps, newProps) {
|
|
1029
|
+
// Suspend this instance and ancestors before applying changes —
|
|
1030
|
+
// prevents intermediate relayouts with partially-updated tree
|
|
1031
|
+
const dimensionsChanged = newProps.width !== oldProps.width || newProps.height !== oldProps.height;
|
|
1032
|
+
if (isSuspendable(instance) || dimensionsChanged) {
|
|
1033
|
+
suspendWithAncestors(instance);
|
|
1034
|
+
}
|
|
968
1035
|
if (typeof instance.updateConfig === 'function') {
|
|
969
1036
|
const changed = diffConfig(newProps, oldProps);
|
|
970
1037
|
if (Object.keys(changed).length > 0) {
|
|
971
1038
|
instance.updateConfig(changed);
|
|
972
1039
|
}
|
|
1040
|
+
applyContainerProps(instance, newProps, oldProps);
|
|
973
1041
|
applyEventProps(instance, newProps, oldProps);
|
|
974
1042
|
}
|
|
975
1043
|
else {
|
|
@@ -992,11 +1060,9 @@ const hostConfig = {
|
|
|
992
1060
|
}
|
|
993
1061
|
}
|
|
994
1062
|
}
|
|
995
|
-
//
|
|
996
|
-
if (newFlexConfig || oldFlexConfig ||
|
|
997
|
-
|
|
998
|
-
instance.parent.updateLayout();
|
|
999
|
-
}
|
|
1063
|
+
// Mark ancestors dirty if flex config or dimensions changed
|
|
1064
|
+
if (newFlexConfig || oldFlexConfig || dimensionsChanged) {
|
|
1065
|
+
suspendWithAncestors(instance);
|
|
1000
1066
|
}
|
|
1001
1067
|
if (hasEventProps(newProps) && instance.eventMode === 'auto') {
|
|
1002
1068
|
instance.eventMode = 'static';
|
|
@@ -1028,8 +1094,25 @@ const hostConfig = {
|
|
|
1028
1094
|
return null;
|
|
1029
1095
|
},
|
|
1030
1096
|
resetAfterCommit() {
|
|
1031
|
-
|
|
1032
|
-
|
|
1097
|
+
if (pendingLayoutFlush.size === 0)
|
|
1098
|
+
return;
|
|
1099
|
+
// Sort by depth (deepest first) so children compute sizes before parents lay out
|
|
1100
|
+
const sorted = [...pendingLayoutFlush].sort((a, b) => {
|
|
1101
|
+
let da = 0;
|
|
1102
|
+
let n = a;
|
|
1103
|
+
while (n.parent) {
|
|
1104
|
+
da++;
|
|
1105
|
+
n = n.parent;
|
|
1106
|
+
}
|
|
1107
|
+
let db = 0;
|
|
1108
|
+
n = b;
|
|
1109
|
+
while (n.parent) {
|
|
1110
|
+
db++;
|
|
1111
|
+
n = n.parent;
|
|
1112
|
+
}
|
|
1113
|
+
return db - da; // deepest first
|
|
1114
|
+
});
|
|
1115
|
+
for (const fc of sorted) {
|
|
1033
1116
|
fc.resumeLayout();
|
|
1034
1117
|
}
|
|
1035
1118
|
pendingLayoutFlush.clear();
|
|
@@ -2186,10 +2269,11 @@ class Modal extends Container {
|
|
|
2186
2269
|
// Overlay
|
|
2187
2270
|
this._overlay = new Graphics();
|
|
2188
2271
|
this._overlay.eventMode = 'static';
|
|
2272
|
+
this._overlay.on('pointertap', () => {
|
|
2273
|
+
if (this._config.closeOnOverlay)
|
|
2274
|
+
this.hide();
|
|
2275
|
+
});
|
|
2189
2276
|
this.addChild(this._overlay);
|
|
2190
|
-
if (this._config.closeOnOverlay) {
|
|
2191
|
-
this._overlay.on('pointertap', () => this.hide());
|
|
2192
|
-
}
|
|
2193
2277
|
// Content container
|
|
2194
2278
|
this._contentContainer = new Container();
|
|
2195
2279
|
this.addChild(this._contentContainer);
|