Skip to content

Commit 0bcff8b

Browse files
committed
fix(node): prevent self-wire deletion in orthogonal routing
1 parent 0e58e46 commit 0bcff8b

File tree

2 files changed

+224
-140
lines changed

2 files changed

+224
-140
lines changed

src/simulator/src/node.js

Lines changed: 112 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function replace(node, index) {
4242
}
4343
var { scope } = node
4444
var { parent } = node
45-
parent.nodeList = parent.nodeList.filter(x=> x !== node);
45+
parent.nodeList = parent.nodeList.filter((x) => x !== node)
4646
node.delete()
4747
node = scope.allNodes[index]
4848
node.parent = parent
@@ -122,9 +122,13 @@ function extractNode(x, scope, parent) {
122122
// input node=0
123123
// intermediate node =2
124124

125-
window.NODE_INPUT = 0
126-
window.NODE_OUTPUT = 1
127-
window.NODE_INTERMEDIATE = 2
125+
const NODE_INPUT = 0
126+
const NODE_OUTPUT = 1
127+
const NODE_INTERMEDIATE = 2
128+
129+
window.NODE_INPUT = NODE_INPUT
130+
window.NODE_OUTPUT = NODE_OUTPUT
131+
window.NODE_INTERMEDIATE = NODE_INTERMEDIATE
128132
/**
129133
* used to give id to a node.
130134
* @type {number}
@@ -288,9 +292,12 @@ export default class Node {
288292
* Refreshes a node after roation of parent
289293
*/
290294
refresh() {
295+
// console.log(`Refreshing node ${this.id}`)
291296
this.updateRotation()
292297
for (var i = 0; i < this.connections.length; i++) {
293-
this.connections[i].connections = this.connections[i].connections.filter(x => x !== this)
298+
this.connections[i].connections = this.connections[
299+
i
300+
].connections.filter((x) => x !== this)
294301
}
295302
this.scope.timeStamp = new Date().getTime()
296303
this.connections = []
@@ -372,8 +379,8 @@ export default class Node {
372379
* disconnecting two nodes connected wirelessly
373380
*/
374381
disconnectWireLess(n) {
375-
this.connections = this.connections.filter(x => x !== n)
376-
n.connections = n.connections.filter(x => x !== this)
382+
this.connections = this.connections.filter((x) => x !== n)
383+
n.connections = n.connections.filter((x) => x !== this)
377384

378385
this.scope.timeStamp = new Date().getTime()
379386
}
@@ -386,7 +393,7 @@ export default class Node {
386393
// Since output node forces its value on its neighbours, remove its contentions.
387394
// An existing contention will now trickle to the other output node that was causing
388395
// the contention.
389-
simulationArea.contentionPending.removeAllContentionsForNode(this);
396+
simulationArea.contentionPending.removeAllContentionsForNode(this)
390397
}
391398
// Remove Propogation of values (TriState)
392399
if (this.value == undefined) {
@@ -412,7 +419,10 @@ export default class Node {
412419
this.parent.isResolvable() &&
413420
!this.parent.queueProperties.inQueue
414421
) {
415-
if (this.parent.objectType == 'TriState' || this.parent.objectType == 'ControlledInverter') {
422+
if (
423+
this.parent.objectType == 'TriState' ||
424+
this.parent.objectType == 'ControlledInverter'
425+
) {
416426
if (this.parent.state.value) {
417427
simulationArea.simulationQueue.add(this.parent)
418428
}
@@ -430,64 +440,83 @@ export default class Node {
430440
if (this.parent.isResolvable()) {
431441
simulationArea.simulationQueue.add(this.parent)
432442
}
433-
}
434-
else if (this.type == NODE_OUTPUT) {
443+
} else if (this.type == NODE_OUTPUT) {
435444
// Since output node forces its value on its neighbours, remove its contentions.
436445
// An existing contention will now trickle to the other output node that was causing
437446
// the contention.
438-
simulationArea.contentionPending.removeAllContentionsForNode(this);
447+
simulationArea.contentionPending.removeAllContentionsForNode(this)
439448
}
440449

441450
for (var i = 0; i < this.connections.length; i++) {
442-
const node = this.connections[i];
451+
const node = this.connections[i]
443452

444453
switch (node.type) {
445-
// TODO: For an output node, a downstream value (value given by elements other than the parent)
446-
// should be overwritten in contention check and should not cause contention.
447-
case NODE_OUTPUT:
448-
if (node.value != this.value || node.bitWidth != this.bitWidth) {
449-
// Check contentions
450-
if (node.value != undefined && node.parent.objectType != 'SubCircuit'
451-
&& !(node.subcircuitOverride && node.scope != this.scope)) {
452-
// Tristate has always been a pain in the ass.
453-
if ((node.parent.objectType == 'TriState' || node.parent.objectType == 'ControlledInverter') && node.value != undefined) {
454-
if (node.parent.state.value) {
455-
simulationArea.contentionPending.add(node, this);
456-
break;
454+
// TODO: For an output node, a downstream value (value given by elements other than the parent)
455+
// should be overwritten in contention check and should not cause contention.
456+
case NODE_OUTPUT:
457+
if (
458+
node.value != this.value ||
459+
node.bitWidth != this.bitWidth
460+
) {
461+
// Check contentions
462+
if (
463+
node.value != undefined &&
464+
node.parent.objectType != 'SubCircuit' &&
465+
!(
466+
node.subcircuitOverride &&
467+
node.scope != this.scope
468+
)
469+
) {
470+
// Tristate has always been a pain in the ass.
471+
if (
472+
(node.parent.objectType == 'TriState' ||
473+
node.parent.objectType ==
474+
'ControlledInverter') &&
475+
node.value != undefined
476+
) {
477+
if (node.parent.state.value) {
478+
simulationArea.contentionPending.add(
479+
node,
480+
this
481+
)
482+
break
483+
}
484+
} else {
485+
simulationArea.contentionPending.add(node, this)
486+
break
457487
}
458488
}
459-
else {
460-
simulationArea.contentionPending.add(node, this);
461-
break;
462-
}
489+
} else {
490+
// Output node was given an agreeing value, so remove any contention
491+
// entry between these two nodes if it exists.
492+
simulationArea.contentionPending.remove(node, this)
463493
}
464-
} else {
465-
// Output node was given an agreeing value, so remove any contention
466-
// entry between these two nodes if it exists.
467-
simulationArea.contentionPending.remove(node, this);
468-
}
469-
470-
// Fallthrough. NODE_OUTPUT propagates like a contention checked NODE_INPUT
471-
case NODE_INPUT:
472-
// Check bitwidths
473-
if (this.bitWidth != node.bitWidth) {
474-
this.highlighted = true;
475-
node.highlighted = true;
476-
showError(`BitWidth Error: ${this.bitWidth} and ${node.bitWidth}`);
477-
break;
478-
}
479494

480-
// Fallthrough. NODE_INPUT propagates like a bitwidth checked NODE_INTERMEDIATE
481-
case NODE_INTERMEDIATE:
495+
// Fallthrough. NODE_OUTPUT propagates like a contention checked NODE_INPUT
496+
case NODE_INPUT:
497+
// Check bitwidths
498+
if (this.bitWidth != node.bitWidth) {
499+
this.highlighted = true
500+
node.highlighted = true
501+
showError(
502+
`BitWidth Error: ${this.bitWidth} and ${node.bitWidth}`
503+
)
504+
break
505+
}
482506

483-
if (node.value != this.value || node.bitWidth != this.bitWidth) {
484-
// Propagate
485-
node.bitWidth = this.bitWidth;
486-
node.value = this.value;
487-
simulationArea.simulationQueue.add(node);
488-
}
489-
default:
490-
break;
507+
// Fallthrough. NODE_INPUT propagates like a bitwidth checked NODE_INTERMEDIATE
508+
case NODE_INTERMEDIATE:
509+
if (
510+
node.value != this.value ||
511+
node.bitWidth != this.bitWidth
512+
) {
513+
// Propagate
514+
node.bitWidth = this.bitWidth
515+
node.value = this.value
516+
simulationArea.simulationQueue.add(node)
517+
}
518+
default:
519+
break
491520
}
492521
}
493522
}
@@ -663,7 +692,8 @@ export default class Node {
663692
*/
664693
checkDeleted() {
665694
if (this.deleted) this.delete()
666-
if (this.connections.length == 0 && this.type == NODE_INTERMEDIATE) this.delete()
695+
if (this.connections.length == 0 && this.type == NODE_INTERMEDIATE)
696+
this.delete()
667697
}
668698

669699
/**
@@ -725,7 +755,10 @@ export default class Node {
725755
if (
726756
simulationArea.multipleObjectSelections.includes(this)
727757
) {
728-
simulationArea.multipleObjectSelections = simulationArea.multipleObjectSelections.filter(x=> x !== this);
758+
simulationArea.multipleObjectSelections =
759+
simulationArea.multipleObjectSelections.filter(
760+
(x) => x !== this
761+
)
729762
} else {
730763
simulationArea.multipleObjectSelections.push(this)
731764
}
@@ -836,15 +869,7 @@ export default class Node {
836869

837870
if (x != x2 && y != y2) {
838871
// Rare Exception Cases
839-
if (
840-
this.prev == 'a' &&
841-
distance(
842-
simulationArea.mouseX,
843-
simulationArea.mouseY,
844-
this.absX(),
845-
this.absY()
846-
) >= 10
847-
) {
872+
if (this.prev == 'a') {
848873
if (
849874
Math.abs(
850875
this.x + this.parent.x - simulationArea.mouseX
@@ -915,7 +940,10 @@ export default class Node {
915940
simulationArea.lastSelected = n2
916941
}
917942

918-
if (this.type == NODE_INTERMEDIATE && simulationArea.mouseDown == false) {
943+
if (
944+
this.type == NODE_INTERMEDIATE &&
945+
simulationArea.mouseDown == false
946+
) {
919947
if (this.connections.length == 2) {
920948
if (
921949
this.connections[0].absX() == this.connections[1].absX() ||
@@ -932,17 +960,25 @@ export default class Node {
932960
* function delete a node
933961
*/
934962
delete() {
963+
// console.log(`Deleting node ${this.id}`)
935964
updateSimulationSet(true)
936965
this.deleted = true
937-
this.parent.scope.allNodes = this.parent.scope.allNodes.filter(x => x !== this)
938-
this.parent.scope.nodes = this.parent.scope.nodes.filter(x => x !== this)
966+
this.parent.scope.allNodes = this.parent.scope.allNodes.filter(
967+
(x) => x !== this
968+
)
969+
this.parent.scope.nodes = this.parent.scope.nodes.filter(
970+
(x) => x !== this
971+
)
939972

940-
this.parent.scope.root.nodeList = this.parent.scope.root.nodeList.filter(x => x !== this) // Hope this works! - Can cause bugs
973+
this.parent.scope.root.nodeList =
974+
this.parent.scope.root.nodeList.filter((x) => x !== this) // Hope this works! - Can cause bugs
941975

942976
if (simulationArea.lastSelected == this)
943977
simulationArea.lastSelected = undefined
944978
for (var i = 0; i < this.connections.length; i++) {
945-
this.connections[i].connections = this.connections[i].connections.filter(x => x !== this)
979+
this.connections[i].connections = this.connections[
980+
i
981+
].connections.filter((x) => x !== this)
946982
this.connections[i].checkDeleted()
947983
}
948984

@@ -1000,6 +1036,12 @@ export default class Node {
10001036
if (n == undefined) {
10011037
for (var i = 0; i < this.parent.scope.wires.length; i++) {
10021038
if (this.parent.scope.wires[i].checkConvergence(this)) {
1039+
if (
1040+
this.parent.scope.wires[i].node1 === this ||
1041+
this.parent.scope.wires[i].node2 === this
1042+
) {
1043+
continue
1044+
}
10031045
var n = this
10041046
if (this.type != NODE_INTERMEDIATE) {
10051047
n = new Node(

0 commit comments

Comments
 (0)