Compare commits
No commits in common. "dev-0.5" and "master" have entirely different histories.
@ -20,10 +20,6 @@ LZ-String, Copyright 2013 pieroxy under MIT license https://github.com/pieroxy/l
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### 0.5.0
|
|
||||||
|
|
||||||
* Local Storage
|
|
||||||
|
|
||||||
### 0.4.16
|
### 0.4.16
|
||||||
|
|
||||||
* Fixed bug where properties window didn't disappear at certain times when it should
|
* Fixed bug where properties window didn't disappear at certain times when it should
|
||||||
|
|||||||
134
css/main.css
134
css/main.css
@ -283,10 +283,10 @@ textarea {
|
|||||||
background-color: #54545d;
|
background-color: #54545d;
|
||||||
}
|
}
|
||||||
|
|
||||||
#inner-left-menu::-webkit-scrollbar, #HelpWindowContent::-webkit-scrollbar, #lsbFilesContainer::-webkit-scrollbar, #lsbfoldersContainer::-webkit-scrollbar {
|
#inner-left-menu::-webkit-scrollbar, #HelpWindowContent::-webkit-scrollbar {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
}
|
}
|
||||||
#inner-left-menu::-webkit-scrollbar-track, #HelpWindowContent::-webkit-scrollbar-track, #lsbFilesContainer::-webkit-scrollbar-track, #lsbfoldersContainer::-webkit-scrollbar-track {
|
#inner-left-menu::-webkit-scrollbar-track, #HelpWindowContent::-webkit-scrollbar-track {
|
||||||
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#575a60+0,292b2d+14,000000+49,292b2d+82,575a60+100 */
|
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#575a60+0,292b2d+14,000000+49,292b2d+82,575a60+100 */
|
||||||
background: rgb(87,90,96); /* Old browsers */
|
background: rgb(87,90,96); /* Old browsers */
|
||||||
background: -moz-linear-gradient(left, rgba(87,90,96,1) 0%, rgba(41,43,45,1) 14%, rgba(0,0,0,1) 49%, rgba(41,43,45,1) 82%, rgba(87,90,96,1) 100%); /* FF3.6-15 */
|
background: -moz-linear-gradient(left, rgba(87,90,96,1) 0%, rgba(41,43,45,1) 14%, rgba(0,0,0,1) 49%, rgba(41,43,45,1) 82%, rgba(87,90,96,1) 100%); /* FF3.6-15 */
|
||||||
@ -295,7 +295,7 @@ textarea {
|
|||||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#575a60', endColorstr='#575a60',GradientType=1 ); /* IE6-9 */
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#575a60', endColorstr='#575a60',GradientType=1 ); /* IE6-9 */
|
||||||
}
|
}
|
||||||
|
|
||||||
#inner-left-menu::-webkit-scrollbar-thumb, #HelpWindowContent::-webkit-scrollbar-thumb, #lsbFilesContainer::-webkit-scrollbar-thumb, #lsbfoldersContainer::-webkit-scrollbar-thumb {
|
#inner-left-menu::-webkit-scrollbar-thumb, #HelpWindowContent::-webkit-scrollbar-thumb {
|
||||||
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#000000+0,000000+50,000000+50,8e8e8e+50,000000+100&0+0,1+50,0+100 */
|
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#000000+0,000000+50,000000+50,8e8e8e+50,000000+100&0+0,1+50,0+100 */
|
||||||
background: -moz-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(142,142,142,1) 50%, rgba(0,0,0,0) 100%); /* FF3.6-15 */
|
background: -moz-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(142,142,142,1) 50%, rgba(0,0,0,0) 100%); /* FF3.6-15 */
|
||||||
background: -webkit-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(142,142,142,1) 50%,rgba(0,0,0,0) 100%); /* Chrome10-25,Safari5.1-6 */
|
background: -webkit-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(142,142,142,1) 50%,rgba(0,0,0,0) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||||
@ -382,134 +382,6 @@ textarea {
|
|||||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f85032', endColorstr='#e73827',GradientType=0 ); /* IE6-9 */
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f85032', endColorstr='#e73827',GradientType=0 ); /* IE6-9 */
|
||||||
}
|
}
|
||||||
|
|
||||||
#LocalStorageBrowser {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
min-width: 480px;
|
|
||||||
height: 100px;
|
|
||||||
flex-direction: column;
|
|
||||||
background-color: #777777;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lsbPath {
|
|
||||||
width: 100%;
|
|
||||||
height: 1.2em;
|
|
||||||
margin: 0px;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
background-color: #444455;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lsbContent {
|
|
||||||
width: 100%;
|
|
||||||
min-width: 480px;
|
|
||||||
display: flex;
|
|
||||||
overflow: hidden;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lsbFolders {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-right: 2px;
|
|
||||||
min-width: 150px;
|
|
||||||
width: 30%;
|
|
||||||
background-color: #444455;
|
|
||||||
border: 1px outset #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lsbfoldersContainer {
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
align-items: stretch;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.lsbFolderEntry {
|
|
||||||
color: #00aaaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lsbFolderEntry:hover {
|
|
||||||
color: #00dddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lsbFiles {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 70%;
|
|
||||||
background-color: #444455;
|
|
||||||
border: 1px outset #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
#lsbFilesContainer {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
overflow-clip: all;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.lsbFileHeader,.lsbFolderHeader {
|
|
||||||
background-color: #555555;
|
|
||||||
border: 1px inset #333;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
height: 1.4em;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.lsbFileHeader .FileName,.lsbFileEntry .FileName {
|
|
||||||
width: 50%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: hidden;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
margin-right: 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.lsbFileEntry .FileModified, .lsbFileEntry .FileSize, .lsbFileEntry .FileName {
|
|
||||||
height: 1.2em;
|
|
||||||
}
|
|
||||||
.lsbFileHeader .FileModified,.lsbFileEntry .FileModified {
|
|
||||||
width: 35%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: hidden;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
margin-right: 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lsbFileHeader .FileSize,.lsbFileEntry .FileSize {
|
|
||||||
width: 15%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: hidden;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lsbFileEntry .FileModified,.lsbFileEntry .FileSize {
|
|
||||||
font-size: 0.75em;
|
|
||||||
padding-top: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lsbFileEntry {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#floatCanvas {
|
#floatCanvas {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
25
index.html
25
index.html
@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html class="no-js" lang="" style="height: 100%;" xmlns="http://www.w3.org/1999/html">
|
<html class="no-js" lang="" style="height: 100%;">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
@ -138,40 +138,22 @@
|
|||||||
<li id="rcm_Disconnect">Disconnect</li>
|
<li id="rcm_Disconnect">Disconnect</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="LocalStorageBrowser">
|
|
||||||
<div id="lsbPath">/</div>
|
|
||||||
<div id="lsbContent">
|
|
||||||
<div id="lsbFolders">
|
|
||||||
<div class="lsbFolderHeader">Folders</div>
|
|
||||||
<div id="lsbfoldersContainer">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="lsbFiles">
|
|
||||||
<div class = "lsbFileHeader"><div class="FileName">Name</div><div class="FileModified">Modified</div><div class="FileSize">Size</div></div>
|
|
||||||
<div id="lsbFilesContainer">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="SaveWindow">
|
<div id="SaveWindow">
|
||||||
<div id="SaveWindowTitle">
|
<div id="SaveWindowTitle">
|
||||||
Save Design
|
Save Design
|
||||||
</div>
|
</div>
|
||||||
<div id="SaveWindowContent">
|
<div id="SaveWindowContent">
|
||||||
|
<div>
|
||||||
<span style="padding-right: 10px;">Design Name</span><span><input type="text" id="saveName" value="My Design"></span>
|
<span style="padding-right: 10px;">Design Name</span><span><input type="text" id="saveName" value="My Design"></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="swcLocalStorage">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div id="swcFileSystem">
|
|
||||||
<div>
|
<div>
|
||||||
<input type="checkbox" id="saveCompressed" checked /> Save Compressed
|
<input type="checkbox" id="saveCompressed" checked /> Save Compressed
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div style="margin-top: 10px;">
|
<div style="margin-top: 10px;">
|
||||||
<center><input type="button" id="btn_SaveDesign" value="Save"> <input type="button" id="btn_CancelSave" value="Cancel"></center>
|
<center><input type="button" id="btn_SaveDesign" value="Save"> <input type="button" id="btn_CancelSave" value="Cancel"></center>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div id="HelpWindow">
|
<div id="HelpWindow">
|
||||||
<div id="HelpWindowTitle">
|
<div id="HelpWindowTitle">
|
||||||
MatCat Logic Engine Help
|
MatCat Logic Engine Help
|
||||||
@ -211,7 +193,6 @@
|
|||||||
<script src="js/rightclickmenu/rightclickmenu.js"></script>
|
<script src="js/rightclickmenu/rightclickmenu.js"></script>
|
||||||
<script src="js/globalfunctions.js"></script>
|
<script src="js/globalfunctions.js"></script>
|
||||||
<script src="js/baseclasses.js"></script>
|
<script src="js/baseclasses.js"></script>
|
||||||
<script src="js/localstorage.js"></script>
|
|
||||||
<script src="js/scheduler.js"></script>
|
<script src="js/scheduler.js"></script>
|
||||||
<script src="js/elements/BaseElementClasses.js"></script>
|
<script src="js/elements/BaseElementClasses.js"></script>
|
||||||
<script src="js/elements/InputElements.js"></script>
|
<script src="js/elements/InputElements.js"></script>
|
||||||
|
|||||||
@ -413,26 +413,25 @@ class Element extends CanvasTools {
|
|||||||
let firstY = (centerY - (totalHeight/2)) + 12;
|
let firstY = (centerY - (totalHeight/2)) + 12;
|
||||||
|
|
||||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||||
if (this.isVisible() || this.OutputConnections[a].Element.isVisible()) {
|
let mouseDist = length2D(this.X+(this.Width - 10), firstY + (this.OutputConnections[a].Output*24),this.MousePosition.x,this.MousePosition.y);
|
||||||
let mouseDist = length2D(this.X + (this.Width - 10), firstY + (this.OutputConnections[a].Output * 24), this.MousePosition.x, this.MousePosition.y);
|
|
||||||
if (!this.OutputConnections[a].Container.HasElement(this.OutputConnections[a].Element)) {
|
if (!this.OutputConnections[a].Container.HasElement(this.OutputConnections[a].Element)) {
|
||||||
// This is a ghosted connection, lets get rid of it
|
// This is a ghosted connection, lets get rid of it
|
||||||
this.OutputConnections.splice(a, 1);
|
this.OutputConnections.splice(a,1);
|
||||||
a--;
|
a--;
|
||||||
} else {
|
} else {
|
||||||
let endCenterY = this.OutputConnections[a].Element.Y + Math.round(this.OutputConnections[a].Element.Height / 2);
|
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 endTotalHeight = this.OutputConnections[a].Element.totalInputs() * ((this.OutputConnections[a].Element.inputCircleRadius*2)+4);
|
||||||
let endFirstY = (endCenterY - (endTotalHeight / 2)) + 12;
|
let endFirstY = (endCenterY - (endTotalHeight/2)) + 12;
|
||||||
|
|
||||||
let startX = this.X + (this.Width - this.outputCircleRadius);
|
let startX = this.X + this.Width;
|
||||||
let startY = firstY + (this.OutputConnections[a].Output * 24);
|
let startY = firstY+ (this.OutputConnections[a].Output*24);
|
||||||
let endX = this.OutputConnections[a].Element.X + this.OutputConnections[a].Element.inputCircleRadius;
|
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 endY = endFirstY + (this.OutputConnections[a].Input*24);
|
||||||
let startMidX = startX + ((endX - startX) / 2);
|
let startMidX = startX + ((endX - startX)/2);
|
||||||
let startMidY = startY;
|
let startMidY = startY;
|
||||||
let midX = startMidX;
|
let midX = startMidX;
|
||||||
let midY = startY + ((endY - startY) / 2);
|
let midY = startY + ((endY - startY)/2);
|
||||||
let endMidX = startMidX;
|
let endMidX = startMidX;
|
||||||
let endMidY = endY;
|
let endMidY = endY;
|
||||||
|
|
||||||
@ -442,13 +441,9 @@ class Element extends CanvasTools {
|
|||||||
if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.lineWidth = (settings.LinkWidth * 2);
|
if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.lineWidth = (settings.LinkWidth * 2);
|
||||||
ctx.setLineDash(settings.LinkDash);
|
ctx.setLineDash(settings.LinkDash);
|
||||||
ctx.moveTo(startX, startY);
|
ctx.moveTo(startX, startY);
|
||||||
if (this instanceof LogicWireNode) {
|
//ctx.lineTo(endX, endY);
|
||||||
ctx.lineTo(endX, endY);
|
ctx.quadraticCurveTo(startMidX,startMidY,midX,midY);
|
||||||
} else {
|
ctx.quadraticCurveTo(endMidX,endMidY,endX,endY);
|
||||||
ctx.quadraticCurveTo(startMidX, startMidY, midX, midY);
|
|
||||||
ctx.quadraticCurveTo(endMidX, endMidY, endX, endY);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.strokeStyle = settings.ActiveConnectionColor;
|
ctx.strokeStyle = settings.ActiveConnectionColor;
|
||||||
if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.strokeStyle = settings.ActiveConnectionHoverColor;
|
if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.strokeStyle = settings.ActiveConnectionHoverColor;
|
||||||
if (!this.getOutput(this.OutputConnections[a].Output)) {
|
if (!this.getOutput(this.OutputConnections[a].Output)) {
|
||||||
@ -462,7 +457,6 @@ class Element extends CanvasTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
setConnections() {
|
setConnections() {
|
||||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||||
|
|||||||
@ -545,145 +545,3 @@ class LogicBuffer extends Element {
|
|||||||
let ElementCatalog_BUFFER = new ElementCatalog_Element("Buffer","The buffer is a special gate to allow the prevention of recursion loops.","|>",LogicBuffer,[]);
|
let ElementCatalog_BUFFER = new ElementCatalog_Element("Buffer","The buffer is a special gate to allow the prevention of recursion loops.","|>",LogicBuffer,[]);
|
||||||
ElementReferenceTable.push(ElementCatalog_BUFFER);
|
ElementReferenceTable.push(ElementCatalog_BUFFER);
|
||||||
ElementCategory_LOGIC.addElement(ElementCatalog_BUFFER);
|
ElementCategory_LOGIC.addElement(ElementCatalog_BUFFER);
|
||||||
|
|
||||||
class RAMElement extends Element {
|
|
||||||
constructor(_Container, RestoreData = null, logicengine) {
|
|
||||||
super(_Container, RestoreData = null, logicengine,2);
|
|
||||||
this.Name = "RAM";
|
|
||||||
this.removeProperty("Inputs");
|
|
||||||
this.AddressWidth = 16;
|
|
||||||
this.DataWidth = 8;
|
|
||||||
this._Data = new Array((2 ** this.AddressWidth));
|
|
||||||
|
|
||||||
for (let a = 0; a < this._Data.length; a++) {
|
|
||||||
this._Data[a] = (2 ** this.DataWidth)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Inputs = new Array(this.AddressWidth + this.DataWidth + 3);
|
|
||||||
this.Outputs = new Array(this.DataWidth);
|
|
||||||
|
|
||||||
this.Height = this.Inputs.length * (this.inputCircleRadius + 14)+10;
|
|
||||||
this.Width = (12*(this.DataWidth/4)) + 220;
|
|
||||||
|
|
||||||
this.InputLabels = new Array(this.Inputs.length);
|
|
||||||
for (let a = 0; a < this.DataWidth; a++) {
|
|
||||||
this.InputLabels[a] = "I" + a;
|
|
||||||
this.OutputLabels[a] = "O" + a;
|
|
||||||
}
|
|
||||||
for (let a = 0; a < this.AddressWidth; a++) {
|
|
||||||
this.InputLabels[this.DataWidth+a] = "A" + a;
|
|
||||||
}
|
|
||||||
this.InputLabels[this.DataWidth+this.AddressWidth] = "WriteEnable";
|
|
||||||
this.InputLabels[this.DataWidth+this.AddressWidth+1] = "OutputEnable";
|
|
||||||
this.InputLabels[this.DataWidth+this.AddressWidth+2] = "CLK";
|
|
||||||
|
|
||||||
this.drawElement(0,0,this.StaticCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
setInput(Input, Value) {
|
|
||||||
if (Value) {
|
|
||||||
Value = true;
|
|
||||||
} else {
|
|
||||||
Value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldInput = this.Inputs[Input];
|
|
||||||
if (Input < this.totalInputs()) {
|
|
||||||
this.Inputs[Input] = Value;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let isHigh = this._Container.isHigh(this,Input);
|
|
||||||
if (isHigh !== false) this.Inputs[Input] = true;
|
|
||||||
if (isHigh === false) this.Inputs[Input] = false;
|
|
||||||
if (oldInput != this.Inputs[Input]) {
|
|
||||||
|
|
||||||
if (this.Inputs[this.Inputs.length-2]) {
|
|
||||||
// Output Enable
|
|
||||||
this.setOutput();
|
|
||||||
} else {
|
|
||||||
this.setOutput(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.Inputs[this.Inputs.length-3] && this.Inputs[this.Inputs.length-1] && (Input == this.Inputs.length-1)) {
|
|
||||||
this._Data[this.currentAddress()] = this.currentInputValue();
|
|
||||||
if (this.Inputs[this.Inputs.length-2]) {
|
|
||||||
// Output Enable
|
|
||||||
this.setOutput();
|
|
||||||
} else {
|
|
||||||
this.setOutput(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.setConnections();
|
|
||||||
this.drawElement(0,0,this.StaticCtx);
|
|
||||||
|
|
||||||
}
|
|
||||||
currentAddress() {
|
|
||||||
let addr = 0;
|
|
||||||
for (let a = 0; a < this.AddressWidth; a++) {
|
|
||||||
addr |= ((this.Inputs[this.DataWidth+a]) ? 1 : 0) << a;
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentInputValue() {
|
|
||||||
let val = 0;
|
|
||||||
for (let a = 0; a < this.DataWidth; a++) {
|
|
||||||
val |= ((this.Inputs[a]) ? 1 : 0) << a;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentValue() {
|
|
||||||
return this._Data[this.currentAddress()];
|
|
||||||
}
|
|
||||||
|
|
||||||
setOutput(clear = false) {
|
|
||||||
let currentValue = this.currentValue();
|
|
||||||
for (let a = 0; a < this.DataWidth; a++) {
|
|
||||||
this.Outputs[a] = false;
|
|
||||||
if (!clear && (currentValue & (0b1 << a))) this.Outputs[a] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getOutput(output) {
|
|
||||||
if (this.Outputs[output]) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawElement(x, y, ctx) {
|
|
||||||
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
|
|
||||||
this.StaticCanvas.width = this.Width;
|
|
||||||
this.StaticCanvas.height = this.Height;
|
|
||||||
|
|
||||||
if (!this._Data) return;
|
|
||||||
|
|
||||||
this.drawBorderBox(ctx,x+20,y,this.Width-40,this.Height);
|
|
||||||
this.drawTextCentered(ctx,x+20,(y+(this.Height-16)),this.Width-40,14,this.Designator,"12px Console","#000");
|
|
||||||
|
|
||||||
let totalAddr = Math.floor((this.Height - 40)/14);
|
|
||||||
let startAddr = this.currentAddress() - Math.floor(totalAddr/2);
|
|
||||||
if (startAddr < 0) startAddr = 0;
|
|
||||||
let endAddr = startAddr + totalAddr;
|
|
||||||
if (endAddr > this._Data.length) startAddr = this._Data.length - totalAddr;
|
|
||||||
if (startAddr < 0) startAddr = 0;
|
|
||||||
|
|
||||||
for (let a = 0; a < ((this._Data.length > totalAddr) ? totalAddr : this._Data.length) ; a++) {
|
|
||||||
let getAddr = a+startAddr;
|
|
||||||
if (this.currentAddress() == a + startAddr) this.drawBorderBox(ctx,x+60,(y+10+(a*14)),this.Width-100,14,0,undefined,"#ffffaa");
|
|
||||||
this.drawTextCentered(ctx,x+57,(y+10+(a*14)),(this.Width/2)-20,14,parseInt(a+startAddr).toString(16).toUpperCase().padStart(parseInt(this._Data.length-1).toString(16).length,'0') + `: `,"12px Console","#000");
|
|
||||||
this.drawText(ctx,x+(Math.floor(this.Width/2)+10),(y+22+Math.floor(a*14)), this._Data[(a+startAddr)].toString(16).toUpperCase().padStart(parseInt((2 ** this.DataWidth)-1).toString(16).length,'0'),"12px Console","#000");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
|
||||||
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let ElementCatalog_RAM = new ElementCatalog_Element("RAM","RAM, configurable address and data width",":::",RAMElement,[]);
|
|
||||||
ElementReferenceTable.push(ElementCatalog_RAM);
|
|
||||||
ElementCategory_Other.addElement(ElementCatalog_RAM);
|
|
||||||
|
|||||||
@ -276,33 +276,20 @@ function SaveSettings() {
|
|||||||
console.log("Settings Saved");
|
console.log("Settings Saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSaveState(container = false,localstorage = false) {
|
function createSaveState(container = false) {
|
||||||
if (!container) return false;
|
let saveState = {
|
||||||
let saveState = null;
|
Name: "LogicDesign",
|
||||||
|
|
||||||
if (localstorage) {
|
|
||||||
saveState = {
|
|
||||||
V: Version,
|
|
||||||
TS: Date.now(),
|
|
||||||
PX: logicEngine.Panning.OffsetX,
|
|
||||||
PY: logicEngine.Panning.OffsetY,
|
|
||||||
Elements: new Array()
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
saveState = {
|
|
||||||
Name: "My Design",
|
|
||||||
Version: Version,
|
Version: Version,
|
||||||
Timestamp: Date.now(),
|
Timestamp: Date.now(),
|
||||||
PanX: logicEngine.Panning.OffsetX,
|
PanX: logicEngine.Panning.OffsetX,
|
||||||
PanY: logicEngine.Panning.OffsetY,
|
PanY: logicEngine.Panning.OffsetY,
|
||||||
Elements: new Array()
|
Elements: new Array()
|
||||||
};
|
};
|
||||||
}
|
|
||||||
if (container.Elements.length > 0) saveState.Elements = container.Elements;
|
if (container.Elements.length > 0) saveState.Elements = container.Elements;
|
||||||
let saveCompressed = document.getElementById("saveCompressed");
|
let saveCompressed = document.getElementById("saveCompressed");
|
||||||
if (saveCompressed.checked || forcecompression) {
|
if (saveCompressed.checked) {
|
||||||
saveState.Elements = LZString.compressToUTF16(JSON.stringify(saveState.Elements));
|
saveState.Elements = LZString.compressToUTF16(JSON.stringify(saveState.Elements));
|
||||||
if (!localstorage) saveState.Compressed = true;
|
saveState.Compressed = true;
|
||||||
} else {
|
} else {
|
||||||
saveState.Compressed = false;
|
saveState.Compressed = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,271 +0,0 @@
|
|||||||
class StorageFolder {
|
|
||||||
constructor(restoreSettings) {
|
|
||||||
this.Name = "Folder";
|
|
||||||
this.CreationDate = Date.now();
|
|
||||||
this.LastModifiedDate = Date.now();
|
|
||||||
this.Folder = undefined;
|
|
||||||
this.Designs = new Array();
|
|
||||||
this.Folders = new Array();
|
|
||||||
|
|
||||||
if (restoreSettings) {
|
|
||||||
if (restoreSettings.Name) this.Name = restoreSettings.Name;
|
|
||||||
if (restoreSettings.CreationDate) this.CreationDate = restoreSettings.CreationDate;
|
|
||||||
if (restoreSettings.LastModifiedDate) this.LastModifiedDate = restoreSettings.LastModifiedDate;
|
|
||||||
if (restoreSettings.Folders) {
|
|
||||||
for (let a = 0; a < restoreSettings.Folders.length;a ++) {
|
|
||||||
let sf = new StorageFolder(restoreSettings.Folders[a]);
|
|
||||||
sf.Folder = this;
|
|
||||||
this.Folders.push(sf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (restoreSettings.Designs) {
|
|
||||||
for (let a = 0; a < restoreSettings.Designs.length;a ++) {
|
|
||||||
let sd = new StorageDesign(restoreSettings.Designs[a]);
|
|
||||||
sd.Folder = this;
|
|
||||||
this.Designs.push(sd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON(key) {
|
|
||||||
let sfjson = {};
|
|
||||||
sfjson.Name = this.Name;
|
|
||||||
sfjson.CreationDate = this.CreationDate;
|
|
||||||
sfjson.LastModifiedDate = this.LastModifiedDate;
|
|
||||||
sfjson.Designs = this.Designs;
|
|
||||||
sfjson.Folders = this.Folders;
|
|
||||||
return sfjson;
|
|
||||||
}
|
|
||||||
|
|
||||||
PathString(ChildrenString = "") {
|
|
||||||
if (this.Folder) {
|
|
||||||
let pathString = `<span>${this.Name}</span> ${(ChildrenString != "") ? "/" : ""} ${ChildrenString}`;
|
|
||||||
pathString = this.Folder.PathString(pathString);
|
|
||||||
return pathString;
|
|
||||||
} else {
|
|
||||||
if (ChildrenString == "") {
|
|
||||||
return `<span>/</span> `;
|
|
||||||
} else {
|
|
||||||
return `<span>/</span> ${ChildrenString}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HasFolder(folder = undefined) {
|
|
||||||
if (!folder) return false;
|
|
||||||
for (let a = 0; a < this.Folders.length; a++) {
|
|
||||||
if (folder === this.Folders[a] || folder === this.Folders[a].Name) return this.Folders[a];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddFolder(folder) {
|
|
||||||
if (!folder) return false;
|
|
||||||
let nameCounter = 1;
|
|
||||||
let ogName = folder.Name;
|
|
||||||
folder.Folder = this;
|
|
||||||
|
|
||||||
while (this.HasFolder(folder.Name)) {
|
|
||||||
// There is a name conflict!
|
|
||||||
folder.Name = ogName + " (" + nameCounter + ")";
|
|
||||||
nameCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Folders.push(folder);
|
|
||||||
this.LastModifiedDate = Date.now();
|
|
||||||
return folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveFolder(folder,overide=false) {
|
|
||||||
if (!folder) return false;
|
|
||||||
for (let a = 0; a < this.Folders; a++) {
|
|
||||||
if (folder === this.Folders[a] || folder == this.Folders[a].Name) {
|
|
||||||
if (this.Folders[a].Designs > 0 && !overide) return -1;
|
|
||||||
this.Folders.splice(a,1);
|
|
||||||
this.LastModifiedDate = Date.now();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HasDesign(design) {
|
|
||||||
if (!design) return false;
|
|
||||||
for (let a = 0; a < this.Designs; a++) {
|
|
||||||
if (design === this.Designs[a] || design == this.Designs[a].Name) this.Designs[a];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddDesign(design) {
|
|
||||||
if (!design) return false;
|
|
||||||
let nameCounter = 1;
|
|
||||||
let ogName = design.Name;
|
|
||||||
design.Folder = this;
|
|
||||||
|
|
||||||
while (this.HasDesign(design.Name)) {
|
|
||||||
// There is a name conflict!
|
|
||||||
design.Name = ogName + " (" + nameCounter + ")";
|
|
||||||
nameCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Designs.push(design);
|
|
||||||
this.LastModifiedDate = Date.now();
|
|
||||||
return design;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveDesign(design) {
|
|
||||||
if (!design) return false;
|
|
||||||
for (let a = 0; a < this.Designs; a++) {
|
|
||||||
if (design === this.Designs[a] || design == this.Designs[a].Name) {
|
|
||||||
this.Designs.splice(a,1);
|
|
||||||
this.LastModifiedDate = Date.now();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StorageDesign {
|
|
||||||
constructor(restoreSettings) {
|
|
||||||
this.Name = "My Design";
|
|
||||||
this.Creator = "Anonymous";
|
|
||||||
this.CreationDate = Date.now();
|
|
||||||
this.LastModifiedDate = Date.now();
|
|
||||||
this.Description = "";
|
|
||||||
this.FileIndex = 0;
|
|
||||||
this.Folder = undefined;
|
|
||||||
|
|
||||||
if (restoreSettings) {
|
|
||||||
if (restoreSettings.Name) this.Name = restoreSettings.Name;
|
|
||||||
if (restoreSettings.Creator) this.Creator = restoreSettings.Creator;
|
|
||||||
if (restoreSettings.CreationDate) this.CreationDate = restoreSettings.CreationDate;
|
|
||||||
if (restoreSettings.LastModifiedDate) this.LastModifiedDate = restoreSettings.LastModifiedDate;
|
|
||||||
if (restoreSettings.Description) this.Description = restoreSettings.Description;
|
|
||||||
if (restoreSettings.FileIndex) this.FileIndex = restoreSettings.FileIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON(key) {
|
|
||||||
let sdjson = {};
|
|
||||||
sdjson.Name = this.Name;
|
|
||||||
sdjson.Creator = this.Creator;
|
|
||||||
sdjson.CreationDate = this.CreationDate;
|
|
||||||
sdjson.LastModifiedDate = this.LastModifiedDate;
|
|
||||||
sdjson.Description = this.Description;
|
|
||||||
sdjson.FileIndex = this.FileIndex;
|
|
||||||
return sdjson;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetFile() {
|
|
||||||
let file = JSON.parse(LZString.decompressFromUTF16(localStorage.getItem("LogicPartsfile" + this.FileIndex)));
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveFile(container) {
|
|
||||||
let saveState = createSaveState(container,true);
|
|
||||||
console.log(saveState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalStorage {
|
|
||||||
constructor() {
|
|
||||||
this._FileIndex = 0;
|
|
||||||
this.RootFolder = new StorageFolder({Name: "ROOT"});
|
|
||||||
if (localStorage.getItem('LogicEngineFileTable')) {
|
|
||||||
let LSFT = json.parse(localStorage.getItem('LogicEngineFileTable'));
|
|
||||||
if (LSFT?.Index >= 0) {
|
|
||||||
this._FileIndex = LSFT.Index;
|
|
||||||
if (LSFT.RootFolder) {
|
|
||||||
this.RootFolder = new StorageFolder(LSFT.RootFolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No file table yet!
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalBrowser {
|
|
||||||
constructor(folder = undefined) {
|
|
||||||
this.DOMElement = document.getElementById("LocalStorageBrowser");
|
|
||||||
this.DOMPath = document.getElementById("lsbPath");
|
|
||||||
this.DOMFolders = document.getElementById("lsbfoldersContainer");
|
|
||||||
this.DOMFiles = document.getElementById("lsbFilesContainer");
|
|
||||||
this.DOMFolders.innerHTML = "";
|
|
||||||
this.DOMFiles.innerHTML = "Empty Folder";
|
|
||||||
this.Folder = (folder instanceof StorageFolder) ? folder : new StorageFolder({Name: "ROOT"});
|
|
||||||
this.DOMPath.innerHTML = this.Folder.PathString();
|
|
||||||
|
|
||||||
this.redrawFolders();
|
|
||||||
this.redrawFiles();
|
|
||||||
//this.DOMFolders.addEventListener("contextmenu",function(evt){});
|
|
||||||
}
|
|
||||||
redrawFolders() {
|
|
||||||
this.DOMFolders.innerHTML="";
|
|
||||||
for (let a = 0; a < this.Folder.Folders.length; a++) {
|
|
||||||
this.DOMFolders.innerHTML += `<div class="lsbFolderEntry">${this.Folder.Folders[a].Name}</div>`;
|
|
||||||
}
|
|
||||||
if (this.Folder.Folder) this.DOMFolders.innerHTML += `<div class="lsbFolderEntry">..</div>`;
|
|
||||||
|
|
||||||
let folders = this.DOMFolders.getElementsByClassName('lsbFolderEntry');
|
|
||||||
for (let a = 0; a < folders.length; a ++) {
|
|
||||||
let lbo = this;
|
|
||||||
folders[a].addEventListener("click",function(evt){
|
|
||||||
lbo.FolderClick(folders[a].innerText);
|
|
||||||
}.bind(lbo));
|
|
||||||
}
|
|
||||||
|
|
||||||
let pathfolders = this.DOMPath.getElementsByTagName('span');
|
|
||||||
for (let a = 0; a < pathfolders.length; a ++) {
|
|
||||||
let lbo = this;
|
|
||||||
pathfolders[a].addEventListener("click",function(evt){
|
|
||||||
lbo.FolderClick(pathfolders[a].innerText);
|
|
||||||
}.bind(lbo));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
redrawFiles() {
|
|
||||||
this.DOMFiles.innerHTML="";
|
|
||||||
for (let a = 0; a < this.Folder.Designs.length; a++) {
|
|
||||||
this.DOMFiles.innerHTML += `<div class = "lsbFileEntry"><div class="FileName">${this.Folder.Designs[a].Name}</div><div class="FileModified">${new Date(this.Folder.Designs[a].LastModifiedDate)}</div><div class="FileSize">?.??KB</div></div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let files = this.DOMFiles.getElementsByClassName('lsbFileEntry');
|
|
||||||
for (let a = 0; a < files.length; a ++) {
|
|
||||||
let lbo = this;
|
|
||||||
files[a].addEventListener("click",function(evt){
|
|
||||||
lbo.FileClick(files[a].getElementsByClassName("FileName")[0].innerText);
|
|
||||||
}.bind(lbo));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileClick(file) {
|
|
||||||
console.log(`The file ${file} was clicked from within the folder ${this.Folder.Name}`);
|
|
||||||
}
|
|
||||||
FolderClick(folder) {
|
|
||||||
console.log(`Folder ${folder} was clicked.`);
|
|
||||||
let folderobj = this.Folder.HasFolder(folder);
|
|
||||||
if (folder === ".." || folder === "/") {
|
|
||||||
if (this.Folder.Folder instanceof StorageFolder) this.Folder = this.Folder.Folder;
|
|
||||||
} else {
|
|
||||||
if (folderobj) this.Folder = folderobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.DOMPath.innerHTML = this.Folder.PathString();
|
|
||||||
this.redrawFolders();
|
|
||||||
this.redrawFiles();
|
|
||||||
}
|
|
||||||
ShowBrowser(x,y,w,h) {
|
|
||||||
let lsb = this.DOMElement;
|
|
||||||
lsb.style.left = x + "px";
|
|
||||||
lsb.style.top = y + "px";
|
|
||||||
lsb.style.width = w + "px";
|
|
||||||
lsb.style.height = h + "px";
|
|
||||||
lsb.style.display = "flex";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -550,7 +550,6 @@ class LogicEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.Settings = new LogicEngineSettings(restoresettings);
|
this.Settings = new LogicEngineSettings(restoresettings);
|
||||||
this.LocalStorage = new LocalStorage();
|
|
||||||
this.FPSCounter = 0;
|
this.FPSCounter = 0;
|
||||||
this.FPS = 0;
|
this.FPS = 0;
|
||||||
this.PotentialFPS = 0;
|
this.PotentialFPS = 0;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
MatCat BrowserLogic Simulator
|
MatCat BrowserLogic Simulator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let Version = "0.5.0";
|
let Version = "0.4.16";
|
||||||
|
|
||||||
let spanVersion = document.getElementById("version");
|
let spanVersion = document.getElementById("version");
|
||||||
spanVersion.innerText = Version;
|
spanVersion.innerText = Version;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user