Skip to content

Commit 5ef0582

Browse files
committed
refactor
1 parent e2db2f0 commit 5ef0582

File tree

5 files changed

+150
-128
lines changed

5 files changed

+150
-128
lines changed

src/engine/monitor-record.js

Lines changed: 110 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,22 @@ const equal = (a, b) => {
2121
* @param {unknown} obj
2222
* @returns {boolean}
2323
*/
24-
const shouldMerge = obj => typeof obj !== 'undefined' && obj !== null;
24+
const defined = obj => typeof obj !== 'undefined' && obj !== null;
2525

2626
/**
27-
* @typedef PartialRecord
27+
* For compatibility, converts an immutable.js delta to a plain JS delta.
28+
* @param {Delta} obj
29+
* @returns {JSDelta}
30+
*/
31+
const toJSDelta = obj => {
32+
if (typeof obj?.toJS === 'function') {
33+
return obj.toJS();
34+
}
35+
return obj;
36+
};
37+
38+
/**
39+
* @typedef JSDelta Delta object using regular properties.
2840
* @property {string|null} [id]
2941
* @property {string|null} [spriteName]
3042
* @property {string|null} [targetId]
@@ -43,46 +55,58 @@ const shouldMerge = obj => typeof obj !== 'undefined' && obj !== null;
4355
*/
4456

4557
/**
46-
* @implements {PartialRecord}
58+
* @typedef ImmutableJSDelta Delta object that is an immutable.js Map/OrderedMap.
59+
* @property {() => Delta} toJS
60+
*/
61+
62+
/**
63+
* @typedef {JSDelta|ImmutableJSDelta} Delta
64+
*/
65+
66+
/**
67+
* @implements {JSDelta}
4768
*/
4869
class MonitorRecord {
4970
/**
50-
* @param {PartialRecord} partial
71+
* @param {Delta} delta
5172
*/
52-
constructor (partial) {
73+
constructor (delta) {
74+
delta = toJSDelta(delta);
75+
5376
/**
5477
* Block ID
5578
*/
56-
this.id = partial.id ?? null;
79+
this.id = delta.id ?? null;
5780
/**
5881
* Present only if the monitor is sprite-specific, such as x position
5982
*/
60-
this.spriteName = partial.spriteName ?? null;
83+
this.spriteName = delta.spriteName ?? null;
6184
/**
6285
* Present only if the monitor is sprite-specific, such as x position
6386
*/
64-
this.targetId = partial.targetId ?? null;
65-
this.opcode = partial.opcode ?? null;
66-
this.value = partial.value ?? null;
67-
this.params = partial.params ?? null;
68-
this.mode = partial.mode ?? 'default';
69-
this.sliderMin = partial.sliderMin ?? 0;
70-
this.sliderMax = partial.sliderMax ?? 100;
71-
this.isDiscrete = partial.isDiscrete ?? true;
87+
this.targetId = delta.targetId ?? null;
88+
this.opcode = delta.opcode ?? null;
89+
this.value = delta.value ?? null;
90+
this.params = delta.params ?? null;
91+
this.mode = delta.mode ?? 'default';
92+
this.sliderMin = delta.sliderMin ?? 0;
93+
this.sliderMax = delta.sliderMax ?? 100;
94+
this.isDiscrete = delta.isDiscrete ?? true;
7295
/**
7396
* (x: null, y: null) Indicates that the monitor should be auto-positioned
7497
*/
75-
this.x = partial.x ?? null;
98+
this.x = delta.x ?? null;
7699
/**
77100
* (x: null, y: null) Indicates that the monitor should be auto-positioned
78101
*/
79-
this.y = partial.y ?? null;
80-
this.width = partial.width ?? 0;
81-
this.height = partial.height ?? 0;
82-
this.visible = partial.visible ?? true;
102+
this.y = delta.y ?? null;
103+
this.width = delta.width ?? 0;
104+
this.height = delta.height ?? 0;
105+
this.visible = delta.visible ?? true;
83106
}
84107

85108
/**
109+
* Exists for compatibility with code expecting an immutable.js Map
86110
* @param {string} property
87111
*/
88112
get (property) {
@@ -107,79 +131,89 @@ class MonitorRecord {
107131
}
108132

109133
/**
110-
* @param {MonitorRecord} otherRecord A different MonitorRecord
111-
* @returns {boolean}
134+
* @param {Delta} delta
135+
* @returns {boolean} true if modified
112136
*/
113-
equals (otherRecord) {
114-
return (
115-
equal(this.id, otherRecord.id) &&
116-
equal(this.spriteName, otherRecord.spriteName) &&
117-
equal(this.targetId, otherRecord.targetId) &&
118-
equal(this.opcode, otherRecord.opcode) &&
119-
equal(this.value, otherRecord.value) &&
120-
equal(this.params, otherRecord.params) &&
121-
equal(this.mode, otherRecord.mode) &&
122-
equal(this.sliderMin, otherRecord.sliderMin) &&
123-
equal(this.sliderMax, otherRecord.sliderMax) &&
124-
equal(this.isDiscrete, otherRecord.isDiscrete) &&
125-
equal(this.x, otherRecord.x) &&
126-
equal(this.y, otherRecord.y) &&
127-
equal(this.width, otherRecord.width) &&
128-
equal(this.height, otherRecord.height) &&
129-
equal(this.visible, otherRecord.visible)
130-
);
131-
}
137+
merge (delta) {
138+
delta = toJSDelta(delta);
139+
let didChange = false;
132140

133-
/**
134-
* @param {PartialRecord} partial
135-
* @returns {MonitorRecord}
136-
*/
137-
merge (partial) {
138-
if (shouldMerge(partial.id)) {
139-
this.id = partial.id;
141+
if (defined(delta.id) && !equal(this.id, delta.id)) {
142+
this.id = delta.id;
143+
didChange = true;
140144
}
141-
if (shouldMerge(partial.spriteName)) {
142-
this.spriteName = partial.spriteName;
145+
146+
if (defined(delta.spriteName) && !equal(this.spriteName, delta.spriteName)) {
147+
this.spriteName = delta.spriteName;
148+
didChange = true;
143149
}
144-
if (shouldMerge(partial.targetId)) {
145-
this.targetId = partial.targetId;
150+
151+
if (defined(delta.targetId) && !equal(this.targetId, delta.targetId)) {
152+
this.targetId = delta.targetId;
153+
didChange = true;
146154
}
147-
if (shouldMerge(partial.opcode)) {
148-
this.opcode = partial.opcode;
155+
156+
if (defined(delta.opcode) && !equal(this.opcode, delta.opcode)) {
157+
this.opcode = delta.opcode;
158+
didChange = true;
149159
}
150-
if (shouldMerge(partial.value)) {
151-
this.value = partial.value;
160+
161+
if (defined(delta.value) && !equal(this.value, delta.value)) {
162+
this.value = delta.value;
163+
didChange = true;
152164
}
153-
if (shouldMerge(partial.params)) {
154-
this.params = partial.params;
165+
166+
if (defined(delta.params) && !equal(this.params, delta.params)) {
167+
this.params = delta.params;
168+
didChange = true;
155169
}
156-
if (shouldMerge(partial.mode)) {
157-
this.mode = partial.mode;
170+
171+
if (defined(delta.mode) && !equal(this.mode, delta.mode)) {
172+
this.mode = delta.mode;
173+
didChange = true;
158174
}
159-
if (shouldMerge(partial.sliderMin)) {
160-
this.sliderMin = partial.sliderMin;
175+
176+
if (defined(delta.sliderMin) && !equal(this.sliderMin, delta.sliderMin)) {
177+
this.sliderMin = delta.sliderMin;
178+
didChange = true;
161179
}
162-
if (shouldMerge(partial.sliderMax)) {
163-
this.sliderMax = partial.sliderMax;
180+
181+
if (defined(delta.sliderMax) && !equal(this.sliderMax, delta.sliderMax)) {
182+
this.sliderMax = delta.sliderMax;
183+
didChange = true;
164184
}
165-
if (shouldMerge(partial.isDiscrete)) {
166-
this.isDiscrete = partial.isDiscrete;
185+
186+
if (defined(delta.isDiscrete) && !equal(this.isDiscrete, delta.isDiscrete)) {
187+
this.isDiscrete = delta.isDiscrete;
188+
didChange = true;
167189
}
168-
if (shouldMerge(partial.x)) {
169-
this.x = partial.x;
190+
191+
if (defined(delta.x) && !equal(this.x, delta.x)) {
192+
this.x = delta.x;
193+
didChange = true;
170194
}
171-
if (shouldMerge(partial.y)) {
172-
this.y = partial.y;
195+
196+
if (defined(delta.y) && !equal(this.y, delta.y)) {
197+
this.y = delta.y;
198+
didChange = true;
173199
}
174-
if (shouldMerge(partial.width)) {
175-
this.width = partial.width;
200+
201+
if (defined(delta.width) && !equal(this.width, delta.width)) {
202+
this.width = delta.width;
203+
didChange = true;
176204
}
177-
if (shouldMerge(partial.height)) {
178-
this.height = partial.height;
205+
206+
if (defined(delta.height) && !equal(this.height, delta.height)) {
207+
this.height = delta.height;
208+
didChange = true;
179209
}
180-
if (shouldMerge(partial.visible)) {
181-
this.visible = partial.visible;
210+
211+
if (defined(delta.visible) && !equal(this.visible, delta.visible)) {
212+
this.visible = delta.visible;
213+
didChange = true;
182214
}
215+
216+
return didChange;
183217
}
184218
}
185219

src/engine/runtime.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,7 +2281,7 @@ class Runtime extends EventEmitter {
22812281
// tw: explicitly emit a MONITORS_UPDATE instead of relying on implicit behavior of _step()
22822282
if (!this._monitorState.empty()) {
22832283
this._monitorState = new MonitorState();
2284-
this.emit(Runtime.MONITORS_UPDATE, this._monitorState);
2284+
this.emit(Runtime.MONITORS_UPDATE, this._monitorState.shallowClone());
22852285
}
22862286
this.emit(Runtime.RUNTIME_DISPOSED);
22872287
this.ioDevices.clock.resetProjectTimer();
@@ -2572,7 +2572,7 @@ class Runtime extends EventEmitter {
25722572
}
25732573

25742574
if (this._monitorState.dirty) {
2575-
this.emit(Runtime.MONITORS_UPDATE, this._monitorState);
2575+
this.emit(Runtime.MONITORS_UPDATE, this._monitorState.shallowClone());
25762576
this._monitorState.dirty = false;
25772577
}
25782578

@@ -2699,14 +2699,14 @@ class Runtime extends EventEmitter {
26992699
if (this._monitorState.size > 0) {
27002700
const offsetX = deltaX / 2;
27012701
const offsetY = deltaY / 2;
2702-
for (const monitor of this._monitorState.values()) {
2702+
for (const monitor of this._monitorState.valueSeq()) {
27032703
this.requestUpdateMonitor({
27042704
id: monitor.id,
27052705
x: monitor.get('x') + offsetX,
27062706
y: monitor.get('y') + offsetY
27072707
});
27082708
}
2709-
this.emit(Runtime.MONITORS_UPDATE, this._monitorState);
2709+
this.emit(Runtime.MONITORS_UPDATE, this._monitorState.shallowClone());
27102710
}
27112711

27122712
this.stageWidth = width;

0 commit comments

Comments
 (0)