@prozilla-os/logic-sim 1.1.14 → 1.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -783,7 +783,7 @@ function li({ app: P }) {
783
783
  return /* @__PURE__ */ w("div", { className: ai.LogicSim, children: /* @__PURE__ */ w(ci, { app: P }) });
784
784
  }
785
785
  const hi = new Y("Logic Sim", "logic-sim", li).setIconUrl("https://os.prozilla.dev/assets/apps/icons/logic-sim.svg").setPinnedByDefault(!1).setCategory("Education");
786
- hi.setMetadata({ name: "@prozilla-os/logic-sim", version: "1.1.12", author: "Prozilla" });
786
+ hi.setMetadata({ name: "@prozilla-os/logic-sim", version: "1.1.15", author: "Prozilla" });
787
787
  export {
788
788
  hi as logicSim
789
789
  };
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../src/core/_utils/state.ts","../src/constants/logicSim.const.ts","../src/core/pins/pin.ts","../src/core/chips/chip.ts","../src/core/pins/controlledPin.ts","../src/core/wires/wire.ts","../src/core/inputHandler.ts","../src/core/circuit.ts","../src/core/chips/chipsManager.ts","../src/components/CircuitView.tsx","../src/components/LogicSim.tsx","../src/main.ts"],"sourcesContent":["export class State {\r\n\tvalue: number;\r\n\r\n\tstatic LOW = new State(0);\r\n\tstatic HIGH = new State(1);\r\n\r\n\tconstructor(value: number) {\r\n\t\tthis.value = value;\r\n\t}\r\n\r\n\tstatic invert(state: State) {\r\n\t\treturn new State(1 - state.value);\r\n\t}\r\n\r\n\tisEqual(state: State) {\r\n\t\treturn this.value === state.value;\r\n\t}\r\n}","export const CURSORS = {\n\tdefault: \"default\",\n\tpointer: \"pointer\",\n};\n\nexport const FONT = \"outfit\";\nexport const ENABLE_COLOR_CACHING = true;\nexport const VIRTUAL_PATH = \"~/Apps/logic-sim/\";\n\nexport const BACKGROUND = {\n\tpadding: 30,\n\tborderWidth: 7.5,\n};\n\nexport const CONTROLLER = {\n\tradius: 25,\n\tborderWidth: 5,\n\tpinOffset: 42.5,\n\tconnectorWidth: 7.5,\n\thandleWidth: 15,\n\thandleTrackWidth: 22.5,\n\tplacingOpacity: 0.5,\n};\n\nexport const WIRE = {\n\twidth: 5,\n\tsnappingSensitivity: 10,\n\tcornerRadius: 25,\n\tresolution: 8,\n};\n\nexport const PIN = {\n\tradius: 10,\n\tlabel: {\n\t\toffset: 10,\n\t\tfontSize: 15,\n\t\tpadding: 5,\n\t},\n};\n\nexport const CHIP = {\n\tBorderWidth: 5,\n\tpadding: 10,\n\tfontSize: 35,\n\tplacingOutline: 10,\n};\n\nexport const COLORS = {\n\tpin: {\n\t\tfill: \"black-4\",\n\t\tfillHover: \"black-3\",\n\t\tlabelText: \"white-0\",\n\t\tlabelBackground: \"black-4\",\n\t},\n\tcontroller: {\n\t\tstroke: \"black-4\",\n\t\tconnector: \"black-4\",\n\t\ton: \"red-0\",\n\t\toff: \"red-2\",\n\t\thover: \"white-0\",\n\t\thandle: \"black-3\",\n\t\thandleHover: \"black-4\",\n\t},\n\tbackground: {\n\t\tborder: \"black-0\",\n\t\touter: \"black-1\",\n\t\tinner: \"black-2\",\n\t\tmargin: \"black-2\",\n\t},\n\twire: {\n\t\tplacing: \"black-1\",\n\t},\n\tchip: {\n\t\ttext: \"black-4\",\n\t\toutline: \"white-0\",\n\t},\n};","import { Vector2 } from \"@prozilla-os/core\";\nimport { Chip } from \"../chips/chip\";\nimport { Circuit } from \"../circuit\";\nimport { State } from \"../_utils/state\";\nimport { Wire } from \"../wires/wire\";\nimport { COLORS, CONTROLLER, CURSORS, PIN } from \"../../constants/logicSim.const\";\n\nexport interface PinJson {\n\tname: string;\n\tid: number;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n}\n\nexport class Pin {\n\tid: number;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tattachedChip!: Chip;\n\tcircuit!: Circuit;\n\n\tstate = State.LOW;\n\tisInput!: boolean;\n\tisControlled: boolean = false;\n\toutputWires: Wire[] = [];\n\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, attachedChip: Chip, id?: number) {\n\t\tObject.assign(this, { circuit, name, isInput, attachedChip });\n\t\tthis.id = id ?? this.circuit.getUniqueId();\n\t}\n\n\taddOutputWire(wire: Wire) {\n\t\tthis.outputWires.push(wire);\n\t\twire.setState(this.state);\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\t// TO DO: clean this mess\n\t\tthis.outputWires.forEach((wire) => {\n\t\t\twire.setState(this.state);\n\t\t});\n\t\tthis.attachedChip?.update();\n\t}\n\n\tget isPointingRight() {\n\t\treturn this.isInput === this.isControlled;\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tlet color = COLORS.pin.fill;\n\n\t\tif (this.circuit.inputHandler.mousePosition.getDistance(this.position.x, this.position.y) <= PIN.radius) {\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t\tcolor = COLORS.pin.fillHover;\n\n\t\t\t// Draw label\n\t\t\tlet positionX = this.position.x;\n\t\t\tconst leftAligned = this.isPointingRight;\n\t\t\tconst textRect = this.circuit.getTextRect(PIN.label.fontSize, this.name);\n\n\t\t\tif (leftAligned) {\n\t\t\t\tpositionX += PIN.radius + PIN.label.offset;\n\t\t\t} else {\n\t\t\t\tpositionX -= PIN.radius + PIN.label.offset;\n\t\t\t}\n\n\t\t\tconst backgroundSize = {\n\t\t\t\tx: textRect.x + PIN.label.padding * 2,\n\t\t\t\ty: textRect.y + PIN.label.padding * 2,\n\t\t\t};\n\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelBackground),\n\t\t\t\tleftAligned ? positionX : positionX - backgroundSize.x, this.position.y - textRect.y / 2 - PIN.label.padding,\n\t\t\t\tbackgroundSize.x, backgroundSize.y\n\t\t\t);\n\n\t\t\tif (leftAligned) {\n\t\t\t\tpositionX += PIN.label.padding;\n\t\t\t} else {\n\t\t\t\tpositionX -= PIN.label.padding;\n\t\t\t}\n\n\t\t\tthis.circuit.drawText(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelText),\n\t\t\t\tleftAligned ? \"left\" : \"right\",\n\t\t\t\tpositionX, this.position.y,\n\t\t\t\tPIN.label.fontSize,\n\t\t\t\tthis.name\n\t\t\t);\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tthis.position.x, this.position.y,\n\t\t\tPIN.radius\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\ttoJson(): PinJson {\n\t\tconst object = {\n\t\t\tname: this.name,\n\t\t\tid: this.id,\n\t\t\tposition: this.position,\n\t\t} as PinJson;\n\n\t\treturn object;\n\t}\n}","import { Circuit } from \"../circuit\";\nimport { Pin, PinJson } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { Vector2 } from \"@prozilla-os/core\";\nimport { CHIP, COLORS, PIN } from \"../../constants/logicSim.const\";\n\nexport interface ChipJson {\n\tcolor: string;\n\tname: string;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tinputPins: PinJson[];\n\toutputPins: PinJson[];\n}\n\nexport class Chip {\n\tcolor!: string;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tsize!: Vector2;\n\tcircuit!: Circuit;\n\tisCircuit = false;\n\tisBlueprint = false;\n\n\tinputCount = 0;\n\toutputCount = 0;\n\tinputPins!: Pin[];\n\toutputPins!: Pin[];\n\tlogic!: (inputStates: State[]) => State[];\n\n\tconstructor(circuit: Circuit | null, name: string, color: string, isBlueprint: boolean, inputCount: number, outputCount: number) {\n\t\tObject.assign(this, { circuit, name, color, isBlueprint, inputCount, outputCount });\n\n\t\tif (this.circuit == null && !isBlueprint) {\n\t\t\tthis.circuit = this as unknown as Circuit;\n\t\t\tthis.isCircuit = true;\n\t\t}\n\n\t\tif (this.isCircuit || this.isBlueprint)\n\t\t\treturn;\n\n\n\t\tif (this.circuit != null) {\n\t\t\tconst textRect = this.circuit.getTextRect(CHIP.fontSize, this.name);\n\n\t\t\tconst width = textRect.x + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\t\tconst minHeight = textRect.y + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\n\t\t\tthis.size = new Vector2(width, minHeight);\n\t\t}\n\n\t\tthis.inputPins = [];\n\t\tfor (let i = 0; i < inputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"IN \" + i, true, this);\n\t\t\tthis.inputPins.push(newPin);\n\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\n\t\tthis.outputPins = [];\n\t\tfor (let i = 0; i < outputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"OUT \" + i, false, this);\n\t\t\tthis.outputPins.push(newPin);\n\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\t}\n\n\tsetCircuit(circuit: Circuit) {\n\t\tthis.circuit = circuit;\n\n\t\tthis.inputPins.concat(this.outputPins).forEach((pin) => { pin.circuit = circuit; });\n\t}\n\n\tsetLogic(logic: (inputStates: State[]) => State[]) {\n\t\tthis.logic = logic;\n\t\treturn this;\n\t}\n\n\tupdate() {\n\t\tif (this.logic == null)\n\t\t\treturn;\n\n\t\tconst inputStates: State[] = [];\n\t\tfor (let i = 0; i < this.inputCount; i++) {\n\t\t\tconst state = this.inputPins[i].state ?? State.LOW;\n\t\t\tinputStates.push(state);\n\t\t}\n\n\t\tconst outputStates: State[] = this.logic(inputStates);\n\n\t\tfor (let i = 0; i < this.outputCount; i++) {\n\t\t\tthis.outputPins[i].setState(outputStates[i]);\n\t\t}\n\t}\n\n\tdrawPins(reposition = true) {\n\t\tthis.inputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.inputCount * PIN.radius * 2) / (this.inputCount + 1);\n\t\t\t\tpin.position.x = this.position.x;\n\t\t\t\tpin.position.y = this.position.y + gap * (index + 1) + PIN.radius * (2 * index + 1);\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\n\t\tthis.outputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.outputCount * PIN.radius * 2) / (this.outputCount + 1);\n\t\t\t\tpin.position.x = this.position.x + this.size.x;\n\t\t\t\tpin.position.y = this.position.y + gap * (index + 1) + PIN.radius * (2 * index + 1);\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-1\"),\n\t\t\tthis.position.x, this.position.y,\n\t\t\tthis.size.x, this.size.y\n\t\t);\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-0\"),\n\t\t\tthis.position.x + CHIP.BorderWidth, this.position.y + CHIP.BorderWidth,\n\t\t\tthis.size.x - CHIP.BorderWidth * 2, this.size.y - CHIP.BorderWidth * 2\n\t\t);\n\n\t\tthis.circuit.drawText(\n\t\t\tthis.circuit.getColor(COLORS.chip.text),\n\t\t\t\"center\",\n\t\t\tthis.position.x + this.size.x / 2, this.position.y + this.size.y / 2,\n\t\t\tCHIP.fontSize,\n\t\t\tthis.name\n\t\t);\n\n\t\tif (isPlacing) {\n\t\t\tthis.circuit.setDrawingOpacity(0.25);\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.chip.outline),\n\t\t\t\tthis.position.x - CHIP.placingOutline, this.position.y - CHIP.placingOutline,\n\t\t\t\tthis.size.x + CHIP.placingOutline * 2, this.size.y + CHIP.placingOutline * 2\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t}\n\n\t\tthis.drawPins();\n\t}\n\n\ttoJson(): ChipJson {\n\t\tconst object = {\n\t\t\tcolor: this.color,\n\t\t\tname: this.name,\n\t\t\tposition: {\n\t\t\t\tx: this.position.x,\n\t\t\t\ty: this.position.y,\n\t\t\t},\n\t\t} as ChipJson;\n\n\t\tif (this.inputPins.length > 0)\n\t\t\tobject.inputPins = this.inputPins.map((pin) => pin.toJson());\n\n\t\tif (this.outputPins.length > 0)\n\t\t\tobject.outputPins = this.outputPins.map((pin) => pin.toJson());\n\n\t\treturn object;\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"./pin\";\nimport { COLORS, CONTROLLER, CURSORS } from \"../../constants/logicSim.const\";\n\nexport class ControlledPin extends Pin {\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, id?: number) {\n\t\tsuper(circuit, name, isInput, circuit, id);\n\t\tthis.isControlled = true;\n\t}\n\n\tdrawControllerHandle(isPlacing: boolean) {\n\t\tconst size = { x: CONTROLLER.handleWidth, y: CONTROLLER.radius * 2 };\n\n\t\tlet positionX = this.position.x;\n\t\tconst positionY = this.position.y - size.y / 2;\n\n\n\t\tif (this.isInput) {\n\t\t\tpositionX -= CONTROLLER.pinOffset + CONTROLLER.handleTrackWidth + CONTROLLER.radius;\n\t\t} else {\n\t\t\tpositionX += CONTROLLER.pinOffset + (CONTROLLER.handleTrackWidth - CONTROLLER.handleWidth) + CONTROLLER.radius;\n\t\t}\n\n\t\tconst rect = {\n\t\t\tposition: { x: positionX, y: positionY } as Vector2,\n\t\t\tsize: { x: size.x, y: size.y } as Vector2,\n\t\t};\n\n\t\tlet color: string;\n\n\t\tif (this.circuit.isPointInsideRect(rect, this.circuit.inputHandler.mousePosition)) {\n\t\t\tcolor = COLORS.controller.handleHover;\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.handle;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(color),\n\t\t\trect.position.x, rect.position.y,\n\t\t\trect.size.x, rect.size.y\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawController(isPlacing: boolean) {\n\t\tconst positionX = this.isInput ? this.position.x - CONTROLLER.pinOffset : this.position.x + CONTROLLER.pinOffset;\n\t\tconst positionY = this.position.y;\n\n\t\tlet color: string;\n\n\t\tif (this.state.value === 1) {\n\t\t\tcolor = COLORS.controller.on;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.off;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(COLORS.controller.stroke),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius\n\t\t);\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t);\n\n\t\tconst isInteractable = this.isInput && this.isControlled && !isPlacing;\n\t\tif (isInteractable && this.circuit.inputHandler.mousePosition.getDistance(positionX, positionY) <= CONTROLLER.radius) {\n\t\t\tthis.circuit.setDrawingOpacity(0.125);\n\t\t\tthis.circuit.drawCircle(\n\t\t\t\tthis.circuit.getColor(COLORS.controller.hover),\n\t\t\t\tpositionX, positionY,\n\t\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawConnector(isPlacing: boolean) {\n\t\tif (isPlacing)\n\t\t\treturn;\n\n\t\tconst positionX = this.isInput ? this.position.x - CONTROLLER.pinOffset : this.position.x;\n\t\tconst positionY = this.position.y;\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(COLORS.controller.connector),\n\t\t\tpositionX, positionY - CONTROLLER.connectorWidth / 2,\n\t\t\tCONTROLLER.pinOffset, CONTROLLER.connectorWidth\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tthis.drawConnector(isPlacing);\n\t\tthis.drawController(isPlacing);\n\t\tthis.drawControllerHandle(isPlacing);\n\n\t\tsuper.draw(isPlacing);\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { WIRE } from \"../../constants/logicSim.const\";\n\nexport interface WireJson {\n\tcolor: string;\n\tinputId: number;\n\toutputId: number;\n\tanchorPoints: {\n\t\tx: number;\n\t\ty: number;\n\t}[];\n}\n\nexport class Wire {\n\tcolor!: string;\n\tstate = State.LOW;\n\tinputPin!: Pin;\n\toutputPin!: Pin;\n\tanchorPoints!: Vector2[];\n\tcircuit!: Circuit;\n\tplacedBackwards = false;\n\n\tconstructor(circuit: Circuit, color: string, inputPin?: Pin, outputPin?: Pin, anchorPoints?: Vector2[]) {\n\t\tObject.assign(this, { circuit, color, inputPin, outputPin, anchorPoints });\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\tif (this.outputPin == null)\n\t\t\treturn;\n\n\t\tthis.outputPin.setState(this.state);\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tconst positions = [...this.anchorPoints];\n\n\t\tif (this.inputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.unshift(this.inputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.push(this.inputPin.position);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (this.outputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.push(this.outputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.unshift(this.outputPin.position);\n\t\t\t}\n\t\t}\n\n\t\tlet color: string;\n\n\t\tif (isPlacing) {\n\t\t\tcolor = `${this.color}-2`;\n\t\t} else if (this.state.value === 1) {\n\t\t\tcolor = `${this.color}-0`;\n\t\t} else {\n\t\t\tcolor = `${this.color}-2`;\n\t\t}\n\n\t\tthis.circuit.drawCurvedLine(this.circuit.getColor(color), positions, WIRE.width, WIRE.cornerRadius, WIRE.resolution);\n\t}\n\n\ttoJson() {\n\t\tconst object = {\n\t\t\tcolor: this.color,\n\t\t} as WireJson;\n\n\t\tif (this.inputPin != null)\n\t\t\tobject.inputId = this.inputPin.id;\n\n\t\tif (this.outputPin != null)\n\t\t\tobject.outputId = this.outputPin.id;\n\n\t\tif (this.anchorPoints != null)\n\t\t\tobject.anchorPoints = this.anchorPoints;\n\n\t\treturn object;\n\t}\n}","import { Chip } from \"./chips/chip\";\r\nimport { Circuit } from \"./circuit\";\r\nimport { ControlledPin } from \"./pins/controlledPin\";\r\nimport { Pin } from \"./pins/pin\";\r\nimport { State } from \"./_utils/state\";\r\nimport { Wire } from \"./wires/wire\";\r\nimport { Vector2 } from \"@prozilla-os/core\";\r\nimport { CONTROLLER, PIN, WIRE } from \"../constants/logicSim.const\";\r\n\r\nexport class InputHandler {\r\n\tcircuit!: Circuit;\r\n\tcanvas!: HTMLCanvasElement;\r\n\r\n\tmousePosition = Vector2.ZERO;\r\n\r\n\tisPlacing = false;\r\n\tsnapping = false;\r\n\tplacingOffset = Vector2.ZERO;\r\n\tpreviousPlacement!: Vector2 | null;\r\n\tplacingWire!: Wire | null;\r\n\tplacingChip!: Chip | null;\r\n\tplacingPin!: ControlledPin | null;\r\n\r\n\tconstructor(circuit: Circuit) {\r\n\t\tObject.assign(this, { circuit });\r\n\t}\r\n\r\n\tsetMousePosition(event: MouseEvent) {\r\n\t\tconst rect = this.canvas.getBoundingClientRect();\r\n\t\tthis.mousePosition.x = event.clientX - rect.left;\r\n\t\tthis.mousePosition.y = event.clientY - rect.top;\r\n\t}\r\n\r\n\tinit() {\r\n\t\tthis.canvas = this.circuit.canvas;\r\n\t\tthis.mousePosition = Vector2.ZERO;\r\n\r\n\t\t// TO DO: add support for touch devices\r\n\r\n\t\tthis.canvas.addEventListener(\"mousemove\", this.onMouseMove);\r\n\t\tthis.canvas.addEventListener(\"mouseup\", this.onMouseUp);\r\n\t\tthis.canvas.addEventListener(\"contextmenu\", this.onMouseUp);\r\n\t\tthis.canvas.addEventListener(\"mousedown\", this.onMouseDown);\r\n\r\n\t\twindow.addEventListener(\"keydown\", this.onKeyDown);\r\n\t\twindow.addEventListener(\"keyup\", this.onKeyUp);\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\tthis.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\r\n\t\tthis.canvas.removeEventListener(\"mouseup\", this.onMouseUp);\r\n\t\tthis.canvas.removeEventListener(\"contextmenu\", this.onMouseUp);\r\n\t\tthis.canvas.removeEventListener(\"mousedown\", this.onMouseDown);\r\n\r\n\t\twindow.removeEventListener(\"keydown\", this.onKeyDown);\r\n\t\twindow.removeEventListener(\"keyup\", this.onKeyUp);\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.placingWire = null;\r\n\t\tthis.placingChip = null;\r\n\t\tthis.placingPin = null;\r\n\t\tthis.previousPlacement = null;\r\n\t\tthis.placingOffset = Vector2.ZERO;\r\n\t\tthis.isPlacing = false;\r\n\t}\r\n\r\n\tonMouseMove = (event?: MouseEvent) => {\r\n\t\tif (event != null)\r\n\t\t\tthis.setMousePosition(event);\r\n\r\n\t\tif (this.placingWire != null) {\r\n\t\t\tthis.updateWirePlacement();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (this.placingChip != null) {\r\n\t\t\tthis.updateChipPlacement();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst isHoveringPinHandle = (pin: ControlledPin) => {\r\n\t\t\tconst top = pin.position.y - CONTROLLER.radius;\r\n\t\t\tconst bottom = pin.position.y + CONTROLLER.radius;\r\n\r\n\t\t\treturn (this.mousePosition.y > top && this.mousePosition.y < bottom);\r\n\t\t};\r\n\r\n\t\tif (this.placingPin != null) {\r\n\t\t\tlet invalidPlacement = this.mousePosition.x > CONTROLLER.handleTrackWidth && this.mousePosition.x < this.circuit.size.x - CONTROLLER.handleTrackWidth;\r\n\r\n\t\t\tif (invalidPlacement) {\r\n\t\t\t\tthis.cancelPinPlacement();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (this.placingPin.isInput) {\r\n\t\t\t\tthis.circuit.inputPins.forEach((pin, index) => {\r\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.inputPins.length - 1)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\tthis.circuit.outputPins.forEach((pin, index) => {\r\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.outputPins.length - 1)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\tif (invalidPlacement) {\r\n\t\t\t\tthis.cancelPinPlacement();\r\n\t\t\t} else {\r\n\t\t\t\tthis.updatePinPlacement();\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (this.mousePosition.x < CONTROLLER.handleTrackWidth) {\r\n\t\t\t\tlet invalidPlacement = false;\r\n\r\n\t\t\t\tthis.circuit.inputPins.forEach((pin) => {\r\n\t\t\t\t\tif (invalidPlacement)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!invalidPlacement)\r\n\t\t\t\t\tthis.startPinPlacement(true);\r\n\t\t\t} else if (this.mousePosition.x > this.circuit.size.x - CONTROLLER.handleTrackWidth) {\r\n\t\t\t\tlet invalidPlacement = false;\r\n\r\n\t\t\t\tthis.circuit.outputPins.forEach((pin) => {\r\n\t\t\t\t\tif (invalidPlacement)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!invalidPlacement)\r\n\t\t\t\t\tthis.startPinPlacement(false);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\tonClickPin(pin: Pin) {\r\n\t\tif (this.placingWire != null) {\r\n\t\t\tthis.endWirePlacement(pin);\r\n\t\t} else {\r\n\t\t\tthis.startWirePlacement(pin);\r\n\t\t}\r\n\t}\r\n\r\n\tonMouseUp = (event: MouseEvent) => {\r\n\t\tevent.preventDefault();\r\n\t\tthis.setMousePosition(event);\r\n\r\n\t\tif (event.button === 2) {\r\n\t\t\tif (this.placingWire != null)\r\n\t\t\t\tthis.cancelWirePlacement();\r\n\t\t\tif (this.placingChip != null)\r\n\t\t\t\tthis.cancelChipPlacement();\r\n\t\t} else if (event.button === 0) {\r\n\t\t\tlet eventComplete = false;\r\n\r\n\t\t\tthis.circuit.inputPins.forEach((pin: Pin) => {\r\n\t\t\t\tif (this.mousePosition.getDistance(pin.position.x - CONTROLLER.pinOffset, pin.position.y) <= CONTROLLER.radius) {\r\n\t\t\t\t\tpin.setState(State.invert(pin.state));\r\n\t\t\t\t\teventComplete = true;\r\n\t\t\t\t} else if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\r\n\t\t\t\t\tthis.onClickPin(pin);\r\n\t\t\t\t\teventComplete = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\r\n\t\t\tif (eventComplete)\r\n\t\t\t\treturn;\r\n\t\r\n\t\t\tthis.circuit.outputPins.forEach((pin: Pin) => {\r\n\t\t\t\tif (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\r\n\t\t\t\t\tthis.onClickPin(pin);\r\n\t\t\t\t\teventComplete = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\r\n\t\t\tif (eventComplete)\r\n\t\t\t\treturn;\r\n\r\n\t\t\tthis.circuit.chips.forEach((chip) => {\r\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\r\n\t\t\t\t\tif (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\r\n\t\t\t\t\t\tthis.onClickPin(pin);\r\n\t\t\t\t\t\teventComplete = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\tif (eventComplete)\r\n\t\t\t\treturn;\r\n\t\r\n\t\t\tif (this.placingWire != null)\r\n\t\t\t\tthis.anchorWirePlacement();\r\n\r\n\t\t\tif (this.placingChip != null)\r\n\t\t\t\tthis.endChipPlacement();\r\n\r\n\t\t\tif (this.placingPin != null)\r\n\t\t\t\tthis.endPinPlacement();\r\n\t\t}\r\n\t};\r\n\r\n\tonMouseDown = (event: MouseEvent) => {\r\n\t\tevent.preventDefault();\r\n\t\tthis.setMousePosition(event);\r\n\r\n\t\tif (event.button !== 0 || this.isPlacing)\r\n\t\t\treturn;\r\n\r\n\t\tthis.circuit.chips.forEach((chip, index) => {\r\n\t\t\tif (!this.isPlacing && this.circuit.isPointInsideRect(chip, this.mousePosition)) {\r\n\t\t\t\tlet hoveringPin = false;\r\n\r\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\r\n\t\t\t\t\tif (pin.position.getDistance(this.mousePosition.x, this.mousePosition.y) <= PIN.radius)\r\n\t\t\t\t\t\thoveringPin = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!hoveringPin)\r\n\t\t\t\t\tthis.editChipPlacement(chip, index);\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\tonKeyDown = (event: KeyboardEvent) => {\r\n\t\tswitch (event.key) {\r\n\t\t\tcase \"Shift\":\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tthis.snapping = true;\r\n\t\t\t\tthis.onMouseMove();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Backspace\":\r\n\t\t\tcase \"Delete\":\r\n\t\t\tcase \"Escape\":\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tif (this.placingWire != null)\r\n\t\t\t\t\tthis.cancelWirePlacement();\r\n\t\t\t\tif (this.placingChip != null)\r\n\t\t\t\t\tthis.cancelChipPlacement();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\tonKeyUp = (event: KeyboardEvent) => {\r\n\t\tswitch (event.key) {\r\n\t\t\tcase \"Shift\":\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tthis.snapping = false;\r\n\t\t\t\tthis.onMouseMove();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\tstartWirePlacement(pin: Pin) {\r\n\t\tconst isInputPin = pin.isPointingRight;\r\n\r\n\t\t// Start wire placement\r\n\t\tconst inputPin = isInputPin ? pin : undefined;\r\n\t\tconst outputPin = !isInputPin ? pin : undefined;\r\n\t\tconst anchorPoint = this.mousePosition.clone;\r\n\r\n\t\tthis.placingWire = new Wire(this.circuit, \"red\", inputPin, outputPin, [anchorPoint]);\r\n\r\n\t\tif (!isInputPin)\r\n\t\t\tthis.placingWire.placedBackwards = true;\r\n\r\n\t\tthis.circuit.wires.push(this.placingWire);\r\n\t}\r\n\r\n\tsnapWireHorizontally(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\r\n\t\tlastAnchorPoint.x = this.mousePosition.x;\r\n\t\tlastAnchorPoint.y = previousAnchorPoint.y;\r\n\r\n\t\t// Snapping horizontal wire to other wires\r\n\t\tlet anchorPoints: Vector2[] = [];\r\n\r\n\t\tthis.circuit.wires.forEach((wire, index) => {\r\n\t\t\tif (index < this.circuit.wires.length - 1)\r\n\t\t\t\tanchorPoints = anchorPoints.concat(wire.anchorPoints);\r\n\t\t});\r\n\r\n\t\tlet closestPositionX: number | undefined;\r\n\t\tlet closestDistance: number | undefined;\r\n\r\n\t\tanchorPoints.forEach((point) => {\r\n\t\t\tconst distance = Math.abs(this.mousePosition.x - point.x);\r\n\r\n\t\t\tif (closestDistance == null || closestDistance > distance) {\r\n\t\t\t\tclosestPositionX = point.x;\r\n\t\t\t\tclosestDistance = distance;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (closestDistance != null && closestPositionX != null && closestDistance < WIRE.snappingSensitivity)\r\n\t\t\tlastAnchorPoint.x = closestPositionX;\r\n\t}\r\n\r\n\tsnapWireVertically(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\r\n\t\tlastAnchorPoint.x = previousAnchorPoint.x;\r\n\t\tlastAnchorPoint.y = this.mousePosition.y;\r\n\r\n\t\t// Snapping vertical wire to pins\r\n\t\tlet pins: Pin[];\r\n\r\n\t\tif (!this.placingWire?.placedBackwards) {\r\n\t\t\tpins = this.circuit.outputPins;\r\n\r\n\t\t\tthis.circuit.chips.forEach((chip) => {\r\n\t\t\t\tpins = pins.concat(chip.inputPins);\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\tpins = this.circuit.inputPins;\r\n\r\n\t\t\tthis.circuit.chips.forEach((chip) => {\r\n\t\t\t\tpins = pins.concat(chip.outputPins);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tlet closestPositionY: number | undefined;\r\n\t\tlet closestDistance: number | undefined;\r\n\r\n\t\tpins.forEach((pin) => {\r\n\t\t\tconst distance = Math.abs(this.mousePosition.y - pin.position.y);\r\n\r\n\t\t\tif (closestDistance == null || closestDistance > distance) {\r\n\t\t\t\tclosestPositionY = pin.position.y;\r\n\t\t\t\tclosestDistance = distance;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (closestDistance != null && closestPositionY != null && closestDistance < WIRE.snappingSensitivity)\r\n\t\t\tlastAnchorPoint.y = closestPositionY;\r\n\t}\r\n\r\n\tupdateWirePlacement() {\r\n\t\tconst anchorCount = this.placingWire?.anchorPoints.length;\r\n\t\tif (anchorCount == null) return;\r\n\t\tconst lastAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 1];\r\n\t\tif (lastAnchorPoint == null) return;\r\n\r\n\t\tif (!this.snapping) {\r\n\t\t\tlastAnchorPoint.x = this.mousePosition.x;\r\n\t\t\tlastAnchorPoint.y = this.mousePosition.y;\r\n\t\t} else {\r\n\t\t\t// Wire snapping\r\n\t\t\tlet previousAnchorPoint: Vector2 | undefined;\r\n\r\n\t\t\tif (anchorCount >= 2) {\r\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 2];\r\n\t\t\t} else if (!this.placingWire?.placedBackwards) {\r\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.inputPin.position;\r\n\t\t\t} else {\r\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.outputPin.position;\r\n\t\t\t}\r\n\r\n\t\t\tif (previousAnchorPoint == null) return;\r\n\t\r\n\t\t\tconst deltaX = Math.abs(this.mousePosition.x - previousAnchorPoint.x);\r\n\t\t\tconst deltaY = Math.abs(this.mousePosition.y - previousAnchorPoint.y);\r\n\t\r\n\t\t\tif (deltaX > deltaY) {\r\n\t\t\t\tthis.snapWireHorizontally(lastAnchorPoint, previousAnchorPoint);\r\n\t\t\t} else {\r\n\t\t\t\tthis.snapWireVertically(lastAnchorPoint, previousAnchorPoint);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tanchorWirePlacement() {\r\n\t\tthis.placingWire?.anchorPoints.push(this.mousePosition.clone);\r\n\t}\r\n\r\n\tcancelWirePlacement() {\r\n\t\tthis.placingWire = null;\r\n\t\tthis.isPlacing = false;\r\n\t\tthis.circuit.wires.pop();\r\n\t}\r\n\r\n\tendWirePlacement(pin: Pin) {\r\n\t\tconst isInputPin = pin.isPointingRight;\r\n\r\n\t\tif (this.placingWire == null) return;\r\n\r\n\t\tlet correctPlacement = false;\r\n\t\tif (!isInputPin && !this.placingWire.placedBackwards) {\r\n\t\t\tthis.placingWire.outputPin = pin;\r\n\t\t\tcorrectPlacement = true;\r\n\t\t} else if (isInputPin && this.placingWire.placedBackwards) {\r\n\t\t\tthis.placingWire.inputPin = pin;\r\n\t\t\tcorrectPlacement = true;\r\n\t\t}\r\n\r\n\t\tif (correctPlacement) {\r\n\t\t\tthis.placingWire.anchorPoints.pop();\r\n\t\t\tthis.placingWire.inputPin.addOutputWire(this.placingWire);\r\n\t\t\tthis.placingWire.inputPin.update();\r\n\r\n\t\t\tthis.placingWire = null;\r\n\t\t\tthis.isPlacing = false;\r\n\t\t}\r\n\t}\r\n\r\n\tstartChipPlacement(chip: Chip) {\r\n\t\tconst newChip = new Chip(this.circuit, chip.name, chip.color, false, chip.inputCount, chip.outputCount);\r\n\t\tnewChip.setLogic(chip.logic);\r\n\t\tnewChip.position = new Vector2(\r\n\t\t\tthis.mousePosition.x - newChip.size.x / 2,\r\n\t\t\tthis.mousePosition.y - newChip.size.y / 2\r\n\t\t);\r\n\r\n\t\tthis.placingChip = newChip;\r\n\t\tthis.isPlacing = true;\r\n\t\tthis.circuit.chips.push(newChip);\r\n\t}\r\n\r\n\teditChipPlacement(chip: Chip, index: number) {\r\n\t\tthis.placingOffset = new Vector2(\r\n\t\t\t(chip.position.x + chip.size.x / 2) - this.mousePosition.x,\r\n\t\t\t(chip.position.y + chip.size.y / 2) - this.mousePosition.y\r\n\t\t);\r\n\t\tthis.previousPlacement = chip.position.clone;\r\n\t\tthis.circuit.chips.push(this.circuit.chips.splice(index, 1)[0]);\r\n\r\n\t\tthis.placingChip = chip;\r\n\t\tthis.isPlacing = true;\r\n\t}\r\n\r\n\tupdateChipPlacement() {\r\n\t\tif (this.placingChip == null) return;\r\n\t\tthis.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2 + this.placingOffset.x;\r\n\t\tthis.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2 + this.placingOffset.y;\r\n\t}\r\n\r\n\tcancelChipPlacement() {\r\n\t\tif (this.placingChip == null) return;\r\n\r\n\t\tif (this.previousPlacement != null) {\r\n\t\t\tthis.placingChip.position = this.previousPlacement;\r\n\t\t\tthis.previousPlacement = null;\r\n\t\t} else {\r\n\t\t\tthis.circuit.chips.pop();\r\n\t\t}\r\n\r\n\t\tthis.placingChip = null;\r\n\t\tthis.isPlacing = false;\r\n\t}\r\n\r\n\tendChipPlacement() {\r\n\t\tthis.placingChip = null;\r\n\t\tthis.isPlacing = false;\r\n\t\tthis.placingOffset = Vector2.ZERO;\r\n\t}\r\n\r\n\tstartPinPlacement(isInput: boolean) {\r\n\t\tconst newPin = new ControlledPin(this.circuit, \"PIN\", isInput);\r\n\r\n\t\tnewPin.position.x = CONTROLLER.handleTrackWidth + CONTROLLER.pinOffset + CONTROLLER.radius;\r\n\t\tnewPin.position.y = this.mousePosition.y;\r\n\r\n\t\tif (isInput) {\r\n\t\t\tthis.circuit.inputPins.push(newPin);\r\n\t\t} else {\r\n\t\t\tnewPin.position.x = this.circuit.size.x - newPin.position.x;\r\n\t\t\tthis.circuit.outputPins.push(newPin);\r\n\t\t}\r\n\r\n\t\tthis.placingPin = newPin;\r\n\t}\r\n\r\n\tupdatePinPlacement() {\r\n\t\tif (this.placingPin != null)\r\n\t\t\tthis.placingPin.position.y = this.mousePosition.y;\r\n\t}\r\n\r\n\tcancelPinPlacement() {\r\n\t\tif (this.placingPin?.isInput) {\r\n\t\t \tthis.circuit.inputPins.pop();\r\n\t\t} else {\r\n\t\t\tthis.circuit.outputPins.pop();\r\n\t\t}\r\n\r\n\t\tthis.placingPin = null;\r\n\t}\r\n\r\n\tendPinPlacement() {\r\n\t\tthis.placingPin = null;\r\n\t}\r\n\r\n\tisPlacingPin(pin: Pin, index: number) {\r\n\t\tif (!pin.isControlled || this.placingPin == null || this.placingPin.isInput != pin.isInput)\r\n\t\t\treturn false;\r\n\r\n\t\tif (pin.isInput) {\r\n\t\t\treturn index == this.circuit.inputPins.length - 1;\r\n\t\t} else {\r\n\t\t\treturn index == this.circuit.outputPins.length - 1;\r\n\t\t}\r\n\t}\r\n}","import { Vector2 } from \"@prozilla-os/core\";\r\nimport { Chip, ChipJson } from \"./chips/chip\";\r\nimport { ControlledPin } from \"./pins/controlledPin\";\r\nimport { InputHandler } from \"./inputHandler\";\r\nimport { Wire, WireJson } from \"./wires/wire\";\r\nimport { BACKGROUND, COLORS, CONTROLLER, CURSORS, ENABLE_COLOR_CACHING, FONT } from \"../constants/logicSim.const\";\r\nimport { clamp } from \"@prozilla-os/shared\";\r\n\r\nexport interface CircuitJson extends ChipJson {\r\n\twires: WireJson[];\r\n\tchips: ChipJson[];\r\n}\r\n\r\nexport class Circuit extends Chip {\r\n\tcanvas!: HTMLCanvasElement;\r\n\tsize = Vector2.ZERO;\r\n\tcontext!: CanvasRenderingContext2D;\r\n\tcolors: { [key: string]: string } = {};\r\n\tinputHandler: InputHandler;\r\n\r\n\tinputPins: ControlledPin[] = [];\r\n\toutputPins: ControlledPin[] = [];\r\n\r\n\twires: Wire[] = [];\r\n\tchips: Chip[] = [];\r\n\r\n\tcursor = CURSORS.default;\r\n\r\n\tlastId = 0;\r\n\r\n\tconstructor(name: string, color: string, inputCount: number, outputCount: number) {\r\n\t\tsuper(null, name, color, false, inputCount, outputCount);\r\n\t\tthis.inputHandler = new InputHandler(this);\r\n\t}\r\n\r\n\tresize() {\r\n\t\tthis.size.x = this.canvas.clientWidth;\r\n\t\tthis.size.y = this.canvas.clientHeight;\r\n\t}\r\n\r\n\tinit(canvas: HTMLCanvasElement) {\r\n\t\tthis.canvas = canvas;\r\n\t\tthis.context = this.canvas.getContext(\"2d\") as CanvasRenderingContext2D;\r\n\t\tthis.resize();\r\n\r\n\t\t// Detect size changes of canvas\r\n\t\tconst observer = new ResizeObserver((entries) => {\r\n\t\t\tentries.forEach(({ target }) => {\r\n\t\t\t\tif (target === this.canvas && (target.clientWidth != this.size.x || target.clientHeight != this.size.y)) {\r\n\t\t\t\t\tthis.resize();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tobserver.observe(this.canvas);\r\n\r\n\t\tthis.inputHandler.init();\r\n\r\n\t\tthis.render();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\tthis.inputHandler.cleanup();\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.inputPins = [];\r\n\t\tthis.outputPins = [];\r\n\t\tthis.wires = [];\r\n\t\tthis.chips = [];\r\n\r\n\t\tthis.inputHandler.reset();\r\n\t}\r\n\r\n\tgetColor(key: string) {\r\n\t\tif (this.colors[key] != null)\r\n\t\t\treturn this.colors[key];\r\n\r\n\t\tconst color = getComputedStyle(this.canvas).getPropertyValue(\"--\" + key);\r\n\r\n\t\tif (ENABLE_COLOR_CACHING)\r\n\t\t\tthis.colors[key] = color;\r\n\r\n\t\treturn color;\r\n\t}\r\n\r\n\tisPointInsideRect(rect: { position: Vector2, size: Vector2 }, point: Vector2) {\r\n\t\treturn point.x > rect.position.x && point.y > rect.position.y\r\n\t\t\t&& point.x < rect.position.x + rect.size.x && point.y < rect.position.y + rect.size.y;\r\n\t}\r\n\r\n\tgetUniqueId() {\r\n\t\treturn this.lastId++;\r\n\t}\r\n\r\n\tgetTextRect(size: number, content: string) {\r\n\t\tthis.context.textBaseline = \"middle\";\r\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\r\n\t\tconst metrics = this.context.measureText(content);\r\n\r\n\t\tconst width = metrics.actualBoundingBoxRight + metrics.actualBoundingBoxLeft;\r\n\t\tconst height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n\t\treturn { x: width, y: height };\r\n\t}\r\n\r\n\tdrawRect(style: string, positionX: number, positionY: number, sizeX: number, sizeY: number) {\r\n\t\tthis.context.fillStyle = style;\r\n\t\tthis.context.fillRect(positionX, positionY, sizeX, sizeY);\r\n\t}\r\n\r\n\tdrawCircle(style: string, positionX: number, positionY: number, radius: number) {\r\n\t\tthis.context.beginPath();\r\n\t\tthis.context.arc(positionX, positionY, radius, 0, 2 * Math.PI);\r\n\r\n\t\tthis.context.fillStyle = style;\r\n\t\tthis.context.fill();\r\n\t}\r\n\r\n\tdrawCurvedLine(style: string, positions: Vector2[], width: number, radius: number, resolution: number) {\r\n\t\tif (positions.length < 2)\r\n\t\t\treturn;\r\n\r\n\t\tthis.context.lineWidth = width;\r\n\t\tthis.context.lineJoin = \"round\";\r\n\t\tthis.context.lineCap = \"round\";\r\n\r\n\t\t/**\r\n\t\t * Based on https://github.com/SebLague/Digital-Logic-Sim/blob/main/Assets/Modules/Chip%20Creation/Scripts/Chip/Wires/WireRenderer.cs\r\n\t\t * TO DO: optimize\r\n\t\t */\r\n\r\n\t\tconst drawPoints: Vector2[] = [];\r\n\t\tdrawPoints.push(positions[0]);\r\n\r\n\t\tfor (let i = 1; i < positions.length - 1; i++) {\r\n\t\t\tconst targetPoint = positions[i];\r\n\t\t\tconst targetDir = Vector2.normalize(Vector2.subtract(positions[i], positions[i - 1]));\r\n\t\t\tconst distanceToTarget = Vector2.magnitude(Vector2.subtract(positions[i], positions[i - 1]));\r\n\t\t\tconst distanceToCurveStart = Math.max(distanceToTarget - radius, distanceToTarget / 2);\r\n\r\n\t\t\tconst nextTargetDir = Vector2.normalize(Vector2.subtract(positions[i + 1], positions[i]));\r\n\t\t\tconst nextLineLength = Vector2.magnitude(Vector2.subtract(positions[i + 1], positions[i]));\r\n\r\n\t\t\tconst curveStartPoint = Vector2.add(positions[i - 1], Vector2.scale(targetDir, distanceToCurveStart));\r\n\t\t\tconst curveEndPoint = Vector2.add(targetPoint, Vector2.scale(nextTargetDir, Math.min(radius, nextLineLength / 2)));\r\n\r\n\t\t\t// Bezier\r\n\t\t\tfor (let j = 0; j < resolution; j++) {\r\n\t\t\t\tconst t = j / (resolution - 1);\r\n\t\t\t\tconst a = Vector2.lerp(curveStartPoint, targetPoint, t);\r\n\t\t\t\tconst b = Vector2.lerp(targetPoint, curveEndPoint, t);\r\n\t\t\t\tconst p = Vector2.lerp(a, b, t);\r\n\r\n\t\t\t\tif (Vector2.sqrDistance(p, drawPoints[drawPoints.length - 1]) > 0.001) {\r\n\t\t\t\t\tdrawPoints.push(p);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tdrawPoints.push(positions[positions.length - 1]);\r\n\r\n\t\tthis.context.beginPath();\r\n\t\tthis.context.moveTo(drawPoints[0].x, drawPoints[0].y);\r\n\r\n\t\tfor (let i = 1; i < drawPoints.length; i++) {\r\n\t\t\tthis.context.lineTo(drawPoints[i].x, drawPoints[i].y);\r\n\t\t}\r\n\r\n\t\tthis.context.strokeStyle = style;\r\n\t\tthis.context.stroke();\r\n\t}\r\n\r\n\tdrawText(style: string, align: CanvasTextAlign, positionX: number, positionY: number, size: number, content: string) {\r\n\t\tthis.context.fillStyle = style;\r\n\t\tthis.context.textAlign = align;\r\n\t\tthis.context.textBaseline = \"middle\";\r\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\r\n\t\tthis.context.fillText(content, positionX, positionY);\r\n\t}\r\n\r\n\tsetDrawingOpacity(alpha: number) {\r\n\t\tthis.context.globalAlpha = clamp(alpha, 0, 1);\r\n\t}\r\n\r\n\tresetDrawingOpacity() {\r\n\t\tthis.setDrawingOpacity(1);\r\n\t}\r\n\r\n\tdrawBackground() {\r\n\t\tconst margin = CONTROLLER.handleTrackWidth;\r\n\t\tconst padding = BACKGROUND.padding;\r\n\r\n\t\tthis.drawRect(this.getColor(COLORS.background.margin), 0, 0, this.size.x, this.size.y);\r\n\r\n\t\tlet offset = 0;\r\n\r\n\t\tthis.drawRect(\r\n\t\t\tthis.getColor(COLORS.background.outer),\r\n\t\t\toffset + margin, offset,\r\n\t\t\tthis.size.x - margin * 2, this.size.y\r\n\t\t);\r\n\r\n\t\toffset = padding - BACKGROUND.borderWidth;\r\n\t\tthis.drawRect(\r\n\t\t\tthis.getColor(COLORS.background.border),\r\n\t\t\toffset + margin, offset,\r\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\r\n\t\t);\r\n\r\n\t\toffset = padding;\r\n\t\tthis.drawRect(\r\n\t\t\tthis.getColor(COLORS.background.inner),\r\n\t\t\toffset + margin, offset,\r\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\r\n\t\t);\r\n\t}\r\n\r\n\tdrawWires() {\r\n\t\tthis.wires.forEach((wire, index) => {\r\n\t\t\tconst isPlacingWire = this.inputHandler.placingWire != null && index == this.wires.length - 1;\r\n\t\t\twire.draw(isPlacingWire);\r\n\t\t});\r\n\t}\r\n\r\n\tdrawChips() {\r\n\t\tthis.chips.forEach((chip, index) => {\r\n\t\t\tconst isPlacingChip = this.inputHandler.placingChip != null && index == this.chips.length - 1;\r\n\t\t\tchip.draw(isPlacingChip);\r\n\t\t});\r\n\t}\r\n\r\n\tdraw() {\r\n\t\tthis.drawBackground();\r\n\t\tthis.drawWires();\r\n\t\tthis.drawChips();\r\n\t\tsuper.drawPins(false);\r\n\t}\r\n\r\n\trender() {\r\n\t\tif (this.canvas.width != this.size.x)\r\n\t\t\tthis.canvas.width = this.size.x;\r\n\t\tif (this.canvas.height != this.size.y)\r\n\t\t\tthis.canvas.height = this.size.y;\r\n\r\n\t\tthis.cursor = CURSORS.default;\r\n\r\n\t\tthis.draw();\r\n\r\n\t\tif (this.inputHandler.isPlacing) {\r\n\t\t\tthis.canvas.style.cursor = CURSORS.default;\r\n\t\t} else {\r\n\t\t\tthis.canvas.style.cursor = this.cursor;\r\n\t\t}\r\n\r\n\t\twindow.requestAnimationFrame(() => {\r\n\t\t\tthis.render();\r\n\t\t});\r\n\t}\r\n\r\n\ttoJson() {\r\n\t\tconst object = super.toJson() as CircuitJson;\r\n\r\n\t\tif (this.wires.length > 0)\r\n\t\t\tobject.wires = this.wires.map((wire) => wire.toJson());\r\n\r\n\t\tif (this.chips.length > 0)\r\n\t\t\tobject.chips = this.chips.map((chip) => chip.toJson());\r\n\r\n\t\treturn object;\r\n\t}\r\n\r\n\ttoString(): string {\r\n\t\tconst json = this.toJson();\r\n\t\treturn JSON.stringify(json);\r\n\t}\r\n}","import { Chip } from \"./chip\";\nimport { State } from \"../_utils/state\";\nimport { Circuit, CircuitJson } from \"../circuit\";\nimport { ControlledPin } from \"../pins/controlledPin\";\nimport { Pin } from \"../pins/pin\";\nimport { Wire } from \"../wires/wire\";\nimport { Vector2, VirtualFolder } from \"@prozilla-os/core\";\n\nexport class ChipsManager {\n\tstatic CHIPS: Record<string, Chip> = {\n\t\tand: new Chip(null, \"AND\", \"blue\", true, 2, 1).setLogic((inputStates: State[]) => {\n\t\t\tif (inputStates[0].value === 1 && inputStates[1].value === 1) {\n\t\t\t\treturn [State.HIGH];\n\t\t\t} else {\n\t\t\t\treturn [State.LOW];\n\t\t\t}\n\t\t}),\n\t\tnot: new Chip(null, \"NOT\", \"red\", true, 1, 1).setLogic((inputStates: State[]) => {\n\t\t\treturn [State.invert(inputStates[0])];\n\t\t}),\n\t};\n\n\tstatic saveCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tvirtualFolder.createFile(circuit.name, \"json\", (file) => {\n\t\t\tfile.setContent(circuit.toString());\n\t\t});\n\t}\n\n\tstatic loadCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tcircuit.reset();\n\t\tconst virtualFile = virtualFolder.findFile(circuit.name, \"json\");\n\n\t\tif (virtualFile == null)\n\t\t\treturn;\n\n\t\tvirtualFile.read()?.then((content) => {\n\t\t\tconst data = JSON.parse(content as string) as CircuitJson;\n\n\t\t\tcircuit.color = data.color;\n\t\t\tcircuit.name = data.name;\n\n\t\t\tconst pins: { [id: number]: Pin } = {};\n\n\t\t\t// Load input pins\n\t\t\tcircuit.inputCount = data.inputPins?.length ?? 0;\n\t\t\tdata.inputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, true, pinData.id);\n\t\t\t\tnewPin.position = pinData.position as Vector2;\n\n\t\t\t\tcircuit.inputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load output pins\n\t\t\tcircuit.outputCount = data.outputPins?.length ?? 0;\n\t\t\tdata.outputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, false, pinData.id);\n\t\t\t\tnewPin.position = pinData.position as Vector2;\n\n\t\t\t\tcircuit.outputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load chips\n\t\t\tdata.chips?.forEach((chipData) => {\n\t\t\t\tconst newChip = new Chip(circuit, chipData.name, chipData.color, false, 0, 0);\n\t\t\t\tnewChip.position = chipData.position as Vector2;\n\n\t\t\t\t// Load input pins\n\t\t\t\tnewChip.inputCount = chipData.inputPins?.length ?? 0;\n\t\t\t\tchipData.inputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, true, newChip, pinData.id);\n\t\t\t\t\tnewChip.inputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load output pins\n\t\t\t\tnewChip.outputCount = chipData.outputPins?.length ?? 0;\n\t\t\t\tchipData.outputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, false, newChip, pinData.id);\n\t\t\t\t\tnewChip.outputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load logic\n\t\t\t\tnewChip.setLogic((ChipsManager.CHIPS[chipData.name]).logic);\n\t\t\t\tnewChip.update();\n\n\t\t\t\tcircuit.chips.push(newChip);\n\t\t\t});\n\n\t\t\t// Load wires\n\t\t\tdata.wires?.forEach((wireData) => {\n\t\t\t\tconst inputPin = pins[wireData.inputId];\n\t\t\t\tconst outputPin = pins[wireData.outputId];\n\t\t\t\tconst anchorPoints = wireData.anchorPoints as Vector2[] ?? [];\n\n\t\t\t\tconst newWire = new Wire(circuit, wireData.color, inputPin, outputPin, anchorPoints);\n\t\t\t\tinputPin?.addOutputWire(newWire);\n\t\t\t\tcircuit.wires.push(newWire);\n\t\t\t});\n\t\t}).catch((error) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n}","import { useEffect, useRef, useState } from \"react\";\r\nimport styles from \"./CircuitView.module.css\";\r\nimport { App, ClickAction, DropdownAction, HeaderMenu, openUrl, useAppFolder } from \"@prozilla-os/core\";\r\nimport { Circuit } from \"../core/circuit\";\r\nimport { ChipsManager } from \"../core/chips/chipsManager\";\r\n\r\ninterface CircuitViewProps {\r\n\tapp?: App;\r\n}\r\n\r\nexport function CircuitView({ app }: CircuitViewProps) {\r\n\tconst virtualFolder = useAppFolder(app);\r\n\tconst [circuit] = useState(new Circuit(\"Chip\", \"#000\", 2, 1));\r\n\tconst canvasRef = useRef(null);\r\n\r\n\tuseEffect(() => {\r\n\t\tif (canvasRef.current == null && circuit.canvas != null)\r\n\t\t\treturn;\r\n\r\n\t\tcircuit.init(canvasRef.current as unknown as HTMLCanvasElement);\r\n\r\n\t\treturn () => {\r\n\t\t\tcircuit.cleanup();\r\n\t\t};\r\n\t}, [canvasRef, circuit]);\r\n\r\n\treturn <>\r\n\t\t<HeaderMenu>\r\n\t\t\t<DropdownAction label=\"Circuit\" showOnHover={false}>\r\n\t\t\t\t<ClickAction label=\"New\" onTrigger={() => { circuit.reset(); }}/>\r\n\t\t\t\t<ClickAction label=\"Save\" onTrigger={() => {\r\n\t\t\t\t\tif (virtualFolder != null)\r\n\t\t\t\t\t\tChipsManager.saveCircuit(circuit, virtualFolder);\r\n\t\t\t\t}}/>\r\n\t\t\t\t<ClickAction label=\"Load\" onTrigger={() => {\r\n\t\t\t\t\tif (virtualFolder != null)\r\n\t\t\t\t\t\tChipsManager.loadCircuit(circuit, virtualFolder);\r\n\t\t\t\t}}/>\r\n\t\t\t</DropdownAction>\r\n\t\t\t<DropdownAction label=\"Add\" showOnHover={false}>\r\n\t\t\t\t<ClickAction label=\"AND gate\" onTrigger={() => {\r\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.AND);\r\n\t\t\t\t}}/>\r\n\t\t\t\t<ClickAction label=\"NOT gate\" onTrigger={() => {\r\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.NOT);\r\n\t\t\t\t}}/>\r\n\t\t\t</DropdownAction>\r\n\t\t\t<DropdownAction label=\"Help\" showOnHover={false}>\r\n\t\t\t\t<ClickAction label=\"Digital Electronics Glossary\" onTrigger={() => {\r\n\t\t\t\t\topenUrl(\"http://www.pmcgibbon.net/teachcte/electron/degloss1.htm\");\r\n\t\t\t\t}}/>\r\n\t\t\t</DropdownAction>\r\n\t\t</HeaderMenu>\r\n\t\t<div className={styles.CircuitView}>\r\n\t\t\t<canvas ref={canvasRef} className={styles.Canvas}/>\r\n\t\t</div>\r\n\t</>;\r\n}","import { WindowProps } from \"@prozilla-os/core\";\r\nimport { CircuitView } from \"./CircuitView\";\r\nimport styles from \"./LogicSim.module.css\";\r\n\r\nexport function LogicSim({ app }: WindowProps) {\r\n\treturn <div className={styles.LogicSim}>\r\n\t\t<CircuitView app={app}/>\r\n\t</div>;\r\n}","import { App } from \"@prozilla-os/core\";\nimport { LogicSim } from \"./components/LogicSim\";\n\nconst logicSim = new App(\"Logic Sim\", \"logic-sim\", LogicSim)\n\t.setIconUrl(\"https://os.prozilla.dev/assets/apps/icons/logic-sim.svg\")\n\t.setPinnedByDefault(false)\n\t.setCategory(\"Education\");\nlogicSim.setMetadata({ name: \"@prozilla-os/logic-sim\", version: \"1.1.12\", author: \"Prozilla\" });\n\n\nexport { logicSim };"],"names":["_State","value","__publicField","state","State","CURSORS","FONT","BACKGROUND","CONTROLLER","WIRE","PIN","CHIP","COLORS","Pin","circuit","name","isInput","attachedChip","id","Vector2","wire","_a","isPlacing","color","positionX","leftAligned","textRect","backgroundSize","Chip","isBlueprint","inputCount","outputCount","width","minHeight","i","newPin","pin","logic","inputStates","outputStates","reposition","index","gap","isPlacingPin","object","ControlledPin","size","positionY","rect","Wire","inputPin","outputPin","anchorPoints","positions","InputHandler","event","isHoveringPinHandle","top","bottom","invalidPlacement","eventComplete","chip","hoveringPin","isInputPin","anchorPoint","lastAnchorPoint","previousAnchorPoint","closestPositionX","closestDistance","point","distance","pins","closestPositionY","anchorCount","_b","_c","_d","_f","_e","deltaX","deltaY","correctPlacement","newChip","Circuit","canvas","entries","target","key","content","metrics","height","style","sizeX","sizeY","radius","resolution","drawPoints","targetPoint","targetDir","distanceToTarget","distanceToCurveStart","nextTargetDir","nextLineLength","curveStartPoint","curveEndPoint","j","t","a","b","p","align","alpha","clamp","margin","padding","offset","isPlacingWire","isPlacingChip","json","_ChipsManager","virtualFolder","file","virtualFile","data","pinData","chipData","wireData","newWire","error","ChipsManager","CircuitView","app","useAppFolder","useState","canvasRef","useRef","useEffect","jsxs","Fragment","HeaderMenu","DropdownAction","jsx","ClickAction","openUrl","styles","LogicSim","logicSim","App"],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sources":["../src/core/_utils/state.ts","../src/constants/logicSim.const.ts","../src/core/pins/pin.ts","../src/core/chips/chip.ts","../src/core/pins/controlledPin.ts","../src/core/wires/wire.ts","../src/core/inputHandler.ts","../src/core/circuit.ts","../src/core/chips/chipsManager.ts","../src/components/CircuitView.tsx","../src/components/LogicSim.tsx","../src/main.ts"],"sourcesContent":["export class State {\r\n\tvalue: number;\r\n\r\n\tstatic LOW = new State(0);\r\n\tstatic HIGH = new State(1);\r\n\r\n\tconstructor(value: number) {\r\n\t\tthis.value = value;\r\n\t}\r\n\r\n\tstatic invert(state: State) {\r\n\t\treturn new State(1 - state.value);\r\n\t}\r\n\r\n\tisEqual(state: State) {\r\n\t\treturn this.value === state.value;\r\n\t}\r\n}","export const CURSORS = {\n\tdefault: \"default\",\n\tpointer: \"pointer\",\n};\n\nexport const FONT = \"outfit\";\nexport const ENABLE_COLOR_CACHING = true;\nexport const VIRTUAL_PATH = \"~/Apps/logic-sim/\";\n\nexport const BACKGROUND = {\n\tpadding: 30,\n\tborderWidth: 7.5,\n};\n\nexport const CONTROLLER = {\n\tradius: 25,\n\tborderWidth: 5,\n\tpinOffset: 42.5,\n\tconnectorWidth: 7.5,\n\thandleWidth: 15,\n\thandleTrackWidth: 22.5,\n\tplacingOpacity: 0.5,\n};\n\nexport const WIRE = {\n\twidth: 5,\n\tsnappingSensitivity: 10,\n\tcornerRadius: 25,\n\tresolution: 8,\n};\n\nexport const PIN = {\n\tradius: 10,\n\tlabel: {\n\t\toffset: 10,\n\t\tfontSize: 15,\n\t\tpadding: 5,\n\t},\n};\n\nexport const CHIP = {\n\tBorderWidth: 5,\n\tpadding: 10,\n\tfontSize: 35,\n\tplacingOutline: 10,\n};\n\nexport const COLORS = {\n\tpin: {\n\t\tfill: \"black-4\",\n\t\tfillHover: \"black-3\",\n\t\tlabelText: \"white-0\",\n\t\tlabelBackground: \"black-4\",\n\t},\n\tcontroller: {\n\t\tstroke: \"black-4\",\n\t\tconnector: \"black-4\",\n\t\ton: \"red-0\",\n\t\toff: \"red-2\",\n\t\thover: \"white-0\",\n\t\thandle: \"black-3\",\n\t\thandleHover: \"black-4\",\n\t},\n\tbackground: {\n\t\tborder: \"black-0\",\n\t\touter: \"black-1\",\n\t\tinner: \"black-2\",\n\t\tmargin: \"black-2\",\n\t},\n\twire: {\n\t\tplacing: \"black-1\",\n\t},\n\tchip: {\n\t\ttext: \"black-4\",\n\t\toutline: \"white-0\",\n\t},\n};","import { Vector2 } from \"@prozilla-os/core\";\nimport { Chip } from \"../chips/chip\";\nimport { Circuit } from \"../circuit\";\nimport { State } from \"../_utils/state\";\nimport { Wire } from \"../wires/wire\";\nimport { COLORS, CONTROLLER, CURSORS, PIN } from \"../../constants/logicSim.const\";\n\nexport interface PinJson {\n\tname: string;\n\tid: number;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n}\n\nexport class Pin {\n\tid: number;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tattachedChip!: Chip;\n\tcircuit!: Circuit;\n\n\tstate = State.LOW;\n\tisInput!: boolean;\n\tisControlled: boolean = false;\n\toutputWires: Wire[] = [];\n\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, attachedChip: Chip, id?: number) {\n\t\tObject.assign(this, { circuit, name, isInput, attachedChip });\n\t\tthis.id = id ?? this.circuit.getUniqueId();\n\t}\n\n\taddOutputWire(wire: Wire) {\n\t\tthis.outputWires.push(wire);\n\t\twire.setState(this.state);\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\t// TO DO: clean this mess\n\t\tthis.outputWires.forEach((wire) => {\n\t\t\twire.setState(this.state);\n\t\t});\n\t\tthis.attachedChip?.update();\n\t}\n\n\tget isPointingRight() {\n\t\treturn this.isInput === this.isControlled;\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tlet color = COLORS.pin.fill;\n\n\t\tif (this.circuit.inputHandler.mousePosition.getDistance(this.position.x, this.position.y) <= PIN.radius) {\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t\tcolor = COLORS.pin.fillHover;\n\n\t\t\t// Draw label\n\t\t\tlet positionX = this.position.x;\n\t\t\tconst leftAligned = this.isPointingRight;\n\t\t\tconst textRect = this.circuit.getTextRect(PIN.label.fontSize, this.name);\n\n\t\t\tif (leftAligned) {\n\t\t\t\tpositionX += PIN.radius + PIN.label.offset;\n\t\t\t} else {\n\t\t\t\tpositionX -= PIN.radius + PIN.label.offset;\n\t\t\t}\n\n\t\t\tconst backgroundSize = {\n\t\t\t\tx: textRect.x + PIN.label.padding * 2,\n\t\t\t\ty: textRect.y + PIN.label.padding * 2,\n\t\t\t};\n\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelBackground),\n\t\t\t\tleftAligned ? positionX : positionX - backgroundSize.x, this.position.y - textRect.y / 2 - PIN.label.padding,\n\t\t\t\tbackgroundSize.x, backgroundSize.y\n\t\t\t);\n\n\t\t\tif (leftAligned) {\n\t\t\t\tpositionX += PIN.label.padding;\n\t\t\t} else {\n\t\t\t\tpositionX -= PIN.label.padding;\n\t\t\t}\n\n\t\t\tthis.circuit.drawText(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelText),\n\t\t\t\tleftAligned ? \"left\" : \"right\",\n\t\t\t\tpositionX, this.position.y,\n\t\t\t\tPIN.label.fontSize,\n\t\t\t\tthis.name\n\t\t\t);\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tthis.position.x, this.position.y,\n\t\t\tPIN.radius\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\ttoJson(): PinJson {\n\t\tconst object = {\n\t\t\tname: this.name,\n\t\t\tid: this.id,\n\t\t\tposition: this.position,\n\t\t} as PinJson;\n\n\t\treturn object;\n\t}\n}","import { Circuit } from \"../circuit\";\nimport { Pin, PinJson } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { Vector2 } from \"@prozilla-os/core\";\nimport { CHIP, COLORS, PIN } from \"../../constants/logicSim.const\";\n\nexport interface ChipJson {\n\tcolor: string;\n\tname: string;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tinputPins: PinJson[];\n\toutputPins: PinJson[];\n}\n\nexport class Chip {\n\tcolor!: string;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tsize!: Vector2;\n\tcircuit!: Circuit;\n\tisCircuit = false;\n\tisBlueprint = false;\n\n\tinputCount = 0;\n\toutputCount = 0;\n\tinputPins!: Pin[];\n\toutputPins!: Pin[];\n\tlogic!: (inputStates: State[]) => State[];\n\n\tconstructor(circuit: Circuit | null, name: string, color: string, isBlueprint: boolean, inputCount: number, outputCount: number) {\n\t\tObject.assign(this, { circuit, name, color, isBlueprint, inputCount, outputCount });\n\n\t\tif (this.circuit == null && !isBlueprint) {\n\t\t\tthis.circuit = this as unknown as Circuit;\n\t\t\tthis.isCircuit = true;\n\t\t}\n\n\t\tif (this.isCircuit || this.isBlueprint)\n\t\t\treturn;\n\n\n\t\tif (this.circuit != null) {\n\t\t\tconst textRect = this.circuit.getTextRect(CHIP.fontSize, this.name);\n\n\t\t\tconst width = textRect.x + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\t\tconst minHeight = textRect.y + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\n\t\t\tthis.size = new Vector2(width, minHeight);\n\t\t}\n\n\t\tthis.inputPins = [];\n\t\tfor (let i = 0; i < inputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"IN \" + i, true, this);\n\t\t\tthis.inputPins.push(newPin);\n\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\n\t\tthis.outputPins = [];\n\t\tfor (let i = 0; i < outputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"OUT \" + i, false, this);\n\t\t\tthis.outputPins.push(newPin);\n\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\t}\n\n\tsetCircuit(circuit: Circuit) {\n\t\tthis.circuit = circuit;\n\n\t\tthis.inputPins.concat(this.outputPins).forEach((pin) => { pin.circuit = circuit; });\n\t}\n\n\tsetLogic(logic: (inputStates: State[]) => State[]) {\n\t\tthis.logic = logic;\n\t\treturn this;\n\t}\n\n\tupdate() {\n\t\tif (this.logic == null)\n\t\t\treturn;\n\n\t\tconst inputStates: State[] = [];\n\t\tfor (let i = 0; i < this.inputCount; i++) {\n\t\t\tconst state = this.inputPins[i].state ?? State.LOW;\n\t\t\tinputStates.push(state);\n\t\t}\n\n\t\tconst outputStates: State[] = this.logic(inputStates);\n\n\t\tfor (let i = 0; i < this.outputCount; i++) {\n\t\t\tthis.outputPins[i].setState(outputStates[i]);\n\t\t}\n\t}\n\n\tdrawPins(reposition = true) {\n\t\tthis.inputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.inputCount * PIN.radius * 2) / (this.inputCount + 1);\n\t\t\t\tpin.position.x = this.position.x;\n\t\t\t\tpin.position.y = this.position.y + gap * (index + 1) + PIN.radius * (2 * index + 1);\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\n\t\tthis.outputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.outputCount * PIN.radius * 2) / (this.outputCount + 1);\n\t\t\t\tpin.position.x = this.position.x + this.size.x;\n\t\t\t\tpin.position.y = this.position.y + gap * (index + 1) + PIN.radius * (2 * index + 1);\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-1\"),\n\t\t\tthis.position.x, this.position.y,\n\t\t\tthis.size.x, this.size.y\n\t\t);\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-0\"),\n\t\t\tthis.position.x + CHIP.BorderWidth, this.position.y + CHIP.BorderWidth,\n\t\t\tthis.size.x - CHIP.BorderWidth * 2, this.size.y - CHIP.BorderWidth * 2\n\t\t);\n\n\t\tthis.circuit.drawText(\n\t\t\tthis.circuit.getColor(COLORS.chip.text),\n\t\t\t\"center\",\n\t\t\tthis.position.x + this.size.x / 2, this.position.y + this.size.y / 2,\n\t\t\tCHIP.fontSize,\n\t\t\tthis.name\n\t\t);\n\n\t\tif (isPlacing) {\n\t\t\tthis.circuit.setDrawingOpacity(0.25);\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.chip.outline),\n\t\t\t\tthis.position.x - CHIP.placingOutline, this.position.y - CHIP.placingOutline,\n\t\t\t\tthis.size.x + CHIP.placingOutline * 2, this.size.y + CHIP.placingOutline * 2\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t}\n\n\t\tthis.drawPins();\n\t}\n\n\ttoJson(): ChipJson {\n\t\tconst object = {\n\t\t\tcolor: this.color,\n\t\t\tname: this.name,\n\t\t\tposition: {\n\t\t\t\tx: this.position.x,\n\t\t\t\ty: this.position.y,\n\t\t\t},\n\t\t} as ChipJson;\n\n\t\tif (this.inputPins.length > 0)\n\t\t\tobject.inputPins = this.inputPins.map((pin) => pin.toJson());\n\n\t\tif (this.outputPins.length > 0)\n\t\t\tobject.outputPins = this.outputPins.map((pin) => pin.toJson());\n\n\t\treturn object;\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"./pin\";\nimport { COLORS, CONTROLLER, CURSORS } from \"../../constants/logicSim.const\";\n\nexport class ControlledPin extends Pin {\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, id?: number) {\n\t\tsuper(circuit, name, isInput, circuit, id);\n\t\tthis.isControlled = true;\n\t}\n\n\tdrawControllerHandle(isPlacing: boolean) {\n\t\tconst size = { x: CONTROLLER.handleWidth, y: CONTROLLER.radius * 2 };\n\n\t\tlet positionX = this.position.x;\n\t\tconst positionY = this.position.y - size.y / 2;\n\n\n\t\tif (this.isInput) {\n\t\t\tpositionX -= CONTROLLER.pinOffset + CONTROLLER.handleTrackWidth + CONTROLLER.radius;\n\t\t} else {\n\t\t\tpositionX += CONTROLLER.pinOffset + (CONTROLLER.handleTrackWidth - CONTROLLER.handleWidth) + CONTROLLER.radius;\n\t\t}\n\n\t\tconst rect = {\n\t\t\tposition: { x: positionX, y: positionY } as Vector2,\n\t\t\tsize: { x: size.x, y: size.y } as Vector2,\n\t\t};\n\n\t\tlet color: string;\n\n\t\tif (this.circuit.isPointInsideRect(rect, this.circuit.inputHandler.mousePosition)) {\n\t\t\tcolor = COLORS.controller.handleHover;\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.handle;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(color),\n\t\t\trect.position.x, rect.position.y,\n\t\t\trect.size.x, rect.size.y\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawController(isPlacing: boolean) {\n\t\tconst positionX = this.isInput ? this.position.x - CONTROLLER.pinOffset : this.position.x + CONTROLLER.pinOffset;\n\t\tconst positionY = this.position.y;\n\n\t\tlet color: string;\n\n\t\tif (this.state.value === 1) {\n\t\t\tcolor = COLORS.controller.on;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.off;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(COLORS.controller.stroke),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius\n\t\t);\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t);\n\n\t\tconst isInteractable = this.isInput && this.isControlled && !isPlacing;\n\t\tif (isInteractable && this.circuit.inputHandler.mousePosition.getDistance(positionX, positionY) <= CONTROLLER.radius) {\n\t\t\tthis.circuit.setDrawingOpacity(0.125);\n\t\t\tthis.circuit.drawCircle(\n\t\t\t\tthis.circuit.getColor(COLORS.controller.hover),\n\t\t\t\tpositionX, positionY,\n\t\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawConnector(isPlacing: boolean) {\n\t\tif (isPlacing)\n\t\t\treturn;\n\n\t\tconst positionX = this.isInput ? this.position.x - CONTROLLER.pinOffset : this.position.x;\n\t\tconst positionY = this.position.y;\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(COLORS.controller.connector),\n\t\t\tpositionX, positionY - CONTROLLER.connectorWidth / 2,\n\t\t\tCONTROLLER.pinOffset, CONTROLLER.connectorWidth\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tthis.drawConnector(isPlacing);\n\t\tthis.drawController(isPlacing);\n\t\tthis.drawControllerHandle(isPlacing);\n\n\t\tsuper.draw(isPlacing);\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { WIRE } from \"../../constants/logicSim.const\";\n\nexport interface WireJson {\n\tcolor: string;\n\tinputId: number;\n\toutputId: number;\n\tanchorPoints: {\n\t\tx: number;\n\t\ty: number;\n\t}[];\n}\n\nexport class Wire {\n\tcolor!: string;\n\tstate = State.LOW;\n\tinputPin!: Pin;\n\toutputPin!: Pin;\n\tanchorPoints!: Vector2[];\n\tcircuit!: Circuit;\n\tplacedBackwards = false;\n\n\tconstructor(circuit: Circuit, color: string, inputPin?: Pin, outputPin?: Pin, anchorPoints?: Vector2[]) {\n\t\tObject.assign(this, { circuit, color, inputPin, outputPin, anchorPoints });\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\tif (this.outputPin == null)\n\t\t\treturn;\n\n\t\tthis.outputPin.setState(this.state);\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tconst positions = [...this.anchorPoints];\n\n\t\tif (this.inputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.unshift(this.inputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.push(this.inputPin.position);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (this.outputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.push(this.outputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.unshift(this.outputPin.position);\n\t\t\t}\n\t\t}\n\n\t\tlet color: string;\n\n\t\tif (isPlacing) {\n\t\t\tcolor = `${this.color}-2`;\n\t\t} else if (this.state.value === 1) {\n\t\t\tcolor = `${this.color}-0`;\n\t\t} else {\n\t\t\tcolor = `${this.color}-2`;\n\t\t}\n\n\t\tthis.circuit.drawCurvedLine(this.circuit.getColor(color), positions, WIRE.width, WIRE.cornerRadius, WIRE.resolution);\n\t}\n\n\ttoJson() {\n\t\tconst object = {\n\t\t\tcolor: this.color,\n\t\t} as WireJson;\n\n\t\tif (this.inputPin != null)\n\t\t\tobject.inputId = this.inputPin.id;\n\n\t\tif (this.outputPin != null)\n\t\t\tobject.outputId = this.outputPin.id;\n\n\t\tif (this.anchorPoints != null)\n\t\t\tobject.anchorPoints = this.anchorPoints;\n\n\t\treturn object;\n\t}\n}","import { Chip } from \"./chips/chip\";\r\nimport { Circuit } from \"./circuit\";\r\nimport { ControlledPin } from \"./pins/controlledPin\";\r\nimport { Pin } from \"./pins/pin\";\r\nimport { State } from \"./_utils/state\";\r\nimport { Wire } from \"./wires/wire\";\r\nimport { Vector2 } from \"@prozilla-os/core\";\r\nimport { CONTROLLER, PIN, WIRE } from \"../constants/logicSim.const\";\r\n\r\nexport class InputHandler {\r\n\tcircuit!: Circuit;\r\n\tcanvas!: HTMLCanvasElement;\r\n\r\n\tmousePosition = Vector2.ZERO;\r\n\r\n\tisPlacing = false;\r\n\tsnapping = false;\r\n\tplacingOffset = Vector2.ZERO;\r\n\tpreviousPlacement!: Vector2 | null;\r\n\tplacingWire!: Wire | null;\r\n\tplacingChip!: Chip | null;\r\n\tplacingPin!: ControlledPin | null;\r\n\r\n\tconstructor(circuit: Circuit) {\r\n\t\tObject.assign(this, { circuit });\r\n\t}\r\n\r\n\tsetMousePosition(event: MouseEvent) {\r\n\t\tconst rect = this.canvas.getBoundingClientRect();\r\n\t\tthis.mousePosition.x = event.clientX - rect.left;\r\n\t\tthis.mousePosition.y = event.clientY - rect.top;\r\n\t}\r\n\r\n\tinit() {\r\n\t\tthis.canvas = this.circuit.canvas;\r\n\t\tthis.mousePosition = Vector2.ZERO;\r\n\r\n\t\t// TO DO: add support for touch devices\r\n\r\n\t\tthis.canvas.addEventListener(\"mousemove\", this.onMouseMove);\r\n\t\tthis.canvas.addEventListener(\"mouseup\", this.onMouseUp);\r\n\t\tthis.canvas.addEventListener(\"contextmenu\", this.onMouseUp);\r\n\t\tthis.canvas.addEventListener(\"mousedown\", this.onMouseDown);\r\n\r\n\t\twindow.addEventListener(\"keydown\", this.onKeyDown);\r\n\t\twindow.addEventListener(\"keyup\", this.onKeyUp);\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\tthis.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\r\n\t\tthis.canvas.removeEventListener(\"mouseup\", this.onMouseUp);\r\n\t\tthis.canvas.removeEventListener(\"contextmenu\", this.onMouseUp);\r\n\t\tthis.canvas.removeEventListener(\"mousedown\", this.onMouseDown);\r\n\r\n\t\twindow.removeEventListener(\"keydown\", this.onKeyDown);\r\n\t\twindow.removeEventListener(\"keyup\", this.onKeyUp);\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.placingWire = null;\r\n\t\tthis.placingChip = null;\r\n\t\tthis.placingPin = null;\r\n\t\tthis.previousPlacement = null;\r\n\t\tthis.placingOffset = Vector2.ZERO;\r\n\t\tthis.isPlacing = false;\r\n\t}\r\n\r\n\tonMouseMove = (event?: MouseEvent) => {\r\n\t\tif (event != null)\r\n\t\t\tthis.setMousePosition(event);\r\n\r\n\t\tif (this.placingWire != null) {\r\n\t\t\tthis.updateWirePlacement();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (this.placingChip != null) {\r\n\t\t\tthis.updateChipPlacement();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst isHoveringPinHandle = (pin: ControlledPin) => {\r\n\t\t\tconst top = pin.position.y - CONTROLLER.radius;\r\n\t\t\tconst bottom = pin.position.y + CONTROLLER.radius;\r\n\r\n\t\t\treturn (this.mousePosition.y > top && this.mousePosition.y < bottom);\r\n\t\t};\r\n\r\n\t\tif (this.placingPin != null) {\r\n\t\t\tlet invalidPlacement = this.mousePosition.x > CONTROLLER.handleTrackWidth && this.mousePosition.x < this.circuit.size.x - CONTROLLER.handleTrackWidth;\r\n\r\n\t\t\tif (invalidPlacement) {\r\n\t\t\t\tthis.cancelPinPlacement();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (this.placingPin.isInput) {\r\n\t\t\t\tthis.circuit.inputPins.forEach((pin, index) => {\r\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.inputPins.length - 1)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\tthis.circuit.outputPins.forEach((pin, index) => {\r\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.outputPins.length - 1)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\tif (invalidPlacement) {\r\n\t\t\t\tthis.cancelPinPlacement();\r\n\t\t\t} else {\r\n\t\t\t\tthis.updatePinPlacement();\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (this.mousePosition.x < CONTROLLER.handleTrackWidth) {\r\n\t\t\t\tlet invalidPlacement = false;\r\n\r\n\t\t\t\tthis.circuit.inputPins.forEach((pin) => {\r\n\t\t\t\t\tif (invalidPlacement)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!invalidPlacement)\r\n\t\t\t\t\tthis.startPinPlacement(true);\r\n\t\t\t} else if (this.mousePosition.x > this.circuit.size.x - CONTROLLER.handleTrackWidth) {\r\n\t\t\t\tlet invalidPlacement = false;\r\n\r\n\t\t\t\tthis.circuit.outputPins.forEach((pin) => {\r\n\t\t\t\t\tif (invalidPlacement)\r\n\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\tif (isHoveringPinHandle(pin))\r\n\t\t\t\t\t\tinvalidPlacement = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!invalidPlacement)\r\n\t\t\t\t\tthis.startPinPlacement(false);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\tonClickPin(pin: Pin) {\r\n\t\tif (this.placingWire != null) {\r\n\t\t\tthis.endWirePlacement(pin);\r\n\t\t} else {\r\n\t\t\tthis.startWirePlacement(pin);\r\n\t\t}\r\n\t}\r\n\r\n\tonMouseUp = (event: MouseEvent) => {\r\n\t\tevent.preventDefault();\r\n\t\tthis.setMousePosition(event);\r\n\r\n\t\tif (event.button === 2) {\r\n\t\t\tif (this.placingWire != null)\r\n\t\t\t\tthis.cancelWirePlacement();\r\n\t\t\tif (this.placingChip != null)\r\n\t\t\t\tthis.cancelChipPlacement();\r\n\t\t} else if (event.button === 0) {\r\n\t\t\tlet eventComplete = false;\r\n\r\n\t\t\tthis.circuit.inputPins.forEach((pin: Pin) => {\r\n\t\t\t\tif (this.mousePosition.getDistance(pin.position.x - CONTROLLER.pinOffset, pin.position.y) <= CONTROLLER.radius) {\r\n\t\t\t\t\tpin.setState(State.invert(pin.state));\r\n\t\t\t\t\teventComplete = true;\r\n\t\t\t\t} else if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\r\n\t\t\t\t\tthis.onClickPin(pin);\r\n\t\t\t\t\teventComplete = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\r\n\t\t\tif (eventComplete)\r\n\t\t\t\treturn;\r\n\t\r\n\t\t\tthis.circuit.outputPins.forEach((pin: Pin) => {\r\n\t\t\t\tif (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\r\n\t\t\t\t\tthis.onClickPin(pin);\r\n\t\t\t\t\teventComplete = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\r\n\t\t\tif (eventComplete)\r\n\t\t\t\treturn;\r\n\r\n\t\t\tthis.circuit.chips.forEach((chip) => {\r\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\r\n\t\t\t\t\tif (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\r\n\t\t\t\t\t\tthis.onClickPin(pin);\r\n\t\t\t\t\t\teventComplete = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\tif (eventComplete)\r\n\t\t\t\treturn;\r\n\t\r\n\t\t\tif (this.placingWire != null)\r\n\t\t\t\tthis.anchorWirePlacement();\r\n\r\n\t\t\tif (this.placingChip != null)\r\n\t\t\t\tthis.endChipPlacement();\r\n\r\n\t\t\tif (this.placingPin != null)\r\n\t\t\t\tthis.endPinPlacement();\r\n\t\t}\r\n\t};\r\n\r\n\tonMouseDown = (event: MouseEvent) => {\r\n\t\tevent.preventDefault();\r\n\t\tthis.setMousePosition(event);\r\n\r\n\t\tif (event.button !== 0 || this.isPlacing)\r\n\t\t\treturn;\r\n\r\n\t\tthis.circuit.chips.forEach((chip, index) => {\r\n\t\t\tif (!this.isPlacing && this.circuit.isPointInsideRect(chip, this.mousePosition)) {\r\n\t\t\t\tlet hoveringPin = false;\r\n\r\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\r\n\t\t\t\t\tif (pin.position.getDistance(this.mousePosition.x, this.mousePosition.y) <= PIN.radius)\r\n\t\t\t\t\t\thoveringPin = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!hoveringPin)\r\n\t\t\t\t\tthis.editChipPlacement(chip, index);\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\tonKeyDown = (event: KeyboardEvent) => {\r\n\t\tswitch (event.key) {\r\n\t\t\tcase \"Shift\":\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tthis.snapping = true;\r\n\t\t\t\tthis.onMouseMove();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Backspace\":\r\n\t\t\tcase \"Delete\":\r\n\t\t\tcase \"Escape\":\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tif (this.placingWire != null)\r\n\t\t\t\t\tthis.cancelWirePlacement();\r\n\t\t\t\tif (this.placingChip != null)\r\n\t\t\t\t\tthis.cancelChipPlacement();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\tonKeyUp = (event: KeyboardEvent) => {\r\n\t\tswitch (event.key) {\r\n\t\t\tcase \"Shift\":\r\n\t\t\t\tevent.preventDefault();\r\n\t\t\t\tthis.snapping = false;\r\n\t\t\t\tthis.onMouseMove();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\tstartWirePlacement(pin: Pin) {\r\n\t\tconst isInputPin = pin.isPointingRight;\r\n\r\n\t\t// Start wire placement\r\n\t\tconst inputPin = isInputPin ? pin : undefined;\r\n\t\tconst outputPin = !isInputPin ? pin : undefined;\r\n\t\tconst anchorPoint = this.mousePosition.clone;\r\n\r\n\t\tthis.placingWire = new Wire(this.circuit, \"red\", inputPin, outputPin, [anchorPoint]);\r\n\r\n\t\tif (!isInputPin)\r\n\t\t\tthis.placingWire.placedBackwards = true;\r\n\r\n\t\tthis.circuit.wires.push(this.placingWire);\r\n\t}\r\n\r\n\tsnapWireHorizontally(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\r\n\t\tlastAnchorPoint.x = this.mousePosition.x;\r\n\t\tlastAnchorPoint.y = previousAnchorPoint.y;\r\n\r\n\t\t// Snapping horizontal wire to other wires\r\n\t\tlet anchorPoints: Vector2[] = [];\r\n\r\n\t\tthis.circuit.wires.forEach((wire, index) => {\r\n\t\t\tif (index < this.circuit.wires.length - 1)\r\n\t\t\t\tanchorPoints = anchorPoints.concat(wire.anchorPoints);\r\n\t\t});\r\n\r\n\t\tlet closestPositionX: number | undefined;\r\n\t\tlet closestDistance: number | undefined;\r\n\r\n\t\tanchorPoints.forEach((point) => {\r\n\t\t\tconst distance = Math.abs(this.mousePosition.x - point.x);\r\n\r\n\t\t\tif (closestDistance == null || closestDistance > distance) {\r\n\t\t\t\tclosestPositionX = point.x;\r\n\t\t\t\tclosestDistance = distance;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (closestDistance != null && closestPositionX != null && closestDistance < WIRE.snappingSensitivity)\r\n\t\t\tlastAnchorPoint.x = closestPositionX;\r\n\t}\r\n\r\n\tsnapWireVertically(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\r\n\t\tlastAnchorPoint.x = previousAnchorPoint.x;\r\n\t\tlastAnchorPoint.y = this.mousePosition.y;\r\n\r\n\t\t// Snapping vertical wire to pins\r\n\t\tlet pins: Pin[];\r\n\r\n\t\tif (!this.placingWire?.placedBackwards) {\r\n\t\t\tpins = this.circuit.outputPins;\r\n\r\n\t\t\tthis.circuit.chips.forEach((chip) => {\r\n\t\t\t\tpins = pins.concat(chip.inputPins);\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\tpins = this.circuit.inputPins;\r\n\r\n\t\t\tthis.circuit.chips.forEach((chip) => {\r\n\t\t\t\tpins = pins.concat(chip.outputPins);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tlet closestPositionY: number | undefined;\r\n\t\tlet closestDistance: number | undefined;\r\n\r\n\t\tpins.forEach((pin) => {\r\n\t\t\tconst distance = Math.abs(this.mousePosition.y - pin.position.y);\r\n\r\n\t\t\tif (closestDistance == null || closestDistance > distance) {\r\n\t\t\t\tclosestPositionY = pin.position.y;\r\n\t\t\t\tclosestDistance = distance;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (closestDistance != null && closestPositionY != null && closestDistance < WIRE.snappingSensitivity)\r\n\t\t\tlastAnchorPoint.y = closestPositionY;\r\n\t}\r\n\r\n\tupdateWirePlacement() {\r\n\t\tconst anchorCount = this.placingWire?.anchorPoints.length;\r\n\t\tif (anchorCount == null) return;\r\n\t\tconst lastAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 1];\r\n\t\tif (lastAnchorPoint == null) return;\r\n\r\n\t\tif (!this.snapping) {\r\n\t\t\tlastAnchorPoint.x = this.mousePosition.x;\r\n\t\t\tlastAnchorPoint.y = this.mousePosition.y;\r\n\t\t} else {\r\n\t\t\t// Wire snapping\r\n\t\t\tlet previousAnchorPoint: Vector2 | undefined;\r\n\r\n\t\t\tif (anchorCount >= 2) {\r\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 2];\r\n\t\t\t} else if (!this.placingWire?.placedBackwards) {\r\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.inputPin.position;\r\n\t\t\t} else {\r\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.outputPin.position;\r\n\t\t\t}\r\n\r\n\t\t\tif (previousAnchorPoint == null) return;\r\n\t\r\n\t\t\tconst deltaX = Math.abs(this.mousePosition.x - previousAnchorPoint.x);\r\n\t\t\tconst deltaY = Math.abs(this.mousePosition.y - previousAnchorPoint.y);\r\n\t\r\n\t\t\tif (deltaX > deltaY) {\r\n\t\t\t\tthis.snapWireHorizontally(lastAnchorPoint, previousAnchorPoint);\r\n\t\t\t} else {\r\n\t\t\t\tthis.snapWireVertically(lastAnchorPoint, previousAnchorPoint);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tanchorWirePlacement() {\r\n\t\tthis.placingWire?.anchorPoints.push(this.mousePosition.clone);\r\n\t}\r\n\r\n\tcancelWirePlacement() {\r\n\t\tthis.placingWire = null;\r\n\t\tthis.isPlacing = false;\r\n\t\tthis.circuit.wires.pop();\r\n\t}\r\n\r\n\tendWirePlacement(pin: Pin) {\r\n\t\tconst isInputPin = pin.isPointingRight;\r\n\r\n\t\tif (this.placingWire == null) return;\r\n\r\n\t\tlet correctPlacement = false;\r\n\t\tif (!isInputPin && !this.placingWire.placedBackwards) {\r\n\t\t\tthis.placingWire.outputPin = pin;\r\n\t\t\tcorrectPlacement = true;\r\n\t\t} else if (isInputPin && this.placingWire.placedBackwards) {\r\n\t\t\tthis.placingWire.inputPin = pin;\r\n\t\t\tcorrectPlacement = true;\r\n\t\t}\r\n\r\n\t\tif (correctPlacement) {\r\n\t\t\tthis.placingWire.anchorPoints.pop();\r\n\t\t\tthis.placingWire.inputPin.addOutputWire(this.placingWire);\r\n\t\t\tthis.placingWire.inputPin.update();\r\n\r\n\t\t\tthis.placingWire = null;\r\n\t\t\tthis.isPlacing = false;\r\n\t\t}\r\n\t}\r\n\r\n\tstartChipPlacement(chip: Chip) {\r\n\t\tconst newChip = new Chip(this.circuit, chip.name, chip.color, false, chip.inputCount, chip.outputCount);\r\n\t\tnewChip.setLogic(chip.logic);\r\n\t\tnewChip.position = new Vector2(\r\n\t\t\tthis.mousePosition.x - newChip.size.x / 2,\r\n\t\t\tthis.mousePosition.y - newChip.size.y / 2\r\n\t\t);\r\n\r\n\t\tthis.placingChip = newChip;\r\n\t\tthis.isPlacing = true;\r\n\t\tthis.circuit.chips.push(newChip);\r\n\t}\r\n\r\n\teditChipPlacement(chip: Chip, index: number) {\r\n\t\tthis.placingOffset = new Vector2(\r\n\t\t\t(chip.position.x + chip.size.x / 2) - this.mousePosition.x,\r\n\t\t\t(chip.position.y + chip.size.y / 2) - this.mousePosition.y\r\n\t\t);\r\n\t\tthis.previousPlacement = chip.position.clone;\r\n\t\tthis.circuit.chips.push(this.circuit.chips.splice(index, 1)[0]);\r\n\r\n\t\tthis.placingChip = chip;\r\n\t\tthis.isPlacing = true;\r\n\t}\r\n\r\n\tupdateChipPlacement() {\r\n\t\tif (this.placingChip == null) return;\r\n\t\tthis.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2 + this.placingOffset.x;\r\n\t\tthis.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2 + this.placingOffset.y;\r\n\t}\r\n\r\n\tcancelChipPlacement() {\r\n\t\tif (this.placingChip == null) return;\r\n\r\n\t\tif (this.previousPlacement != null) {\r\n\t\t\tthis.placingChip.position = this.previousPlacement;\r\n\t\t\tthis.previousPlacement = null;\r\n\t\t} else {\r\n\t\t\tthis.circuit.chips.pop();\r\n\t\t}\r\n\r\n\t\tthis.placingChip = null;\r\n\t\tthis.isPlacing = false;\r\n\t}\r\n\r\n\tendChipPlacement() {\r\n\t\tthis.placingChip = null;\r\n\t\tthis.isPlacing = false;\r\n\t\tthis.placingOffset = Vector2.ZERO;\r\n\t}\r\n\r\n\tstartPinPlacement(isInput: boolean) {\r\n\t\tconst newPin = new ControlledPin(this.circuit, \"PIN\", isInput);\r\n\r\n\t\tnewPin.position.x = CONTROLLER.handleTrackWidth + CONTROLLER.pinOffset + CONTROLLER.radius;\r\n\t\tnewPin.position.y = this.mousePosition.y;\r\n\r\n\t\tif (isInput) {\r\n\t\t\tthis.circuit.inputPins.push(newPin);\r\n\t\t} else {\r\n\t\t\tnewPin.position.x = this.circuit.size.x - newPin.position.x;\r\n\t\t\tthis.circuit.outputPins.push(newPin);\r\n\t\t}\r\n\r\n\t\tthis.placingPin = newPin;\r\n\t}\r\n\r\n\tupdatePinPlacement() {\r\n\t\tif (this.placingPin != null)\r\n\t\t\tthis.placingPin.position.y = this.mousePosition.y;\r\n\t}\r\n\r\n\tcancelPinPlacement() {\r\n\t\tif (this.placingPin?.isInput) {\r\n\t\t \tthis.circuit.inputPins.pop();\r\n\t\t} else {\r\n\t\t\tthis.circuit.outputPins.pop();\r\n\t\t}\r\n\r\n\t\tthis.placingPin = null;\r\n\t}\r\n\r\n\tendPinPlacement() {\r\n\t\tthis.placingPin = null;\r\n\t}\r\n\r\n\tisPlacingPin(pin: Pin, index: number) {\r\n\t\tif (!pin.isControlled || this.placingPin == null || this.placingPin.isInput != pin.isInput)\r\n\t\t\treturn false;\r\n\r\n\t\tif (pin.isInput) {\r\n\t\t\treturn index == this.circuit.inputPins.length - 1;\r\n\t\t} else {\r\n\t\t\treturn index == this.circuit.outputPins.length - 1;\r\n\t\t}\r\n\t}\r\n}","import { Vector2 } from \"@prozilla-os/core\";\r\nimport { Chip, ChipJson } from \"./chips/chip\";\r\nimport { ControlledPin } from \"./pins/controlledPin\";\r\nimport { InputHandler } from \"./inputHandler\";\r\nimport { Wire, WireJson } from \"./wires/wire\";\r\nimport { BACKGROUND, COLORS, CONTROLLER, CURSORS, ENABLE_COLOR_CACHING, FONT } from \"../constants/logicSim.const\";\r\nimport { clamp } from \"@prozilla-os/shared\";\r\n\r\nexport interface CircuitJson extends ChipJson {\r\n\twires: WireJson[];\r\n\tchips: ChipJson[];\r\n}\r\n\r\nexport class Circuit extends Chip {\r\n\tcanvas!: HTMLCanvasElement;\r\n\tsize = Vector2.ZERO;\r\n\tcontext!: CanvasRenderingContext2D;\r\n\tcolors: { [key: string]: string } = {};\r\n\tinputHandler: InputHandler;\r\n\r\n\tinputPins: ControlledPin[] = [];\r\n\toutputPins: ControlledPin[] = [];\r\n\r\n\twires: Wire[] = [];\r\n\tchips: Chip[] = [];\r\n\r\n\tcursor = CURSORS.default;\r\n\r\n\tlastId = 0;\r\n\r\n\tconstructor(name: string, color: string, inputCount: number, outputCount: number) {\r\n\t\tsuper(null, name, color, false, inputCount, outputCount);\r\n\t\tthis.inputHandler = new InputHandler(this);\r\n\t}\r\n\r\n\tresize() {\r\n\t\tthis.size.x = this.canvas.clientWidth;\r\n\t\tthis.size.y = this.canvas.clientHeight;\r\n\t}\r\n\r\n\tinit(canvas: HTMLCanvasElement) {\r\n\t\tthis.canvas = canvas;\r\n\t\tthis.context = this.canvas.getContext(\"2d\") as CanvasRenderingContext2D;\r\n\t\tthis.resize();\r\n\r\n\t\t// Detect size changes of canvas\r\n\t\tconst observer = new ResizeObserver((entries) => {\r\n\t\t\tentries.forEach(({ target }) => {\r\n\t\t\t\tif (target === this.canvas && (target.clientWidth != this.size.x || target.clientHeight != this.size.y)) {\r\n\t\t\t\t\tthis.resize();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tobserver.observe(this.canvas);\r\n\r\n\t\tthis.inputHandler.init();\r\n\r\n\t\tthis.render();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\tthis.inputHandler.cleanup();\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.inputPins = [];\r\n\t\tthis.outputPins = [];\r\n\t\tthis.wires = [];\r\n\t\tthis.chips = [];\r\n\r\n\t\tthis.inputHandler.reset();\r\n\t}\r\n\r\n\tgetColor(key: string) {\r\n\t\tif (this.colors[key] != null)\r\n\t\t\treturn this.colors[key];\r\n\r\n\t\tconst color = getComputedStyle(this.canvas).getPropertyValue(\"--\" + key);\r\n\r\n\t\tif (ENABLE_COLOR_CACHING)\r\n\t\t\tthis.colors[key] = color;\r\n\r\n\t\treturn color;\r\n\t}\r\n\r\n\tisPointInsideRect(rect: { position: Vector2, size: Vector2 }, point: Vector2) {\r\n\t\treturn point.x > rect.position.x && point.y > rect.position.y\r\n\t\t\t&& point.x < rect.position.x + rect.size.x && point.y < rect.position.y + rect.size.y;\r\n\t}\r\n\r\n\tgetUniqueId() {\r\n\t\treturn this.lastId++;\r\n\t}\r\n\r\n\tgetTextRect(size: number, content: string) {\r\n\t\tthis.context.textBaseline = \"middle\";\r\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\r\n\t\tconst metrics = this.context.measureText(content);\r\n\r\n\t\tconst width = metrics.actualBoundingBoxRight + metrics.actualBoundingBoxLeft;\r\n\t\tconst height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\r\n\r\n\t\treturn { x: width, y: height };\r\n\t}\r\n\r\n\tdrawRect(style: string, positionX: number, positionY: number, sizeX: number, sizeY: number) {\r\n\t\tthis.context.fillStyle = style;\r\n\t\tthis.context.fillRect(positionX, positionY, sizeX, sizeY);\r\n\t}\r\n\r\n\tdrawCircle(style: string, positionX: number, positionY: number, radius: number) {\r\n\t\tthis.context.beginPath();\r\n\t\tthis.context.arc(positionX, positionY, radius, 0, 2 * Math.PI);\r\n\r\n\t\tthis.context.fillStyle = style;\r\n\t\tthis.context.fill();\r\n\t}\r\n\r\n\tdrawCurvedLine(style: string, positions: Vector2[], width: number, radius: number, resolution: number) {\r\n\t\tif (positions.length < 2)\r\n\t\t\treturn;\r\n\r\n\t\tthis.context.lineWidth = width;\r\n\t\tthis.context.lineJoin = \"round\";\r\n\t\tthis.context.lineCap = \"round\";\r\n\r\n\t\t/**\r\n\t\t * Based on https://github.com/SebLague/Digital-Logic-Sim/blob/main/Assets/Modules/Chip%20Creation/Scripts/Chip/Wires/WireRenderer.cs\r\n\t\t * TO DO: optimize\r\n\t\t */\r\n\r\n\t\tconst drawPoints: Vector2[] = [];\r\n\t\tdrawPoints.push(positions[0]);\r\n\r\n\t\tfor (let i = 1; i < positions.length - 1; i++) {\r\n\t\t\tconst targetPoint = positions[i];\r\n\t\t\tconst targetDir = Vector2.normalize(Vector2.subtract(positions[i], positions[i - 1]));\r\n\t\t\tconst distanceToTarget = Vector2.magnitude(Vector2.subtract(positions[i], positions[i - 1]));\r\n\t\t\tconst distanceToCurveStart = Math.max(distanceToTarget - radius, distanceToTarget / 2);\r\n\r\n\t\t\tconst nextTargetDir = Vector2.normalize(Vector2.subtract(positions[i + 1], positions[i]));\r\n\t\t\tconst nextLineLength = Vector2.magnitude(Vector2.subtract(positions[i + 1], positions[i]));\r\n\r\n\t\t\tconst curveStartPoint = Vector2.add(positions[i - 1], Vector2.scale(targetDir, distanceToCurveStart));\r\n\t\t\tconst curveEndPoint = Vector2.add(targetPoint, Vector2.scale(nextTargetDir, Math.min(radius, nextLineLength / 2)));\r\n\r\n\t\t\t// Bezier\r\n\t\t\tfor (let j = 0; j < resolution; j++) {\r\n\t\t\t\tconst t = j / (resolution - 1);\r\n\t\t\t\tconst a = Vector2.lerp(curveStartPoint, targetPoint, t);\r\n\t\t\t\tconst b = Vector2.lerp(targetPoint, curveEndPoint, t);\r\n\t\t\t\tconst p = Vector2.lerp(a, b, t);\r\n\r\n\t\t\t\tif (Vector2.sqrDistance(p, drawPoints[drawPoints.length - 1]) > 0.001) {\r\n\t\t\t\t\tdrawPoints.push(p);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tdrawPoints.push(positions[positions.length - 1]);\r\n\r\n\t\tthis.context.beginPath();\r\n\t\tthis.context.moveTo(drawPoints[0].x, drawPoints[0].y);\r\n\r\n\t\tfor (let i = 1; i < drawPoints.length; i++) {\r\n\t\t\tthis.context.lineTo(drawPoints[i].x, drawPoints[i].y);\r\n\t\t}\r\n\r\n\t\tthis.context.strokeStyle = style;\r\n\t\tthis.context.stroke();\r\n\t}\r\n\r\n\tdrawText(style: string, align: CanvasTextAlign, positionX: number, positionY: number, size: number, content: string) {\r\n\t\tthis.context.fillStyle = style;\r\n\t\tthis.context.textAlign = align;\r\n\t\tthis.context.textBaseline = \"middle\";\r\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\r\n\t\tthis.context.fillText(content, positionX, positionY);\r\n\t}\r\n\r\n\tsetDrawingOpacity(alpha: number) {\r\n\t\tthis.context.globalAlpha = clamp(alpha, 0, 1);\r\n\t}\r\n\r\n\tresetDrawingOpacity() {\r\n\t\tthis.setDrawingOpacity(1);\r\n\t}\r\n\r\n\tdrawBackground() {\r\n\t\tconst margin = CONTROLLER.handleTrackWidth;\r\n\t\tconst padding = BACKGROUND.padding;\r\n\r\n\t\tthis.drawRect(this.getColor(COLORS.background.margin), 0, 0, this.size.x, this.size.y);\r\n\r\n\t\tlet offset = 0;\r\n\r\n\t\tthis.drawRect(\r\n\t\t\tthis.getColor(COLORS.background.outer),\r\n\t\t\toffset + margin, offset,\r\n\t\t\tthis.size.x - margin * 2, this.size.y\r\n\t\t);\r\n\r\n\t\toffset = padding - BACKGROUND.borderWidth;\r\n\t\tthis.drawRect(\r\n\t\t\tthis.getColor(COLORS.background.border),\r\n\t\t\toffset + margin, offset,\r\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\r\n\t\t);\r\n\r\n\t\toffset = padding;\r\n\t\tthis.drawRect(\r\n\t\t\tthis.getColor(COLORS.background.inner),\r\n\t\t\toffset + margin, offset,\r\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\r\n\t\t);\r\n\t}\r\n\r\n\tdrawWires() {\r\n\t\tthis.wires.forEach((wire, index) => {\r\n\t\t\tconst isPlacingWire = this.inputHandler.placingWire != null && index == this.wires.length - 1;\r\n\t\t\twire.draw(isPlacingWire);\r\n\t\t});\r\n\t}\r\n\r\n\tdrawChips() {\r\n\t\tthis.chips.forEach((chip, index) => {\r\n\t\t\tconst isPlacingChip = this.inputHandler.placingChip != null && index == this.chips.length - 1;\r\n\t\t\tchip.draw(isPlacingChip);\r\n\t\t});\r\n\t}\r\n\r\n\tdraw() {\r\n\t\tthis.drawBackground();\r\n\t\tthis.drawWires();\r\n\t\tthis.drawChips();\r\n\t\tsuper.drawPins(false);\r\n\t}\r\n\r\n\trender() {\r\n\t\tif (this.canvas.width != this.size.x)\r\n\t\t\tthis.canvas.width = this.size.x;\r\n\t\tif (this.canvas.height != this.size.y)\r\n\t\t\tthis.canvas.height = this.size.y;\r\n\r\n\t\tthis.cursor = CURSORS.default;\r\n\r\n\t\tthis.draw();\r\n\r\n\t\tif (this.inputHandler.isPlacing) {\r\n\t\t\tthis.canvas.style.cursor = CURSORS.default;\r\n\t\t} else {\r\n\t\t\tthis.canvas.style.cursor = this.cursor;\r\n\t\t}\r\n\r\n\t\twindow.requestAnimationFrame(() => {\r\n\t\t\tthis.render();\r\n\t\t});\r\n\t}\r\n\r\n\ttoJson() {\r\n\t\tconst object = super.toJson() as CircuitJson;\r\n\r\n\t\tif (this.wires.length > 0)\r\n\t\t\tobject.wires = this.wires.map((wire) => wire.toJson());\r\n\r\n\t\tif (this.chips.length > 0)\r\n\t\t\tobject.chips = this.chips.map((chip) => chip.toJson());\r\n\r\n\t\treturn object;\r\n\t}\r\n\r\n\ttoString(): string {\r\n\t\tconst json = this.toJson();\r\n\t\treturn JSON.stringify(json);\r\n\t}\r\n}","import { Chip } from \"./chip\";\nimport { State } from \"../_utils/state\";\nimport { Circuit, CircuitJson } from \"../circuit\";\nimport { ControlledPin } from \"../pins/controlledPin\";\nimport { Pin } from \"../pins/pin\";\nimport { Wire } from \"../wires/wire\";\nimport { Vector2, VirtualFolder } from \"@prozilla-os/core\";\n\nexport class ChipsManager {\n\tstatic CHIPS: Record<string, Chip> = {\n\t\tand: new Chip(null, \"AND\", \"blue\", true, 2, 1).setLogic((inputStates: State[]) => {\n\t\t\tif (inputStates[0].value === 1 && inputStates[1].value === 1) {\n\t\t\t\treturn [State.HIGH];\n\t\t\t} else {\n\t\t\t\treturn [State.LOW];\n\t\t\t}\n\t\t}),\n\t\tnot: new Chip(null, \"NOT\", \"red\", true, 1, 1).setLogic((inputStates: State[]) => {\n\t\t\treturn [State.invert(inputStates[0])];\n\t\t}),\n\t};\n\n\tstatic saveCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tvirtualFolder.createFile(circuit.name, \"json\", (file) => {\n\t\t\tfile.setContent(circuit.toString());\n\t\t});\n\t}\n\n\tstatic loadCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tcircuit.reset();\n\t\tconst virtualFile = virtualFolder.findFile(circuit.name, \"json\");\n\n\t\tif (virtualFile == null)\n\t\t\treturn;\n\n\t\tvirtualFile.read()?.then((content) => {\n\t\t\tconst data = JSON.parse(content as string) as CircuitJson;\n\n\t\t\tcircuit.color = data.color;\n\t\t\tcircuit.name = data.name;\n\n\t\t\tconst pins: { [id: number]: Pin } = {};\n\n\t\t\t// Load input pins\n\t\t\tcircuit.inputCount = data.inputPins?.length ?? 0;\n\t\t\tdata.inputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, true, pinData.id);\n\t\t\t\tnewPin.position = pinData.position as Vector2;\n\n\t\t\t\tcircuit.inputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load output pins\n\t\t\tcircuit.outputCount = data.outputPins?.length ?? 0;\n\t\t\tdata.outputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, false, pinData.id);\n\t\t\t\tnewPin.position = pinData.position as Vector2;\n\n\t\t\t\tcircuit.outputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load chips\n\t\t\tdata.chips?.forEach((chipData) => {\n\t\t\t\tconst newChip = new Chip(circuit, chipData.name, chipData.color, false, 0, 0);\n\t\t\t\tnewChip.position = chipData.position as Vector2;\n\n\t\t\t\t// Load input pins\n\t\t\t\tnewChip.inputCount = chipData.inputPins?.length ?? 0;\n\t\t\t\tchipData.inputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, true, newChip, pinData.id);\n\t\t\t\t\tnewChip.inputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load output pins\n\t\t\t\tnewChip.outputCount = chipData.outputPins?.length ?? 0;\n\t\t\t\tchipData.outputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, false, newChip, pinData.id);\n\t\t\t\t\tnewChip.outputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load logic\n\t\t\t\tnewChip.setLogic((ChipsManager.CHIPS[chipData.name]).logic);\n\t\t\t\tnewChip.update();\n\n\t\t\t\tcircuit.chips.push(newChip);\n\t\t\t});\n\n\t\t\t// Load wires\n\t\t\tdata.wires?.forEach((wireData) => {\n\t\t\t\tconst inputPin = pins[wireData.inputId];\n\t\t\t\tconst outputPin = pins[wireData.outputId];\n\t\t\t\tconst anchorPoints = wireData.anchorPoints as Vector2[] ?? [];\n\n\t\t\t\tconst newWire = new Wire(circuit, wireData.color, inputPin, outputPin, anchorPoints);\n\t\t\t\tinputPin?.addOutputWire(newWire);\n\t\t\t\tcircuit.wires.push(newWire);\n\t\t\t});\n\t\t}).catch((error) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n}","import { useEffect, useRef, useState } from \"react\";\r\nimport styles from \"./CircuitView.module.css\";\r\nimport { App, ClickAction, DropdownAction, HeaderMenu, openUrl, useAppFolder } from \"@prozilla-os/core\";\r\nimport { Circuit } from \"../core/circuit\";\r\nimport { ChipsManager } from \"../core/chips/chipsManager\";\r\n\r\ninterface CircuitViewProps {\r\n\tapp?: App;\r\n}\r\n\r\nexport function CircuitView({ app }: CircuitViewProps) {\r\n\tconst virtualFolder = useAppFolder(app);\r\n\tconst [circuit] = useState(new Circuit(\"Chip\", \"#000\", 2, 1));\r\n\tconst canvasRef = useRef(null);\r\n\r\n\tuseEffect(() => {\r\n\t\tif (canvasRef.current == null && circuit.canvas != null)\r\n\t\t\treturn;\r\n\r\n\t\tcircuit.init(canvasRef.current as unknown as HTMLCanvasElement);\r\n\r\n\t\treturn () => {\r\n\t\t\tcircuit.cleanup();\r\n\t\t};\r\n\t}, [canvasRef, circuit]);\r\n\r\n\treturn <>\r\n\t\t<HeaderMenu>\r\n\t\t\t<DropdownAction label=\"Circuit\" showOnHover={false}>\r\n\t\t\t\t<ClickAction label=\"New\" onTrigger={() => { circuit.reset(); }}/>\r\n\t\t\t\t<ClickAction label=\"Save\" onTrigger={() => {\r\n\t\t\t\t\tif (virtualFolder != null)\r\n\t\t\t\t\t\tChipsManager.saveCircuit(circuit, virtualFolder);\r\n\t\t\t\t}}/>\r\n\t\t\t\t<ClickAction label=\"Load\" onTrigger={() => {\r\n\t\t\t\t\tif (virtualFolder != null)\r\n\t\t\t\t\t\tChipsManager.loadCircuit(circuit, virtualFolder);\r\n\t\t\t\t}}/>\r\n\t\t\t</DropdownAction>\r\n\t\t\t<DropdownAction label=\"Add\" showOnHover={false}>\r\n\t\t\t\t<ClickAction label=\"AND gate\" onTrigger={() => {\r\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.AND);\r\n\t\t\t\t}}/>\r\n\t\t\t\t<ClickAction label=\"NOT gate\" onTrigger={() => {\r\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.NOT);\r\n\t\t\t\t}}/>\r\n\t\t\t</DropdownAction>\r\n\t\t\t<DropdownAction label=\"Help\" showOnHover={false}>\r\n\t\t\t\t<ClickAction label=\"Digital Electronics Glossary\" onTrigger={() => {\r\n\t\t\t\t\topenUrl(\"http://www.pmcgibbon.net/teachcte/electron/degloss1.htm\");\r\n\t\t\t\t}}/>\r\n\t\t\t</DropdownAction>\r\n\t\t</HeaderMenu>\r\n\t\t<div className={styles.CircuitView}>\r\n\t\t\t<canvas ref={canvasRef} className={styles.Canvas}/>\r\n\t\t</div>\r\n\t</>;\r\n}","import { WindowProps } from \"@prozilla-os/core\";\r\nimport { CircuitView } from \"./CircuitView\";\r\nimport styles from \"./LogicSim.module.css\";\r\n\r\nexport function LogicSim({ app }: WindowProps) {\r\n\treturn <div className={styles.LogicSim}>\r\n\t\t<CircuitView app={app}/>\r\n\t</div>;\r\n}","import { App } from \"@prozilla-os/core\";\nimport { LogicSim } from \"./components/LogicSim\";\n\nconst logicSim = new App(\"Logic Sim\", \"logic-sim\", LogicSim)\n\t.setIconUrl(\"https://os.prozilla.dev/assets/apps/icons/logic-sim.svg\")\n\t.setPinnedByDefault(false)\n\t.setCategory(\"Education\");\nlogicSim.setMetadata({ name: \"@prozilla-os/logic-sim\", version: \"1.1.15\", author: \"Prozilla\" });\n\n\nexport { logicSim };"],"names":["_State","value","__publicField","state","State","CURSORS","FONT","BACKGROUND","CONTROLLER","WIRE","PIN","CHIP","COLORS","Pin","circuit","name","isInput","attachedChip","id","Vector2","wire","_a","isPlacing","color","positionX","leftAligned","textRect","backgroundSize","Chip","isBlueprint","inputCount","outputCount","width","minHeight","i","newPin","pin","logic","inputStates","outputStates","reposition","index","gap","isPlacingPin","object","ControlledPin","size","positionY","rect","Wire","inputPin","outputPin","anchorPoints","positions","InputHandler","event","isHoveringPinHandle","top","bottom","invalidPlacement","eventComplete","chip","hoveringPin","isInputPin","anchorPoint","lastAnchorPoint","previousAnchorPoint","closestPositionX","closestDistance","point","distance","pins","closestPositionY","anchorCount","_b","_c","_d","_f","_e","deltaX","deltaY","correctPlacement","newChip","Circuit","canvas","entries","target","key","content","metrics","height","style","sizeX","sizeY","radius","resolution","drawPoints","targetPoint","targetDir","distanceToTarget","distanceToCurveStart","nextTargetDir","nextLineLength","curveStartPoint","curveEndPoint","j","t","a","b","p","align","alpha","clamp","margin","padding","offset","isPlacingWire","isPlacingChip","json","_ChipsManager","virtualFolder","file","virtualFile","data","pinData","chipData","wireData","newWire","error","ChipsManager","CircuitView","app","useAppFolder","useState","canvasRef","useRef","useEffect","jsxs","Fragment","HeaderMenu","DropdownAction","jsx","ClickAction","openUrl","styles","LogicSim","logicSim","App"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prozilla-os/logic-sim",
3
3
  "description": "A ProzillaOS application for simulating digital logic.",
4
- "version": "1.1.14",
4
+ "version": "1.1.16",
5
5
  "homepage": "https://os.prozilla.dev/logic-sim",
6
6
  "author": {
7
7
  "name": "Prozilla",
@@ -20,7 +20,7 @@
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
22
  "react": "^18.3.1",
23
- "@prozilla-os/core": "1.3.9",
23
+ "@prozilla-os/core": "1.3.11",
24
24
  "@prozilla-os/shared": "1.2.0"
25
25
  },
26
26
  "devDependencies": {
@@ -31,7 +31,7 @@
31
31
  "vite": "^5.4.8",
32
32
  "vite-plugin-dts": "^3.9.1",
33
33
  "vite-plugin-lib-inject-css": "^2.1.1",
34
- "@prozilla-os/dev-tools": "1.1.6"
34
+ "@prozilla-os/dev-tools": "1.1.8"
35
35
  },
36
36
  "files": [
37
37
  "dist"