253 lines
8.5 KiB
JavaScript
253 lines
8.5 KiB
JavaScript
class LogicEngineSettings {
|
|
constructor() {
|
|
this.ActiveConnectionColor = "#aabbaa";
|
|
this.InactiveConnectionColor = "#bbaaaa";
|
|
this.LinkWidth = "2";
|
|
this.LinkDash = [];
|
|
this.LinkingConnectionColor = "#aabbbb";
|
|
this.LinkingWidth = "3";
|
|
this.LinkingDash = [2,2];
|
|
this.ShadowColor = "#222";
|
|
this.InputCircleSize = 10;
|
|
this.OutputCircleSize = 10;
|
|
this.GridSize = 20;
|
|
}
|
|
}
|
|
|
|
class LogicEngine {
|
|
Resize(evt) {
|
|
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;
|
|
let gridPlane = document.getElementById("GridPlane");
|
|
gridPlane.width = this.Canvas.width;
|
|
gridPlane.height = this.Canvas.height;
|
|
let Ctx = gridPlane.getContext("2d");
|
|
Ctx.save();
|
|
let gridWidth = this.Settings.GridSize;
|
|
for (let x = gridWidth;x < (this.Canvas.width); x+= gridWidth) {
|
|
Ctx.beginPath();
|
|
Ctx.moveTo(x,0);
|
|
Ctx.lineTo(x,this.Canvas.height);
|
|
Ctx.strokeStyle = "#777";
|
|
Ctx.lineWidth = "1";
|
|
Ctx.stroke();
|
|
}
|
|
for (let y = gridWidth;y < (this.Canvas.height); y+= gridWidth) {
|
|
Ctx.beginPath();
|
|
Ctx.moveTo(0,y);
|
|
Ctx.lineTo(this.Canvas.width,y);
|
|
Ctx.lineWidth = "1";
|
|
Ctx.strokeStyle = "#777";
|
|
Ctx.stroke();
|
|
}
|
|
Ctx.restore();
|
|
|
|
}
|
|
|
|
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.MouseDownTime = performance.now();
|
|
let element = this.ActiveContainer.checkMouseBounds(mousePos);
|
|
if (element) {
|
|
this.MouseDown = true;
|
|
this.ActiveContainer.Select(element);
|
|
this.MovingElement = element;
|
|
this.MovingElementStartX = element.X;
|
|
this.MovingElementStartY = element.Y;
|
|
this.MovingElementMouseStartX = mousePos.x;
|
|
this.MovingElementMouseStartY = mousePos.y;
|
|
element.MouseDown(mousePos);
|
|
} else {
|
|
this.ActiveLink = false;
|
|
}
|
|
}
|
|
|
|
Mouse_Up(evt) {
|
|
let mousePos = getMousePos(this.Canvas, evt);
|
|
if (this.MovingElement) this.MovingElement.MouseUp(mousePos);
|
|
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.MovingElement.MouseClick(mousePos);
|
|
}
|
|
//console.log("Mouse Up");
|
|
}
|
|
if (!this.MovingElement) this.ActiveContainer.Selected = false;
|
|
this.MovingElement = false;
|
|
this.MouseDown = false;
|
|
}
|
|
|
|
Mouse_Move(evt) {
|
|
//this.Canvas.focus();
|
|
let mousePos = getMousePos(this.Canvas, evt);
|
|
this.Mouse = mousePos;
|
|
if(this.MouseDown) {
|
|
//console.log('Mouse at position: ' + mousePos.x + ',' + mousePos.y);
|
|
if (this.MovingElement) {
|
|
if ((performance.now() - this.MouseDownTime) > 100) {
|
|
let xOffset = mousePos.x - this.MovingElementMouseStartX;
|
|
let yOffset = mousePos.y - this.MovingElementMouseStartY;
|
|
let diffxOffset = this.MovingElementMouseStartX - this.MovingElementStartX;
|
|
let diffyOffset = this.MovingElementMouseStartY - this.MovingElementStartY;
|
|
let actualPosX = (this.MovingElementMouseStartX + xOffset) - diffxOffset;
|
|
let actualPosY = (this.MovingElementMouseStartY + yOffset) - diffyOffset;
|
|
if (!this.ControlPressed) actualPosX = Math.round(actualPosX/this.Settings.GridSize)*this.Settings.GridSize;
|
|
if (!this.ControlPressed) actualPosY = Math.round(actualPosY/this.Settings.GridSize)*this.Settings.GridSize;
|
|
this.MovingElement.X = actualPosX;
|
|
this.MovingElement.Y = actualPosY;
|
|
}
|
|
}
|
|
} else {
|
|
this.ActiveContainer.checkMouseBounds(mousePos);
|
|
}
|
|
}
|
|
|
|
|
|
Key_Up(evt) {
|
|
if (!evt.ctrlKey) {
|
|
this.ControlPressed = false;
|
|
}
|
|
}
|
|
|
|
Key_Press(evt) {
|
|
if (evt.ctrlKey) {
|
|
this.ControlPressed = true;
|
|
}
|
|
|
|
if (evt.key == "Escape") {
|
|
if (this.MovingElement && this.MouseDown) {
|
|
this.MovingElement.X = this.MovingElementStartX;
|
|
this.MovingElement.Y = this.MovingElementStartY;
|
|
this.MovingElement = false;
|
|
}
|
|
}
|
|
if (evt.key == "Delete") {
|
|
if (this.ActiveContainer.Selected) {
|
|
this.ActiveContainer.DeleteElement(this.ActiveContainer.Selected);
|
|
this.ActiveContainer.Selected = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
constructor(canvas) {
|
|
this.Canvas = canvas;
|
|
this.Ctx = canvas.getContext("2d");
|
|
|
|
this.Settings = new LogicEngineSettings;
|
|
this.FPSCounter = 0;
|
|
this.FPS = 0;
|
|
this.PotentialFPS = 0;
|
|
this.PotentialFPSAVGs = new Array(20);
|
|
this.PotentialFPSAVGLoc = 0;
|
|
this.LastFPSCheck = performance.now();
|
|
this.MouseDown = false;
|
|
this.MouseDownTime = 0;
|
|
this.MovingElementContainer = false;
|
|
this.MovingElement = false;
|
|
this.MovingElementStartX = 0;
|
|
this.MovingElementStartY = 0;
|
|
this.MovingElementMouseStartX = 0;
|
|
this.MovingElementMouseStartY = 0;
|
|
this.ActiveContainer = new elementContainer();
|
|
this.ActiveLink = false;
|
|
this.Scheduler = new ScheduleEngine();
|
|
this.RecursionCount = 0;
|
|
this.RecursionError = false;
|
|
this.Canvas.setAttribute('tabindex','0');
|
|
this.ControlPressed = false;
|
|
|
|
}
|
|
|
|
Link(input = 0) {
|
|
if (this.ActiveLink) {
|
|
if (this.ActiveContainer.Selected && (this.ActiveContainer.Selected != this.ActiveLink)) {
|
|
this.ActiveLink.addConnection(this.ActiveContainer,this.ActiveContainer.Selected,input,this.ActiveLink.OutputLink.Output);
|
|
this.ActiveLink = false;
|
|
} else {
|
|
this.ActiveLink = false;
|
|
}
|
|
} else {
|
|
if (this.ActiveContainer.Selected) {
|
|
this.ActiveLink = this.ActiveContainer.Selected;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
this.ActiveContainer.DrawAll(this.Ctx,this.Settings);
|
|
let btn_CreateIC = document.getElementById("btn_CreateIC");
|
|
btn_CreateIC.disabled = true;
|
|
if (this.ActiveContainer.ICOutputs > 0) btn_CreateIC.disabled = false;
|
|
if (this.ActiveLink) {
|
|
let startX = this.ActiveLink.LinkOutLocation().x;
|
|
let startY = this.ActiveLink.LinkOutLocation().y;
|
|
let endX = this.Mouse.x;
|
|
let endY = this.Mouse.y;
|
|
let startMidX = startX + ((endX - startX)/2);
|
|
let startMidY = startY;
|
|
let midX = startMidX;
|
|
let midY = startY + ((endY - startY)/2);
|
|
let endMidX = startMidX;
|
|
let endMidY = endY;
|
|
|
|
this.Ctx.save();
|
|
this.Ctx.strokeStyle = this.Settings.LinkingConnectionColor;
|
|
this.Ctx.lineWidth = this.Settings.LinkingWidth;
|
|
this.Ctx.setLineDash(this.Settings.LinkingDash);
|
|
this.Ctx.beginPath();
|
|
this.Ctx.moveTo(startX, startY);
|
|
this.Ctx.quadraticCurveTo(startMidX,startMidY,midX,midY);
|
|
this.Ctx.quadraticCurveTo(endMidX,endMidY,endX,endY);
|
|
this.Ctx.stroke();
|
|
this.Ctx.restore();
|
|
}
|
|
let ct = new CanvasTools();
|
|
let FPSOffset = this.Canvas.width - 150;
|
|
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++;
|
|
|
|
if (!(Math.round(timeCheck - this.LastFPSCheck) % 50)) {
|
|
let frameTimeUS = (performance.now() - startLoop) * 1000;
|
|
let potentialFPS = 1000000 / frameTimeUS;
|
|
this.PotentialFPSAVGs[this.PotentialFPSAVGLoc] = Math.round(potentialFPS);
|
|
this.PotentialFPSAVGLoc++;
|
|
if (this.PotentialFPSAVGLoc == this.PotentialFPSAVGs.length) this.PotentialFPSAVGLoc = 0;
|
|
this.PotentialFPS = averageArray(this.PotentialFPSAVGs);
|
|
}
|
|
|
|
if ((timeCheck - this.LastFPSCheck) >= 1000) {
|
|
this.FPS = this.FPSCounter;
|
|
this.FPSCounter = 0;
|
|
this.LastFPSCheck = performance.now();
|
|
//console.log("Frame Time: " + frameTimeUS + "uS" + ", Potential FPS: " + potentialFPS);
|
|
//console.log("FPS: " + FPS);
|
|
}
|
|
|
|
requestAnimationFrame(this.DrawLoop.bind(this));
|
|
}
|
|
|
|
StartEngine() {
|
|
this.Resize("");
|
|
this.DrawLoop();
|
|
}
|
|
}
|