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{ if(w.source.component==0){w.source.pin-=1}}); } else { this.pins.pop(); } } }