From 0a38839418811b5cc5a9b1146bf3a4fdc1f77d15 Mon Sep 17 00:00:00 2001 From: MatCat Date: Sun, 21 Feb 2021 01:51:21 -0800 Subject: [PATCH] Update to 0.2.0, dark theme, click linking, and properties --- README.md | 6 + css/main.css | 53 +++++- index.html | 38 +++-- js/logicengine.js | 408 ++++++++++++++++++++++++++++++++++++++-------- js/main.js | 88 +++------- 5 files changed, 450 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index 0bec4d9..d3565bb 100644 --- a/README.md +++ b/README.md @@ -12,5 +12,11 @@ To be decided, but at this moment this code is open source and free to use for n ## Changelog +### 0.2.0 +* Switched to a dark theme +* Added left hand toolbar +* Linking can now be done by clicking on an output then an input +* Added new element: Clock + ### 0.1.0 Initial public release. diff --git a/css/main.css b/css/main.css index 416a37e..b519912 100644 --- a/css/main.css +++ b/css/main.css @@ -10,9 +10,12 @@ /* ========================================================================== Base styles: opinionated defaults ========================================================================== */ +body { + background-color: #454550; +} html { - color: #222; + color: #ddd; font-size: 1em; line-height: 1.4; } @@ -261,3 +264,51 @@ textarea { } } +#left-menu { + width: 200px; + max-width: 200px; + height: 100vh; + display: inline-block; + border: 1px solid black; + margin: 0px; + padding: 0px; +} + +#top-bar { + height: 50px; + overflow: auto; + margin: 0px; + padding: 0px; + background-color: #222; + font-size: 2em; +} + +#PropertiesBox { + display: none; + position: absolute; + right: 20px; + top: 50px; + width: 300px; + height: 200px; + background-color: #444455; + border: 1px solid black; +} + +#PropertiesBoxTitle { + text-align: center; + background-color: #222222; + font-size: 1.5em; +} + +#PropertiesBoxContent { + padding: 5px; +} + +#LogicPlane { + outline: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); /* mobile webkit */ +} + +#propertiesTable { + width: 100%; +} diff --git a/index.html b/index.html index 2a83329..057b4fe 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,6 @@ - @@ -26,20 +25,31 @@ -
- MatCat BrowserLogic 0.1.0 - - - - - - - - - +
+ MatCat BrowserLogic +
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ Properties +
+
+ Content +
- - diff --git a/js/logicengine.js b/js/logicengine.js index e05d257..67aae09 100644 --- a/js/logicengine.js +++ b/js/logicengine.js @@ -13,10 +13,88 @@ function averageArray(arr) { return arr.reduce((a, b) => (a + b)) / arr.length; } +function length2D(x1,y1,x2,y2) { + let xDist = x1 - x2; + let yDist = y1 - y2; + return Math.sqrt(xDist*xDist + yDist * yDist); +} /* Now we can get into the classes */ + +class LogicEngineSettings { + constructor() { + this.ActiveConnectionColor = "#aabbaa"; + this.InactiveConnectionColor = "#bbaaaa"; + this.LinkWidth = "2"; + this.LinkDash = []; + this.LinkingConnectionColor = "#aabbbb"; + this.LinkingWidth = "3"; + this.LinkingDash = [2,2]; + } +} +class Task { + constructor(taskname,taskdescription,tasktype,tasktime,callback,deleteonrun = false) { + // tasktype: 0: interval, 1: fixed time + this.Name = taskname; + this.Description = taskdescription; + this.Type = tasktype; + this.Enabled = true; + this.Time = tasktime; + this.LastCall = Date.now(); + this.CallCount = 0; + this.DeleteOnRun = false; + if (deleteonrun) this.DeleteOnRun = true; + this.Callback = callback; + if (!(tasktype >= 0 && tasktype <= 1)) this.Type = 0; + } + CheckTime() { + let time = this.Time; + if (this.Type == 0) time = this.LastCall + this.Time; + if (this.Enabled && (Date.now() >= time)) { + this.LastCall = Date.now(); + this.CallCount++; + if (this.Type == 1 || this.DeleteOnRun == true) this.Enabled = false; + this.Callback(); + return true; + } + return false; + } +} + +class ScheduleEngine { + constructor() { + this.Tasks = new Array(); + } + + addTask(task) { + this.Tasks.push(task); + } + + deleteTask(task) { + for (let a = 0; a < this.Tasks.length; a++) { + if (this.Tasks[a] == task) { + this.Tasks.splice(a,1); + return true; + } + } + return false; + } + + Tick() { + for (let a = 0; a < this.Tasks.length; a++) { + this.Tasks[a].CheckTime(); + if (!this.Tasks[a].Enabled && this.Tasks[a].DeleteOnRun) { + this.Tasks.splice(a,1); + a--; + } + } + } + + +} + class CanvasTools { constructor() { @@ -68,6 +146,38 @@ class CanvasTools { } +class ElementProperty { + constructor(name,type,callback,defaultValue,currentValue = false,values=false,min=0,max=12) { + /* + Types + --------------------------------------- + bool Boolean Values + int Integer Value + string String Value + list Dropdown box of values + + Callback is an object of: + --------------------------------------- + CBObject Object to call function on + CBFunction The function + + */ + this.Name = name; + this.Type = type; + this.Callback = callback; + this.DefaultValue = defaultValue; + if (!currentValue) currentValue = defaultValue; + this.CurrentValue = currentValue; + this.Values = values; + if (!values) this.Values = new Array(); + this.Minimium = min; + this.Maximium = max; + } + Call(value) { + this.Callback.CBObject[this.Callback.CBFunction](value); + } +} + class ElementConnection { constructor(elementContainer,element,input) { this.Container = elementContainer; @@ -78,12 +188,11 @@ class ElementConnection { class Element extends CanvasTools { - constructor(Inputs) { + constructor(logicengine,Inputs) { super(); this.Name = "Element"; this.Designator = ""; this.Inputs = new Array(Inputs); - this.totalInputs = Inputs; this.Width = 150; this.Height = 100; this.inputCircleRadius = 10; @@ -91,6 +200,40 @@ class Element extends CanvasTools { this.X = 0; this.Y = 0; this.OutputConnections = new Array(); + this.MouseOver = false; + this.MousePosition = {x: 0, y: 0}; + this.Properties = new Array(); + this.LogicEngine = logicengine; + + let inputProperty = new ElementProperty("Inputs","int",{CBObject: this,CBFunction: "ChangeInputs"},2,Inputs); + this.Properties.push(inputProperty); + } + + getProperty(property) { + for (let a = 0; a < this.Properties.length;a++) { + if (this.Properties[a].Name == property) return this.Properties[a]; + } + return false; + } + + removeProperty(property) { + for (let a = 0; a < this.Properties.length;a++) { + if (this.Properties[a].Name == property) { + this.Properties.splice(a,1); + return true; + } + } + return false; + } + + totalInputs() { + return this.Inputs.length; + } + + ChangeInputs(inputs) { + inputs = parseInt(inputs,10); + this.Inputs = new Array(inputs); + this.getProperty("Inputs").CurrentValue = inputs; } Delete() { @@ -99,13 +242,40 @@ class Element extends CanvasTools { this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,false); } } - MouseClick() { - // Function for if mouse is clicked + MouseClick(mousePos) { + + let mouseDistOutput = length2D(this.X+(this.Width-20), + this.Y+(this.Height/2), + this.MousePosition.x, + this.MousePosition.y); + if (this.LogicEngine.ActiveLink) { + // 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 mouseDist = length2D(this.X+20, + this.Y+(this.inputCircleRadius + 2)+(((a*(4+(this.inputCircleRadius*2))))-2)+(this.inputCircleRadius/2), + this.MousePosition.x, + this.MousePosition.y); + if (mouseDist <= (this.inputCircleRadius)) { + this.LogicEngine.Link(a); + foundInput = true; + break; + } + } + + } else { + if (mouseDistOutput <= (this.outputCircleRadius)) { + // Clicked on output, let us start a link + this.LogicEngine.Link(); + } + } } mouseInside(mousePos) { - if (((mousePos.x >= this.X ) && (mousePos.x <= (this.X + this.Width))) & ((mousePos.y >= this.Y ) && (mousePos.y <= (this.Y + this.Height)))) return true; - return false; + this.MouseOver = false; + if (((mousePos.x >= this.X ) && (mousePos.x <= (this.X + this.Width))) & ((mousePos.y >= this.Y ) && (mousePos.y <= (this.Y + this.Height)))) this.MouseOver = true; + this.MousePosition = mousePos; + return this.MouseOver; } addConnection(container, element, input) { @@ -114,19 +284,23 @@ class Element extends CanvasTools { element.setInput(input,this.getOutput()); } - drawInputs(ctx,x,y,borderColor = "#000",circleColorFalse = "#ff0000",circleColorTrue="#00ff00") { + drawInputs(ctx,x,y,borderColor = "#000",circleColorFalse = "#ff0000",circleColorTrue="#00ff00",circleColorHover = "#00ffff") { let old_strokeStyle = ctx.strokeStyle; let old_fillStyle = ctx.fillStyle; - if ((this.totalInputs * ((this.inputCircleRadius*2)+4)) > (this.Height-2)) { - this.inputCircleRadius = ((this.Height-(2 + this.totalInputs * 4)) / this.totalInputs)/2; + if ((this.totalInputs() * ((this.inputCircleRadius*2)+4)) > (this.Height-2)) { + this.inputCircleRadius = ((this.Height-(2 + this.totalInputs() * 4)) / this.totalInputs())/2; + } else { + this.inputCircleRadius = 10; } - for (let a = 0; a < this.totalInputs;a++) { + for (let a = 0; a < this.totalInputs();a++) { + let mouseDist = length2D(x+20,y+(this.inputCircleRadius + 2)+(((a*(4+(this.inputCircleRadius*2))))-2)+(this.inputCircleRadius/2),this.MousePosition.x,this.MousePosition.y); ctx.beginPath(); ctx.arc(x+20,y+(this.inputCircleRadius + 2)+(((a*(4+(this.inputCircleRadius*2))))-2)+(this.inputCircleRadius/2),this.inputCircleRadius,0,2*Math.PI); ctx.strokeStyle = borderColor; ctx.fillStyle = circleColorFalse; if (this.Inputs[a]) ctx.fillStyle = circleColorTrue; + if ((mouseDist <= (this.inputCircleRadius)) && this.LogicEngine.ActiveLink) ctx.fillStyle = circleColorHover; ctx.fill(); ctx.stroke(); } @@ -134,21 +308,23 @@ class Element extends CanvasTools { ctx.fillStyle = old_fillStyle; } - drawOutputs(ctx,x,y,borderColor = "#000",circleColorFalse = "#ff0000",circleColorTrue="#00ff00") { + drawOutputs(ctx,x,y,borderColor = "#000",circleColorFalse = "#ff0000",circleColorTrue="#00ff00",circleColorHover="#00ffff") { let old_strokeStyle = ctx.strokeStyle; let old_fillStyle = ctx.fillStyle; + let mouseDist = length2D(x+(this.Width-20),y+(this.Height/2),this.MousePosition.x,this.MousePosition.y); ctx.beginPath(); ctx.arc(x+(this.Width-20),y+(this.Height/2),this.outputCircleRadius,0,2*Math.PI); ctx.strokeStyle = borderColor; ctx.fillStyle = circleColorFalse; if (this.getOutput()) ctx.fillStyle = circleColorTrue; + if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.fillStyle = circleColorHover; ctx.fill(); ctx.stroke(); ctx.strokeStyle = old_strokeStyle; ctx.fillStyle = old_fillStyle; } - drawConnections(ctx) { + drawConnections(ctx,settings) { ctx.save(); for (let a = 0; a < this.OutputConnections.length;a++) { if (!this.OutputConnections[a].Container.HasElement(this.OutputConnections[a].Element)) { @@ -157,9 +333,12 @@ class Element extends CanvasTools { a--; } else { ctx.beginPath(); + ctx.lineWidth = settings.LinkWidth; + ctx.setLineDash(settings.LinkDash); ctx.moveTo((this.X + this.Width) - 20, this.Y + (this.Height / 2)); ctx.lineTo(this.OutputConnections[a].Element.X + 20, this.OutputConnections[a].Element.Y + 20); - ctx.strokeStyle = "#555"; + ctx.strokeStyle = settings.ActiveConnectionColor; + if (!this.getOutput()) ctx.strokeStyle = settings.InactiveConnectionColor; ctx.stroke(); } } @@ -173,7 +352,7 @@ class Element extends CanvasTools { } else { Value = false; } - if (Input < this.totalInputs) { + if (Input < this.totalInputs()) { this.Inputs[Input] = Value; } if (this.getOutput() != oldOutput) { @@ -203,12 +382,78 @@ class Element extends CanvasTools { } -class inputElement extends Element { - constructor() { - super(0); +class ClockElement extends Element { + ClockTick() { + if (this.Inputs[0]) { + this.Output = ~this.Output; + if (this.Output) { + this.Task.Time = Math.round(this.Period * this.Duty); + } else { + this.Task.Time = this.Period - Math.round(this.Period * this.Duty); + } + for (let a = 0; a < this.OutputConnections.length; a++) { + this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input, this.getOutput()); + } + } + } + + getOutput() { + return this.Output; + } + + setInput(Input, Value) { + super.setInput(Input, Value); + if (!this.Inputs[0]) { + this.Output = false; + for (let a = 0; a < this.OutputConnections.length;a++) { + this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,this.getOutput()); + } + } + } + + constructor(logicengine) { + super(logicengine,1); + this.removeProperty("Inputs"); + this.Name = "Clock"; + this.Period = 1000; + this.Duty = 0.5; this.Output = false; this.Width = 100; + this.Task = new Task("ClockTask","CLOCK",0,Math.round(this.Period * this.Duty),this.ClockTick.bind(this)); + this.setInput(0,true); + this.removeProperty("Inputs"); + let periodProperty = new ElementProperty("Period","int",{CBObject: this,CBFunction: "setPeriod"},1000,false,false,4,999999); + let dutyProperty = new ElementProperty("Duty","int",{CBObject: this,CBFunction: "setDuty"},50,false,false,0,100); + this.Properties.push(periodProperty); + this.Properties.push(dutyProperty); + } + + setPeriod(period) { + this.Period = period; + this.Task.LastCall = 0; + this.getProperty("Period").CurrentValue = period; + } + + setDuty(duty) { + this.Duty = duty/100; + this.Task.LastCall = 0; + this.getProperty("Duty").CurrentValue = duty; + } + + drawElement(x, y, ctx) { + this.drawBorderBox(ctx, x,y,this.Width,this.Height); + this.drawTextCentered(ctx,x,y,this.Width,(this.Height+(this.Height/2)),this.Period + "ms " + (this.Duty * 100) + "%","10px Console"); + this.drawInputs(ctx,x,y); + this.drawOutputs(ctx,x,y); + } +} + +class inputElement extends Element { + constructor(logicengine) { + super(logicengine,0); this.Name = "InputElement"; + this.Output = false; + this.Width = 100; } getOutput() { @@ -222,16 +467,19 @@ class inputElement extends Element { } } -class inputButton extends inputElement { - constructor() { - super(); - this.Name = "Button"; +class InputSwitch extends inputElement { + constructor(logicengine) { + super(logicengine); + this.Name = "Switch"; } - MouseClick() { - this.Output = ~this.Output; - for (let a = 0; a < this.OutputConnections.length;a++) { - this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,this.getOutput()); + MouseClick(mousePos) { + super.MouseClick(mousePos); + if ((mousePos.x >= (this.X + 10)) && (mousePos.x <= (this.X + 60)) && (mousePos.y >= (this.Y + 25)) && (mousePos.y <= (this.Y + 75))) { + this.Output = ~this.Output; + for (let a = 0; a < this.OutputConnections.length; a++) { + this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input, this.getOutput()); + } } } @@ -243,14 +491,14 @@ class inputButton extends inputElement { } class LogicAND extends Element { - constructor(Inputs) { - super(Inputs); + constructor(logicengine,Inputs) { + super(logicengine,Inputs); this.Name = "AND"; } getOutput() { let ANDResult = true; - for (let a = 0; a < this.totalInputs;a++) { + for (let a = 0; a < this.totalInputs();a++) { if (!this.Inputs[a]) ANDResult = false; } return ANDResult; @@ -264,8 +512,8 @@ class LogicAND extends Element { } class LogicNAND extends LogicAND { - constructor(Inputs) { - super(Inputs); + constructor(logicengine,Inputs) { + super(logicengine,Inputs); this.Name = "NAND"; } getOutput() { @@ -284,14 +532,14 @@ class LogicNAND extends LogicAND { } class LogicOR extends Element { - constructor(Inputs) { - super(Inputs); + constructor(logicengine,Inputs) { + super(logicengine,Inputs); this.Name = "OR"; } getOutput() { let ORResult = false; - for (let a = 0; a < this.totalInputs;a++) { + for (let a = 0; a < this.totalInputs();a++) { if (this.Inputs[a]) ORResult = true; } return ORResult; @@ -308,8 +556,8 @@ class LogicOR extends Element { } class LogicNOR extends LogicOR { - constructor(Inputs) { - super(Inputs); + constructor(logicengine,Inputs) { + super(logicengine,Inputs); this.Name = "NOR"; } getOutput() { @@ -328,8 +576,8 @@ class LogicNOR extends LogicOR { } class LogicXOR extends Element { - constructor() { - super(2); // Only 2 inputs on XOR + constructor(logicengine) { + super(logicengine,2); // Only 2 inputs on XOR this.Name = "XOR"; } @@ -351,8 +599,8 @@ class LogicXOR extends Element { } class LogicXNOR extends Element { - constructor() { - super(2); // Only 2 inputs on XOR + constructor(logicengine) { + super(logicengine,2); // Only 2 inputs on XOR this.Name = "XNOR"; } @@ -423,31 +671,51 @@ class elementContainer { return false; } - DrawAll(ctx) { - for (let a = 0;a < this.Elements.length;a++) { + DrawAll(ctx,settings) { + for (let a = 0; a < this.Elements.length; a++) { // Not ideal to loop twice but we need the connections drawn first - this.Elements[a].drawConnections(ctx); + this.Elements[a].drawConnections(ctx, settings); } - for (let a = 0;a < this.Elements.length;a++) { - if (this.Elements[a] == this.Selected) this.Elements[a].drawBorderBox(ctx,this.Elements[a].X - 2,this.Elements[a].Y - 2,this.Elements[a].Width+4,this.Elements[a].Height+4,2,"#5555FF","#5555ff"); - this.Elements[a].drawElement(this.Elements[a].X,this.Elements[a].Y,ctx); + for (let a = 0; a < this.Elements.length; a++) { + if (this.Elements[a] == this.Selected) this.Elements[a].drawBorderBox(ctx, this.Elements[a].X - 2, this.Elements[a].Y - 2, this.Elements[a].Width + 4, this.Elements[a].Height + 4, 2, "#5555FF", "#5555ff"); + this.Elements[a].drawElement(this.Elements[a].X, this.Elements[a].Y, ctx); let old_font = ctx.font; let old_fillStyle = ctx.fillStyle; ctx.font = "10px Console"; let x = this.Elements[a].X; - let y = this.Elements[a].Y + (this.Elements[a].Height-12); + let y = this.Elements[a].Y + (this.Elements[a].Height - 12); let x2 = this.Elements[a].Width; let y2 = 10; - this.Elements[a].drawTextCentered(ctx,x,y,x2,y2,this.Elements[a].Designator,ctx.font,"#000"); + this.Elements[a].drawTextCentered(ctx, x, y, x2, y2, this.Elements[a].Designator, ctx.font, "#000"); ctx.font = old_font; ctx.fillStyle = old_fillStyle; } + if (!this.Selected) { + let PropertiesBox = document.getElementById("PropertiesBox"); + if (PropertiesBox.style.display != "none") PropertiesBox.style.display = "none"; + } } Select(element) { this.Selected = element; + let PropertiesBox = document.getElementById("PropertiesBox"); + let PropertiesBoxTitle = document.getElementById("PropertiesBoxTitle"); + let PropertiesBoxContent = document.getElementById("PropertiesBoxContent"); + PropertiesBoxTitle.innerText = this.Selected.Designator + " Properties"; + let contentString = ""; + for (let a = 0; a < this.Selected.Properties.length;a++) { + contentString += ""; + } + PropertiesBoxContent.innerHTML = contentString; + PropertiesBox.style.display = "block"; } checkMouseBounds(mousePos) { @@ -463,11 +731,19 @@ class elementContainer { class LogicEngine { Resize(evt) { - this.Canvas.width = window.innerWidth; + let leftmenu = document.getElementById("left-menu"); + leftmenu.style.height = (window.innerHeight - 52) + "px"; + this.Canvas.width = window.innerWidth - 205; this.Canvas.height = window.innerHeight - 50; this.Mouse = false; } + PropertyChange(property) { + if (!this.ActiveContainer.Selected.getProperty(property)) return false; + let propElement = document.getElementById("prop_" + property); + this.ActiveContainer.Selected.getProperty(property).Call(propElement.value); + } + Mouse_Down(evt) { let mousePos = getMousePos(this.Canvas, evt); this.MouseDown = true; @@ -480,29 +756,28 @@ class LogicEngine { this.MovingElementStartY = element.Y; this.MovingElementMouseStartX = mousePos.x; this.MovingElementMouseStartY = mousePos.y; + } else { + this.ActiveLink = false; } } Mouse_Up(evt) { + let mousePos = getMousePos(this.Canvas, evt); this.MouseDown = false; if (this.MovingElement && (this.MovingElement.X == this.MovingElementStartX) && (this.MovingElement.Y == this.MovingElementStartY)) { if ((performance.now() - this.MouseDownTime) < 3000) { // Presume this was a click this.ActiveContainer.Select(this.MovingElement); - if (this.ActiveLink) { - this.Link(); - } else { - this.MovingElement.MouseClick(); - } + this.MovingElement.MouseClick(mousePos); } //console.log("Mouse Up"); } if (!this.MovingElement) this.ActiveContainer.Selected = false; - this.ActiveLink = false; this.MovingElement = false; } Mouse_Move(evt) { + this.Canvas.focus(); let mousePos = getMousePos(this.Canvas, evt); this.Mouse = mousePos; if(this.MouseDown) { @@ -518,6 +793,8 @@ class LogicEngine { this.MovingElement.Y = (this.MovingElementMouseStartY + yOffset) - diffyOffset; } } + } else { + this.ActiveContainer.checkMouseBounds(mousePos); } } @@ -541,6 +818,7 @@ class LogicEngine { this.Canvas = canvas; this.Ctx = canvas.getContext("2d"); + this.Settings = new LogicEngineSettings; this.FPSCounter = 0; this.FPS = 0; this.PotentialFPS = 0; @@ -557,18 +835,15 @@ class LogicEngine { this.MovingElementMouseStartY = 0; this.ActiveContainer = new elementContainer(); this.ActiveLink = false; + this.Scheduler = new ScheduleEngine(); this.Canvas.setAttribute('tabindex','0'); + } - Link() { + Link(input = 0) { if (this.ActiveLink) { if (this.ActiveContainer.Selected && (this.ActiveContainer.Selected != this.ActiveLink)) { - - let input = parseInt(prompt("Please enter the input number (0 - x)")); - while (input == NaN) { - input = parseInt(prompt("Please enter the input number (0 - x)")); - } this.ActiveLink.addConnection(this.ActiveContainer,this.ActiveContainer.Selected,input); this.ActiveLink = false; } else { @@ -582,26 +857,25 @@ class LogicEngine { } - DrawLoop() { let startLoop = performance.now(); - this.Canvas.focus(); this.Ctx.clearRect(0,0,this.Canvas.width,this.Canvas.height); if (this.ActiveLink) { this.Ctx.save(); - this.Ctx.strokeStyle = "#5555AA"; - this.Ctx.lineWidth = 5; + this.Ctx.strokeStyle = this.Settings.LinkingConnectionColor; + this.Ctx.lineWidth = this.Settings.LinkingWidth; + this.Ctx.setLineDash(this.Settings.LinkingDash); this.Ctx.beginPath(); this.Ctx.moveTo(this.ActiveLink.X + (this.ActiveLink.Width/2), this.ActiveLink.Y + (this.ActiveLink.Height/2)); this.Ctx.lineTo(this.Mouse.x, this.Mouse.y); this.Ctx.stroke(); this.Ctx.restore(); } - this.ActiveContainer.DrawAll(this.Ctx); + this.ActiveContainer.DrawAll(this.Ctx,this.Settings); let ct = new CanvasTools(); let FPSOffset = this.Canvas.width - 150; - ct.drawText(this.Ctx,FPSOffset,650,"FPS: " + this.FPS,"12px console", "#005500"); - ct.drawText(this.Ctx,FPSOffset,670,"Potential FPS: " + this.PotentialFPS,"12px console", "#005500"); + ct.drawText(this.Ctx,FPSOffset,650,"FPS: " + this.FPS,"12px console", "#00ff00"); + ct.drawText(this.Ctx,FPSOffset,670,"Potential FPS: " + this.PotentialFPS,"12px console", "#00ff00"); let timeCheck = performance.now(); this.FPSCounter++; diff --git a/js/main.js b/js/main.js index 24a721e..32b801d 100644 --- a/js/main.js +++ b/js/main.js @@ -2,10 +2,17 @@ MatCat BrowserLogic Simulator */ +let Version = "0.2.0"; +let spanVersion = document.getElementById("version"); +spanVersion.innerText = Version; // get the canvas and get the engine object going let lCanvasElement = document.getElementById("LogicPlane"); let logicEngine = new LogicEngine(lCanvasElement); +// Get the game Tick going, this will be 4ms for now which is the fastest that is supported +// by the HTML5 spec! +setInterval(logicEngine.Scheduler.Tick.bind(logicEngine.Scheduler), 4); + // Sadly this doesn't work well inside of the class so we will do it here real fast window.addEventListener('resize', function(evt) { logicEngine.Resize(evt); @@ -31,11 +38,6 @@ lCanvasElement.addEventListener('mousemove', function(evt) { logicEngine.StartEngine(); // Setup interface buttons -let btn_Link = document.getElementById("btn_Link"); -btn_Link.addEventListener('click', function(evt) { - logicEngine.Link(); - }, false); - let btn_Delete = document.getElementById("btn_Delete"); btn_Delete.addEventListener('click', function(evt) { logicEngine.Key_Press({key: "Delete"}); @@ -43,7 +45,7 @@ btn_Delete.addEventListener('click', function(evt) { let btn_AddAND = document.getElementById("btn_AddAND"); btn_AddAND.addEventListener('click', function(evt) { - let newAND = new LogicAND(2); + let newAND = new LogicAND(logicEngine,2); newAND.X = 20; newAND.Y = 20; logicEngine.ActiveContainer.AddElement(newAND); @@ -51,7 +53,7 @@ btn_AddAND.addEventListener('click', function(evt) { let btn_AddNAND = document.getElementById("btn_AddNAND"); btn_AddNAND.addEventListener('click', function(evt) { - let newNAND = new LogicNAND(2); + let newNAND = new LogicNAND(logicEngine,2); newNAND.X = 20; newNAND.Y = 20; logicEngine.ActiveContainer.AddElement(newNAND); @@ -59,7 +61,7 @@ btn_AddNAND.addEventListener('click', function(evt) { let btn_AddOR = document.getElementById("btn_AddOR"); btn_AddOR.addEventListener('click', function(evt) { - let newOR = new LogicOR(2); + let newOR = new LogicOR(logicEngine,2); newOR.X = 20; newOR.Y = 20; logicEngine.ActiveContainer.AddElement(newOR); @@ -67,7 +69,7 @@ btn_AddOR.addEventListener('click', function(evt) { let btn_AddNOR = document.getElementById("btn_AddNOR"); btn_AddNOR.addEventListener('click', function(evt) { - let newNOR = new LogicNOR(2); + let newNOR = new LogicNOR(logicEngine,2); newNOR.X = 20; newNOR.Y = 20; logicEngine.ActiveContainer.AddElement(newNOR); @@ -75,7 +77,7 @@ btn_AddNOR.addEventListener('click', function(evt) { let btn_AddXOR = document.getElementById("btn_AddXOR"); btn_AddXOR.addEventListener('click', function(evt) { - let newXOR = new LogicXOR(); + let newXOR = new LogicXOR(logicEngine); newXOR.X = 20; newXOR.Y = 20; logicEngine.ActiveContainer.AddElement(newXOR); @@ -83,62 +85,26 @@ btn_AddXOR.addEventListener('click', function(evt) { let btn_AddXNOR = document.getElementById("btn_AddXNOR"); btn_AddXNOR.addEventListener('click', function(evt) { - let newXNOR = new LogicXNOR(); + let newXNOR = new LogicXNOR(logicEngine); newXNOR.X = 20; newXNOR.Y = 20; logicEngine.ActiveContainer.AddElement(newXNOR); }, false); -let btn_AddBTN = document.getElementById("btn_AddBTN"); -btn_AddBTN.addEventListener('click', function(evt) { - let newBTN = new inputButton(); - newBTN.X = 20; - newBTN.Y = 20; - logicEngine.ActiveContainer.AddElement(newBTN); +let btn_AddSWITCH = document.getElementById("btn_AddSWITCH"); +btn_AddSWITCH.addEventListener('click', function(evt) { + let newSWITCH = new InputSwitch(logicEngine); + newSWITCH.X = 20; + newSWITCH.Y = 20; + logicEngine.ActiveContainer.AddElement(newSWITCH); }, false); +let btn_AddCLK = document.getElementById("btn_AddCLK"); +btn_AddCLK.addEventListener('click', function(evt) { + let newCLK = new ClockElement(logicEngine); + newCLK.X = 20; + newCLK.Y = 20; + logicEngine.ActiveContainer.AddElement(newCLK); + logicEngine.Scheduler.addTask(newCLK.Task); +}, false); -/* -let AND1 = new LogicAND(2); -AND1.X = 430; -AND1.Y = 70; -logicEngine.ActiveContainer.AddElement(AND1); -let OR1 = new LogicOR(6); -OR1.X = 220; -OR1.Y = 20; -OR1.addConnection(logicEngine.ActiveContainer,AND1,0); -logicEngine.ActiveContainer.AddElement(OR1); -let NAND1 = new LogicNAND(2); -NAND1.X = 220; -NAND1.Y = 140; -NAND1.addConnection(logicEngine.ActiveContainer,AND1,1); -logicEngine.ActiveContainer.AddElement(NAND1); -let AND2 = new LogicAND(2); -AND2.X = 630; -AND2.Y = 120; -AND1.addConnection(logicEngine.ActiveContainer,AND2,0); -logicEngine.ActiveContainer.AddElement(AND2); -let NOR1 = new LogicNOR(2); -NOR1.X = 430; -NOR1.Y = 250; -NOR1.addConnection(logicEngine.ActiveContainer,AND2,1); -logicEngine.ActiveContainer.AddElement(NOR1); - -let Button1 = new inputButton(); -Button1.X = 20; -Button1.Y = 20; -Button1.addConnection(logicEngine.ActiveContainer,OR1,1); -logicEngine.ActiveContainer.AddElement(Button1); - -let Button2 = new inputButton(); -Button2.X = 20; -Button2.Y = 130; -Button2.addConnection(logicEngine.ActiveContainer,NAND1,0); -logicEngine.ActiveContainer.AddElement(Button2); - -let Button3 = new inputButton(); -Button3.X = 20; -Button3.Y = 240; -Button3.addConnection(logicEngine.ActiveContainer,NAND1,1); -logicEngine.ActiveContainer.AddElement(Button3); -*/
" + this.Selected.Properties[a].Name + ""; + switch (this.Selected.Properties[a].Type) { + case "int": + contentString += ""; + break; + } + contentString += "