function addElement(RestoreData = null,refClass,props) { let newElement = new refClass(RestoreData,logicEngine,...props); if (!RestoreData) { let x = Math.round(logicEngine.Canvas.width / 2); let y = Math.round(logicEngine.Canvas.height / 2); x = logicEngine.Settings.GridSize * Math.round(x/logicEngine.Settings.GridSize); y = logicEngine.Settings.GridSize * Math.round(y/logicEngine.Settings.GridSize); let width = newElement.Width; let height = newElement.Height; let noclearspot = true; while (noclearspot) { if (!logicEngine.ActiveContainer.checkOverlayBounds(x, y, width, height)) { noclearspot = false; } else { x += Math.floor(Math.random() * (width - (width - (width * 2)))) + (width - (width * 2)); y += Math.floor(Math.random() * (height - (height - (height * 2)))) + (height - (height * 2)); if (x < 0) x = 0; if (y < 0) y = 0; if (x + width > logicEngine.Canvas.width) x = logicEngine.Canvas.width - width; if (y + height > logicEngine.Canvas.height) y = logicEngine.Canvas.height - height; x = logicEngine.Settings.GridSize * Math.round(x/logicEngine.Settings.GridSize); y = logicEngine.Settings.GridSize * Math.round(y/logicEngine.Settings.GridSize); } } newElement.X = x; newElement.Y = y; } logicEngine.ActiveContainer.AddElement(newElement); logicEngine.ActiveContainer.Select(newElement); return newElement; } function createIC(container,name,description) { let newContainer = false; if (container instanceof elementContainer) newContainer = loadContainer(JSON.parse(JSON.stringify(container))); if (typeof container == 'string' || container instanceof String) newContainer = loadContainer(JSON.parse(container)); if (!newContainer) return false; let ICSettings = { Name: name.replace('^[a-zA-Z0-9_]+$',''), Description: description, Container: JSON.stringify(container), }; let outputCount = 0; for (let a = 0; a < newContainer.Elements.length; a++) { if (newContainer.Elements[a] instanceof ICOutput) { outputCount++; } } if (outputCount == 0) return false; let ElementCatalog_IC = new ElementCatalog_Element(ICSettings.Name,ICSettings.Description,"≡█≡",ICElement,[ICSettings]); ElementReferenceTable.push(ElementCatalog_IC); ElementCategory_ICs.addElement(ElementCatalog_IC); BuildToolbox(); return ElementCatalog_IC; } function setCookie(cname, cvalue, exdays) { let d = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000)); let expires = "expires="+ d.toUTCString(); document.cookie = cname + '="' + cvalue + '";' + expires; localStorage.setItem(cname,cvalue); } function getCookie(cname) { let name = cname + "="; let decodedCookie = decodeURIComponent(document.cookie); let ca = decodedCookie.split(';'); for(var i = 0; i (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); } function BuildToolbox() { let toolbox = document.getElementById("inner-left-menu"); toolbox.innerHTML = ""; for (let a = 0; a < elementCatalog.Categories.length; a++) { let div_CategoryHeader = document.createElement("div"); div_CategoryHeader.id = "TB_CATH_" + elementCatalog.Categories[a].Name; div_CategoryHeader.className ="TOOLBOX_CATEGORY_HEADER"; div_CategoryHeader.innerHTML = '

' + elementCatalog.Categories[a].Name + '

'; let div_Category = document.createElement("div"); div_Category.id = "TB_CATB_" + elementCatalog.Categories[a].Name; div_Category.className = "TOOLBOX_CATEGORY_BODY"; div_Category.innerHTML = ""; for (let b = 0; b < elementCatalog.Categories[a].Elements.length; b++) { let btn_Element = document.createElement("input"); btn_Element.type = "button"; btn_Element.id = "btn_" + elementCatalog.Categories[a].Elements[b].Name; btn_Element.title = elementCatalog.Categories[a].Elements[b].Description; btn_Element.value = elementCatalog.Categories[a].Elements[b].Icon + " " + elementCatalog.Categories[a].Elements[b].Name; btn_Element.style.width = "100px"; btn_Element.style.textAlign = "left"; btn_Element.addEventListener('click', function(evt) { addElement(null,elementCatalog.Categories[a].Elements[b].Class,elementCatalog.Categories[a].Elements[b].Args); }, false); div_Category.append(btn_Element); // div_Category.append(document.createElement("br")); } toolbox.append(div_CategoryHeader); toolbox.append(div_Category); } } function getElementInfo(element) { for (let a = 0; a < ElementReferenceTable.length; a++) { if (ElementReferenceTable[a].Name == element) return ElementReferenceTable[a]; } return false; } function isVersionNewer(version1,version2,orEqual = true) { let v1 = version1.split("."); let v2 = version1.split("."); if (v1.length != 3) return false; if (v2.length != 3) return false; for (let a = 0; a < 3; a++) { v1[a] = parseInt(v1[a]); v2[a] = parseInt(v2[a]); } if (v1[0] > v2[0]) return true; if (v1[0] == v2[0] && v1[1] > v2[1]) return true; if (v1[0] == v2[0] && v1[1] == v2[1] && v1[2] > v2[2]) return true; if ((v1[0] == v2[0] && v1[1] == v2[1]) && (orEqual && v1[2] == v2[2])) return true; return false; } function createSaveState(container = false) { let saveState = { Name: "LogicDesign", Version: Version, Timestamp: Date.now(), Elements: new Array() }; if (container.Elements.length > 0) saveState.Elements = container.Elements; return saveState; } function download(filename, savestate) { let text = JSON.stringify(savestate); let element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); } function loadContainer(Elements) { let newContainer = new elementContainer(); let elementConnections = new Array(); let icelementConnections = new Array(); for (let a = 0; a < Elements.length; a++) { if (Elements[a].IsIC) { let classRef = getElementInfo(Elements[a].Name).Class; if (!classRef) { // We need to add this IC to the toolbox let newIC = createIC(JSON.stringify(Elements[a].ICBlueprint),Elements[a].Name,Elements[a].Description); console.log("NewIC:" + newIC); if (!newIC) return false; } } let classRef = getElementInfo(Elements[a].Name).Class; let newElement = new classRef(Elements[a],logicEngine,getElementInfo(Elements[a].Name).Args[0]); newContainer.AddElement(newElement); newElement.Designator = Elements[a].Designator; if (Elements[a].Outputs) { if (Elements[a].Outputs.length > 0) { for (let b=0; b < Elements[a].Outputs.length; b++) { elementConnections.push({ FromElement: newElement, Input: Elements[a].Outputs[b].Input, Output: Elements[a].Outputs[b].Output, ToElement: Elements[a].Outputs[b].Element }); } } } if (Elements[a].ICOutputs) { if (Elements[a].ICOutputs.length > 0) { for (let b=0; b < Elements[a].ICOutputs.length; b++) { icelementConnections.push({ Element: newElement, FromContainer: newElement.Container, FromElement: Elements[a].ICOutputs[b].fromElement, Input: Elements[a].ICOutputs[b].Input, ToElement: Elements[a].ICOutputs[b].toElement }); } } } } // Now we need to make all of the connections for (let a = 0; a < elementConnections.length; a++) { if (elementConnections[a].FromElement.Name == "1B_ADD") { console.log("Making connection " + a); console.log(elementConnections[a]); } let toElement = newContainer.HasElement(elementConnections[a].ToElement); if (toElement) { if (elementConnections[a].FromContainer) { let fromElement = elementConnections[a].FromContainer.HasElement(elementConnections[a].fromElement); let newConnection = new ContainerConnection(elementConnections[a].FromContainer,newContainer,fromElement,toElement,elementConnections[a].Input); elementConnections[a].Element.Outputs.push(newConnection); } else { let newConnection = new ElementConnection(newContainer, toElement, elementConnections[a].Input, elementConnections[a].Output); //elementConnections[a].FromElement.addConnection(newContainer,toElement,elementConnections[a].Input,elementConnections[a].Output) if (newConnection) { //elementConnections[a].FromElement.OutputConnections.push(newConnection); elementConnections[a].FromElement.addConnection(newContainer,toElement,elementConnections[a].Input, elementConnections[a].Output) if (elementConnections[a].FromElement.Name == "1B_ADD") { console.log("Making Connection"); console.log(newConnection); console.log(elementConnections[a].FromElement); console.log(elementConnections[a].FromElement.OutputConnections); } } else { console.log("We dont have a new connection!!!"); console.log(toElement); console.log(elementConnections[a]); } } } } /* for (let a = 0; a < icelementConnections.length; a++) { let fromElement = icelementConnections[a].FromContainer.HasElement(icelementConnections[a].FromElement); let toElement = newContainer.HasElement(icelementConnections[a].ToElement); if (toElement) { icelementConnections[a].Element.addConnection(newContainer, toElement, icelementConnections[a].Input); } } */ return newContainer; } function loadsave(savedata) { if (!savedata) return 0; if (!savedata.Version) return -1; // TODO: Let the person know invalid save file if (!isVersionNewer(savedata.Version,"0.3.0")) return -2; // TODO: Let the person know the version is too old let newContainer = loadContainer(savedata.Elements); if (!newContainer) return -3; logicEngine.ActiveContainer = newContainer; return true; }