206 lines
7.4 KiB
JavaScript
Executable File
206 lines
7.4 KiB
JavaScript
Executable File
class Component {
|
|
type;
|
|
image;
|
|
inputs=0;
|
|
pins = [];
|
|
subComponents = [this];
|
|
zIndex = [];
|
|
wires = [];
|
|
position = { x: 0, y: 0 };
|
|
constructor(name){
|
|
this.type = name;
|
|
if (!(name in chips)) {
|
|
return;
|
|
}
|
|
var chip = JSON.parse(JSON.stringify(chips[name]));
|
|
this.image = chip.image;
|
|
this.pins = chip.pins;
|
|
this.wires = chip.wires;
|
|
this.inputs = chip.inputs;
|
|
chip.subComponents.forEach((sc,i)=>{
|
|
this.subComponents.push(new Component(sc));
|
|
this.zIndex.push(this.subComponents[i]);
|
|
});
|
|
this.process();
|
|
}
|
|
process(){
|
|
if (this.type=="nand"){
|
|
this.pins[2] = (this.pins[0] && this.pins[1])?0:1;
|
|
} else {
|
|
this.subComponents.forEach(s=>{if(s != this) {s.process()}});
|
|
this.wires.forEach(w=>{
|
|
this.subComponents[w.destination.component].pins[w.destination.pin] = this.subComponents[w.source.component].pins[w.source.pin]
|
|
});
|
|
}
|
|
return this.pins;
|
|
}
|
|
addComponent(name){
|
|
var nc = new Component(name);
|
|
this.subComponents.push(nc);
|
|
this.zIndex.unshift(nc);
|
|
}
|
|
removeComponent(index){
|
|
this.zIndex = this.zIndex.filter(zEntry=> this.getProperIndex(zEntry) !== index);
|
|
this.wires.forEach(w=>{
|
|
if(w.source.component == index)
|
|
this.subComponents[w.destination.component].pins[w.destination.pin] = 0;
|
|
});
|
|
this.wires = this.wires.filter(w=>w.source.component != index && w.destination.component != index).map(w => { if(w.destination.component>index){w.destination.component-=1};if(w.source.component>index){w.source.component-=1}; return w });
|
|
|
|
this.subComponents.splice(index,1);
|
|
console.log("hi");
|
|
console.log(this.subComponents);
|
|
|
|
}
|
|
sendToFront(index){
|
|
this.zIndex=this.zIndex.filter(zEntry=>this.getProperIndex(zEntry)!==index);
|
|
this.zIndex.push(this.subComponents[index]);
|
|
}
|
|
getProperIndex(zEntry){
|
|
return this.subComponents.indexOf(zEntry);
|
|
}
|
|
connect(source,destination,wid){
|
|
var sourceIsInput,destinationIsOutput;
|
|
sourceIsInput=destinationIsOutput=0;
|
|
if (source.pin < this.subComponents[source.component].inputs)
|
|
sourceIsInput = true;
|
|
if (destination.pin >= this.subComponents[destination.component].inputs)
|
|
destinationIsOutput = true;
|
|
source = {component:source.component, pin:source.pin};
|
|
destination={component:destination.component,pin:destination.pin};
|
|
if(source.component == 0){ // if the source is the chip itself
|
|
if(destination.component == 0){ // should be direct connection between input and output pins
|
|
if(!(sourceIsInput&&destinationIsOutput)){ // if not,
|
|
if((!sourceIsInput&&!destinationIsOutput)){ // is it backwards?
|
|
var tmp=source;
|
|
source=destination;
|
|
destination=tmp;
|
|
} else { // no, so it's wrong
|
|
console.log("1");
|
|
return false;
|
|
}
|
|
} else {
|
|
// connection between chip and component - both should be inputs or both should be outputs
|
|
if(!((sourceIsInput&&!destinationIsOutput)||(!sourceIsInput && destinationIsOutput))){
|
|
// if not, we know something must be wrong. there is no reason ever for an output pin on a component to go to an input pin or vice versa.
|
|
console.log("2");
|
|
return false;
|
|
} else if(!sourceIsInput&&!destinationIsOutput) {
|
|
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if(destination.component == 0){
|
|
//connection between component and chip! both inputs or both outputs
|
|
if(!((sourceIsInput&&!destinationIsOutput)||(!sourceIsInput && destinationIsOutput))){
|
|
console.log("3");
|
|
return false;
|
|
}
|
|
} else { // connection between two components. source must be an output and destination must be input. cannot be same type.
|
|
//if same type
|
|
|
|
if(!((sourceIsInput&&destinationIsOutput)||(!sourceIsInput&&!destinationIsOutput))){
|
|
console.log("4");
|
|
return false;
|
|
}
|
|
if(sourceIsInput&&destinationIsOutput){ // if that happened its mixed up
|
|
var tmp = source;
|
|
tmp=destination;
|
|
destination=tmp;
|
|
}
|
|
}
|
|
|
|
}
|
|
/*
|
|
var sourceShouldBeInput,destinationShouldBeOutput,sourceIsInput, destinationIsOutput;
|
|
sourceShouldBeInput = destinationShouldBeOutput = sourceIsInput = destinationIsOutput = false;
|
|
if (source.pin < this.subComponents[source.component].inputs)
|
|
sourceIsInput = true;
|
|
if (destination.pin >= this.subComponents[destination.component].inputs)
|
|
destinationIsOutput = true;
|
|
if(source.component==0)
|
|
sourceShouldBeInput=true;
|
|
if(destination.component==0)
|
|
destinationShouldBeOutput=true;
|
|
|
|
if(sourceIsInput&&!sourceShouldBeInput){
|
|
if(destinationIsOutput&&!destinationShouldBeOutput){
|
|
var tmp = source;
|
|
source = destination;
|
|
destination = tmp;
|
|
} else {
|
|
if(
|
|
console.log("no bc source is input xor destination is output");
|
|
console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput});
|
|
return false;
|
|
}
|
|
} else if(destinationIsOutput&&!destinationShouldBeOutput) {
|
|
console.log("no bc destination is output");
|
|
console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput});
|
|
return false;
|
|
}
|
|
if(!sourceIsInput&&sourceShouldBeInput){
|
|
if(!destinationIsOutput&&destinationShouldBeOutput){
|
|
var tmp=source;
|
|
source=destination;
|
|
destination=tmp;
|
|
} else {
|
|
console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput});
|
|
console.log("no bc source is output xor destination is input");
|
|
return false;
|
|
}
|
|
} else if(!destinationIsOutput&&destinationShouldBeOutput) {
|
|
console.log("no bc destination is input");
|
|
console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput});
|
|
return false;
|
|
}
|
|
console.log({sourceIsInput,sourceShouldBeInput,destinationIsOutput,destinationShouldBeOutput});
|
|
/*
|
|
if (sourceIsInput && destinationIsOutput) {
|
|
if (source.component==0||destination.component==0)
|
|
return false;
|
|
var tmp = source;
|
|
source=destination;
|
|
destination = tmp;
|
|
} else if (sourceIsInput || destinationIsOutput) {
|
|
if (!((sourceIsInput && source.component==0)||(destinationIsOutput && destination.component==0)))
|
|
return false;
|
|
} else {
|
|
if(source.component==0||destination.component==0){
|
|
var tmp=source;
|
|
source=destination;
|
|
destination=tmp;
|
|
}
|
|
}
|
|
*/
|
|
this.wires = this.wires.filter(w=>JSON.stringify(w.destination)!=JSON.stringify(destination));
|
|
this.wires.push({ source: source, destination: destination, wireId:wid });
|
|
return true;
|
|
|
|
}
|
|
disconnect(source,destination){
|
|
this.wires = this.wires.filter(w=>JSON.stringify(w)!=JSON.stringify({source:source,destination:destination}));
|
|
}
|
|
addPin(isInput){
|
|
if(isInput){
|
|
this.inputs++;
|
|
this.pins.unshift(0);
|
|
this.wires.forEach(w=>{ if(w.source.component==0){w.source.pin+=1} });
|
|
} else {
|
|
this.pins.push(0);
|
|
}
|
|
}
|
|
removePin(i){;
|
|
this.wires = this.wires.filter(w=>!((w.source.component==0 && w.source.pin == pin)||(w.destination.component==0 && w.destination.pin == pin)));
|
|
if(i<this.inputs){
|
|
this.pins.shift();
|
|
this.wires.forEach(w=>{ if(w.source.component==0){w.source.pin-=1}});
|
|
} else {
|
|
this.pins.pop();
|
|
}
|
|
}
|
|
}
|
|
|
|
|