0.2.5: Fixed linking alignment, fixed clock syncing on input reset, added recursion detection for runaway logic loops

This commit is contained in:
MatCat 2021-02-21 18:06:52 -08:00
parent 3d2ed2f9d7
commit 6f50294e8d
3 changed files with 45 additions and 4 deletions

View File

@ -12,6 +12,11 @@ To be decided, but at this moment this code is open source and free to use for n
## Changelog
### 0.2.5
* Fixed clock sync issue when disabled
* Added recursive detection on logic to prevent runaway oscillations
* Fixed click alignment on single input elements
### 0.2.4
* Brought connections to foreground to make them more obvious in less then ideal layouts
* Resized logic elements and positions I/O better

View File

@ -241,6 +241,7 @@ class Element extends CanvasTools {
Delete() {
// Just to clean up connections
for (let a = 0; a < this.OutputConnections.length;a++) {
this.LogicEngine.RecursionCount = 0;
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,false);
}
}
@ -254,8 +255,12 @@ class Element extends CanvasTools {
// We need to see if an input is being clicked on to be linked to
let foundInput = false;
for (let a = 0; a < this.Inputs.length;a++) {
let centerY = this.Y + Math.round(this.Height / 2);
let totalHeight = this.totalInputs() * ((this.inputCircleRadius*2)+4);
let firstY = (centerY - (totalHeight/2)) + 12;
let mouseDist = length2D(this.X+10,
this.Y+(this.inputCircleRadius + 2)+(((a*(4+(this.inputCircleRadius*2))))-2)+(this.inputCircleRadius/2),
firstY+ (a*24),
this.MousePosition.x,
this.MousePosition.y);
if (mouseDist <= (this.inputCircleRadius)) {
@ -283,6 +288,7 @@ class Element extends CanvasTools {
addConnection(container, element, input) {
let newConnection = new ElementConnection(container,element,input);
this.OutputConnections.push(newConnection);
this.LogicEngine.RecursionCount = 0;
element.setInput(input,this.getOutput());
}
@ -331,10 +337,15 @@ class Element extends CanvasTools {
this.OutputConnections.splice(a,1);
a--;
} else {
let endCenterY = this.OutputConnections[a].Element.Y + Math.round(this.OutputConnections[a].Element.Height / 2);
let endTotalHeight = this.OutputConnections[a].Element.totalInputs() * ((this.OutputConnections[a].Element.inputCircleRadius*2)+4);
let endFirstY = (endCenterY - (endTotalHeight/2)) + 12;
let startX = this.X + this.Width;
let startY = this.Y+(this.Height/2);
let endX = this.OutputConnections[a].Element.X;
let endY = this.OutputConnections[a].Element.Y+(this.OutputConnections[a].Element.inputCircleRadius + 2)+(((this.OutputConnections[a].Input*(4+(this.OutputConnections[a].Element.inputCircleRadius*2))))-2)+(this.OutputConnections[a].Element.inputCircleRadius/2);
//let endY = this.OutputConnections[a].Element.Y+(this.OutputConnections[a].Element.inputCircleRadius + 2)+(((this.OutputConnections[a].Input*(4+(this.OutputConnections[a].Element.inputCircleRadius*2))))-2)+(this.OutputConnections[a].Element.inputCircleRadius/2);
let endY = endFirstY + (this.OutputConnections[a].Input*24);
let startMidX = startX + ((endX - startX)/2);
let startMidY = startY;
let midX = startMidX;
@ -366,11 +377,24 @@ class Element extends CanvasTools {
}
if (Input < this.totalInputs()) {
this.Inputs[Input] = Value;
} else {
return;
}
if (this.getOutput() != oldOutput) {
// The output changed, we need to notify connected elements
for (let a = 0; a < this.OutputConnections.length;a++) {
//console.log(this.Designator + " sending " + this.getOutput() + " to " + this.OutputConnections[a].Element.Designator + " I" + this.OutputConnections[a].Input);
this.LogicEngine.RecursionCount++;
//console.log("Recursion: " + this.LogicEngine.RecursionCount);
if (this.LogicEngine.RecursionCount > 1000) {
if (!this.LogicEngine.RecursionError) {
console.log("RECURSION ERROR");
this.LogicEngine.RecursionError = true;
}
return;
}
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,this.getOutput());
this.LogicEngine.RecursionCount--;
}
}
}
@ -404,6 +428,7 @@ class ClockElement extends Element {
this.Task.Time = this.Period - Math.round(this.Period * this.Duty);
}
for (let a = 0; a < this.OutputConnections.length; a++) {
this.LogicEngine.RecursionCount = 0;
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input, this.getOutput());
}
}
@ -422,9 +447,14 @@ class ClockElement extends Element {
super.setInput(Input, Value);
if (!this.Inputs[0]) {
this.Output = false;
this.Task.LastCall = 0;
this.Task.Enabled = false;
for (let a = 0; a < this.OutputConnections.length;a++) {
this.LogicEngine.RecursionCount = 0;
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,this.getOutput());
}
} else {
this.Task.Enabled = true;
}
}
@ -497,6 +527,7 @@ class InputSwitch extends inputElement {
if ((mousePos.x >= (this.X + 5)) && (mousePos.x <= (this.X + 55)) && (mousePos.y >= (this.Y + 5)) && (mousePos.y <= (this.Y + 55))) {
this.Output = ~this.Output;
for (let a = 0; a < this.OutputConnections.length; a++) {
this.LogicEngine.RecursionCount = 0;
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input, this.getOutput());
}
}
@ -880,7 +911,8 @@ class LogicEngine {
this.ActiveContainer = new elementContainer();
this.ActiveLink = false;
this.Scheduler = new ScheduleEngine();
this.RecursionCount = 0;
this.RecursionError = false;
this.Canvas.setAttribute('tabindex','0');
}
@ -902,6 +934,10 @@ class LogicEngine {
}
DrawLoop() {
if (this.RecursionError) {
this.RecursionError = false;
alert("Recursion Error! Whatever you last did is causing an oscillating loop, please check your connections and try again!");
}
let startLoop = performance.now();
this.Ctx.clearRect(0,0,this.Canvas.width,this.Canvas.height);
if (this.ActiveLink) {

View File

@ -2,7 +2,7 @@
MatCat BrowserLogic Simulator
*/
let Version = "0.2.4";
let Version = "0.2.5";
let spanVersion = document.getElementById("version");
spanVersion.innerText = Version;
// get the canvas and get the engine object going