cpu-simulator/build/editor/js/bk/components.js

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();
}
}
}