Added logic gates to logic sim app
This commit is contained in:
parent
54249b4ba6
commit
445c10d68d
10 changed files with 222 additions and 68 deletions
|
|
@ -70,7 +70,6 @@ export function Actions({ children, className, onAnyTrigger, triggerParams, avoi
|
||||||
actionId,
|
actionId,
|
||||||
children: iterateOverChildren((child.props as ActionProps).children),
|
children: iterateOverChildren((child.props as ActionProps).children),
|
||||||
onTrigger: (event, ...args) => {
|
onTrigger: (event, ...args) => {
|
||||||
console.log(event);
|
|
||||||
onAnyTrigger?.(event, triggerParams, ...args);
|
onAnyTrigger?.(event, triggerParams, ...args);
|
||||||
onTrigger?.(event, triggerParams, ...args);
|
onTrigger?.(event, triggerParams, ...args);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { Circuit } from "../../../features/apps/logic-sim/circuit";
|
import { Circuit } from "../../../features/apps/logic-sim/circuit";
|
||||||
import styles from "./CircuitView.module.css";
|
import styles from "./CircuitView.module.css";
|
||||||
|
import { DropdownAction } from "../../actions/actions/DropdownAction";
|
||||||
|
import { HeaderMenu } from "../_utils/header-menu/HeaderMenu";
|
||||||
|
import { ClickAction } from "../../actions/actions/ClickAction";
|
||||||
|
import { ChipsManager } from "../../../features/apps/logic-sim/chipsManager";
|
||||||
|
|
||||||
export function CircuitView() {
|
export function CircuitView() {
|
||||||
const [circuit, setCircuit] = useState(new Circuit("Chip", "#000", 2, 1));
|
const [circuit] = useState(new Circuit("Chip", "#000", 2, 1));
|
||||||
const canvasRef = useRef(null);
|
const canvasRef = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -17,5 +21,13 @@ export function CircuitView() {
|
||||||
};
|
};
|
||||||
}, [canvasRef, circuit]);
|
}, [canvasRef, circuit]);
|
||||||
|
|
||||||
return <canvas ref={canvasRef} className={styles.Canvas}/>;
|
return <>
|
||||||
|
<HeaderMenu>
|
||||||
|
<DropdownAction label="Add" showOnHover={false}>
|
||||||
|
<ClickAction label="AND gate" onTrigger={() => { circuit.addChip(ChipsManager.CHIPS.AND); }}/>
|
||||||
|
<ClickAction label="NOT gate" onTrigger={() => { circuit.addChip(ChipsManager.CHIPS.NOT); }}/>
|
||||||
|
</DropdownAction>
|
||||||
|
</HeaderMenu>
|
||||||
|
<canvas ref={canvasRef} className={styles.Canvas}/>
|
||||||
|
</>;
|
||||||
}
|
}
|
||||||
|
|
@ -127,9 +127,7 @@ export function TextEditor({ file, setTitle, setIconUrl, close, mode, app, modal
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.Container} style={{ fontSize: zoom }}>
|
<div className={styles.Container} style={{ fontSize: zoom }}>
|
||||||
<HeaderMenu onAnyTrigger={(event) => {
|
<HeaderMenu>
|
||||||
console.log(event);
|
|
||||||
}}>
|
|
||||||
<DropdownAction label="File" showOnHover={false}>
|
<DropdownAction label="File" showOnHover={false}>
|
||||||
<ClickAction label="New" onTrigger={() => { newText(); }} shortcut={["Control", "e"]}/>
|
<ClickAction label="New" onTrigger={() => { newText(); }} shortcut={["Control", "e"]}/>
|
||||||
<ClickAction label="Open" onTrigger={() => {
|
<ClickAction label="Open" onTrigger={() => {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ export const CURSORS = {
|
||||||
pointer: "pointer"
|
pointer: "pointer"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const FONT = "outfit";
|
||||||
|
|
||||||
export const BACKGROUND = {
|
export const BACKGROUND = {
|
||||||
padding: 40,
|
padding: 40,
|
||||||
borderWidth: 8,
|
borderWidth: 8,
|
||||||
|
|
@ -20,7 +22,14 @@ export const WIRE = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PIN = {
|
export const PIN = {
|
||||||
radius: 10,
|
radius: 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CHIP = {
|
||||||
|
width: 140,
|
||||||
|
height: 72,
|
||||||
|
padding: 12,
|
||||||
|
fontSize: 36,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const COLORS = {
|
export const COLORS = {
|
||||||
|
|
@ -44,4 +53,7 @@ export const COLORS = {
|
||||||
wire: {
|
wire: {
|
||||||
placing: "dark-grey-ca",
|
placing: "dark-grey-ca",
|
||||||
},
|
},
|
||||||
|
chip: {
|
||||||
|
text: "dark-grey-f"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { CHIP, COLORS } from "../../../config/apps/logicSim.config";
|
||||||
import Vector2 from "../../math/vector2";
|
import Vector2 from "../../math/vector2";
|
||||||
import { Circuit } from "./circuit";
|
import { Circuit } from "./circuit";
|
||||||
import { Pin } from "./pin";
|
import { Pin } from "./pin";
|
||||||
|
|
@ -7,7 +8,9 @@ export class Chip {
|
||||||
color: string;
|
color: string;
|
||||||
name: string;
|
name: string;
|
||||||
position: Vector2;
|
position: Vector2;
|
||||||
|
size: Vector2;
|
||||||
circuit: Circuit;
|
circuit: Circuit;
|
||||||
|
isCircuit = true;
|
||||||
|
|
||||||
inputCount: number;
|
inputCount: number;
|
||||||
outputCount: number;
|
outputCount: number;
|
||||||
|
|
@ -15,8 +18,8 @@ export class Chip {
|
||||||
outputPins: Pin[];
|
outputPins: Pin[];
|
||||||
logic: (inputStates: State[]) => State[];
|
logic: (inputStates: State[]) => State[];
|
||||||
|
|
||||||
constructor(circuit: Circuit | null, name: string, color: string, inputCount: number, outputCount: number) {
|
constructor(circuit: Circuit | null, name: string, color: string, size: Vector2, inputCount: number, outputCount: number) {
|
||||||
Object.assign(this, { circuit, name, color, inputCount, outputCount });
|
Object.assign(this, { circuit, name, color, size, inputCount, outputCount });
|
||||||
|
|
||||||
if (this.circuit == null)
|
if (this.circuit == null)
|
||||||
this.circuit = this as unknown as Circuit;
|
this.circuit = this as unknown as Circuit;
|
||||||
|
|
@ -32,15 +35,21 @@ export class Chip {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setInputState(index: number, state: State) {
|
setCircuit(circuit: Circuit) {
|
||||||
if (this.inputPins[index].state.isEqual(state))
|
this.circuit = circuit;
|
||||||
return;
|
|
||||||
|
|
||||||
this.inputPins[index].state = state;
|
this.inputPins.concat(this.outputPins).forEach((pin) => { pin.circuit = circuit; });
|
||||||
this.update();
|
}
|
||||||
|
|
||||||
|
setLogic(logic: (inputStates: State[]) => State[]) {
|
||||||
|
this.logic = logic;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
|
if (this.logic == null)
|
||||||
|
return;
|
||||||
|
|
||||||
const inputStates: State[] = [];
|
const inputStates: State[] = [];
|
||||||
for (let i = 0; i < this.inputCount; i++) {
|
for (let i = 0; i < this.inputCount; i++) {
|
||||||
const state = this.inputPins[i].state ?? State.LOW;
|
const state = this.inputPins[i].state ?? State.LOW;
|
||||||
|
|
@ -50,16 +59,52 @@ export class Chip {
|
||||||
const outputStates: State[] = this.logic(inputStates);
|
const outputStates: State[] = this.logic(inputStates);
|
||||||
|
|
||||||
for (let i = 0; i < this.outputCount; i++) {
|
for (let i = 0; i < this.outputCount; i++) {
|
||||||
this.outputPins[i].state = outputStates[i];
|
this.outputPins[i].setState(outputStates[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawPins() {
|
drawPins(reposition = true) {
|
||||||
this.inputPins.forEach((pin) => pin.draw());
|
this.inputPins.forEach((pin, index) => {
|
||||||
this.outputPins.forEach((pin) => pin.draw());
|
if (reposition) {
|
||||||
|
const gap = this.size.y / (this.inputCount + 1);
|
||||||
|
pin.position.x = this.position.x;
|
||||||
|
pin.position.y = this.position.y + gap * (index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pin.draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.outputPins.forEach((pin, index) => {
|
||||||
|
if (reposition) {
|
||||||
|
const gap = this.size.y / (this.outputCount + 1);
|
||||||
|
pin.position.x = this.position.x + this.size.x;
|
||||||
|
pin.position.y = this.position.y + gap * (index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pin.draw();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
|
this.circuit.drawRect(
|
||||||
|
this.circuit.getColor(this.color + "-b"),
|
||||||
|
this.position.x, this.position.y,
|
||||||
|
this.size.x, this.size.y
|
||||||
|
);
|
||||||
|
this.circuit.drawRect(
|
||||||
|
this.circuit.getColor(this.color + "-a"),
|
||||||
|
this.position.x + CHIP.padding, this.position.y + CHIP.padding,
|
||||||
|
this.size.x - CHIP.padding * 2, this.size.y - CHIP.padding * 2
|
||||||
|
);
|
||||||
|
|
||||||
|
this.circuit.drawText(
|
||||||
|
this.circuit.getColor(COLORS.chip.text),
|
||||||
|
"center",
|
||||||
|
this.position.x + this.size.x / 2, this.position.y + this.size.y / 2,
|
||||||
|
CHIP.fontSize,
|
||||||
|
this.name
|
||||||
|
);
|
||||||
|
|
||||||
this.drawPins();
|
this.drawPins();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
19
src/features/apps/logic-sim/chipsManager.ts
Normal file
19
src/features/apps/logic-sim/chipsManager.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { CHIP } from "../../../config/apps/logicSim.config";
|
||||||
|
import Vector2 from "../../math/vector2";
|
||||||
|
import { Chip } from "./chip";
|
||||||
|
import { State } from "./state";
|
||||||
|
|
||||||
|
export class ChipsManager {
|
||||||
|
static CHIPS = {
|
||||||
|
AND: new Chip(null, "AND", "cyan", new Vector2(CHIP.width, CHIP.height), 2, 1).setLogic((inputStates: State[]) => {
|
||||||
|
if (inputStates[0].value === 1 && inputStates[1].value === 1) {
|
||||||
|
return [State.HIGH];
|
||||||
|
} else {
|
||||||
|
return [State.LOW];
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
NOT: new Chip(null, "NOT", "yellow", new Vector2(CHIP.width, CHIP.height), 1, 1).setLogic((inputStates: State[]) => {
|
||||||
|
return [State.invert(inputStates[0])];
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { BACKGROUND, COLORS, CURSORS, INPUT_OUTPUT, PIN, WIRE } from "../../../config/apps/logicSim.config";
|
import { BACKGROUND, COLORS, CURSORS, FONT, INPUT_OUTPUT, PIN } from "../../../config/apps/logicSim.config";
|
||||||
import Vector2 from "../../math/vector2";
|
import Vector2 from "../../math/vector2";
|
||||||
import { Chip } from "./chip";
|
import { Chip } from "./chip";
|
||||||
import { Pin } from "./pin";
|
import { Pin } from "./pin";
|
||||||
|
|
@ -11,16 +11,19 @@ export class Circuit extends Chip {
|
||||||
context: CanvasRenderingContext2D;
|
context: CanvasRenderingContext2D;
|
||||||
colors: { [key: string]: string } = {};
|
colors: { [key: string]: string } = {};
|
||||||
mousePosition = Vector2.ZERO;
|
mousePosition = Vector2.ZERO;
|
||||||
|
isCircuit = true;
|
||||||
|
|
||||||
isPlacing = false;
|
isPlacing = false;
|
||||||
snapping = false;
|
snapping = false;
|
||||||
placingWire: Wire;
|
placingWire: Wire;
|
||||||
wires: Wire[] = [];
|
wires: Wire[] = [];
|
||||||
|
placingChip: Chip;
|
||||||
|
chips: Chip[] = [];
|
||||||
|
|
||||||
cursor = CURSORS.default;
|
cursor = CURSORS.default;
|
||||||
|
|
||||||
constructor(name: string, color: string, inputCount: number, outputCount: number) {
|
constructor(name: string, color: string, inputCount: number, outputCount: number) {
|
||||||
super(null, name, color, inputCount, outputCount);
|
super(null, name, color, null, inputCount, outputCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
resize() {
|
resize() {
|
||||||
|
|
@ -111,11 +114,18 @@ export class Circuit extends Chip {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.placingChip != null) {
|
||||||
|
this.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2;
|
||||||
|
this.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickPin(pin: Pin) {
|
onClickPin(pin: Pin, isInputOutput = false) {
|
||||||
|
const isInputPin = isInputOutput ? !pin.isInput : pin.isInput;
|
||||||
|
|
||||||
if (this.placingWire != null) {
|
if (this.placingWire != null) {
|
||||||
if (!pin.isInput) {
|
if (isInputPin) {
|
||||||
this.placingWire.outputPin = pin;
|
this.placingWire.outputPin = pin;
|
||||||
this.placingWire.anchorPoints.pop();
|
this.placingWire.anchorPoints.pop();
|
||||||
|
|
||||||
|
|
@ -125,14 +135,15 @@ export class Circuit extends Chip {
|
||||||
this.placingWire = null;
|
this.placingWire = null;
|
||||||
this.isPlacing = false;
|
this.isPlacing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputConnection = pin.isInput ? pin : null;
|
const inputConnection = isInputPin ? null : pin;
|
||||||
const outputConnection = pin.isInput ? null : pin;
|
const outputConnection = isInputPin ? pin : null;
|
||||||
const anchorPoint = this.mousePosition.clone;
|
const anchorPoint = this.mousePosition.clone;
|
||||||
|
|
||||||
this.placingWire = new Wire("blue", inputConnection, outputConnection, [anchorPoint]);
|
this.placingWire = new Wire(this, "red", inputConnection, outputConnection, [anchorPoint]);
|
||||||
this.wires.push(this.placingWire);
|
this.wires.push(this.placingWire);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,6 +158,8 @@ export class Circuit extends Chip {
|
||||||
this.wires.pop();
|
this.wires.pop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(this);
|
||||||
} else if (event.button === 0) {
|
} else if (event.button === 0) {
|
||||||
let eventComplete = false;
|
let eventComplete = false;
|
||||||
|
|
||||||
|
|
@ -155,7 +168,7 @@ export class Circuit extends Chip {
|
||||||
pin.setState(State.invert(pin.state));
|
pin.setState(State.invert(pin.state));
|
||||||
eventComplete = true;
|
eventComplete = true;
|
||||||
} else if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {
|
} else if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {
|
||||||
this.onClickPin(pin);
|
this.onClickPin(pin, true);
|
||||||
eventComplete = true;
|
eventComplete = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -165,16 +178,37 @@ export class Circuit extends Chip {
|
||||||
|
|
||||||
this.outputPins.forEach((pin: Pin) => {
|
this.outputPins.forEach((pin: Pin) => {
|
||||||
if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {
|
if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {
|
||||||
this.onClickPin(pin);
|
this.onClickPin(pin, true);
|
||||||
eventComplete = true;
|
eventComplete = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (eventComplete)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.chips.forEach((chip) => {
|
||||||
|
chip.inputPins.concat(chip.outputPins).forEach((pin) => {
|
||||||
|
if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {
|
||||||
|
this.onClickPin(pin);
|
||||||
|
eventComplete = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (eventComplete)
|
if (eventComplete)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Create wire anchor point
|
||||||
if (this.placingWire != null) {
|
if (this.placingWire != null) {
|
||||||
this.placingWire.anchorPoints.push(this.mousePosition.clone);
|
this.placingWire.anchorPoints.push(this.mousePosition.clone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place chip
|
||||||
|
if (this.placingChip != null) {
|
||||||
|
this.placingChip = null;
|
||||||
|
this.isPlacing = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -197,6 +231,19 @@ export class Circuit extends Chip {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
addChip(chip: Chip) {
|
||||||
|
const newChip = new Chip(this, chip.name, chip.color, chip.size, chip.inputCount, chip.outputCount);
|
||||||
|
newChip.setLogic(chip.logic);
|
||||||
|
newChip.position = new Vector2(
|
||||||
|
this.mousePosition.x - newChip.size.x / 2,
|
||||||
|
this.mousePosition.y - newChip.size.y / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
this.placingChip = newChip;
|
||||||
|
this.isPlacing = true;
|
||||||
|
this.chips.push(newChip);
|
||||||
|
}
|
||||||
|
|
||||||
getColor(key: string) {
|
getColor(key: string) {
|
||||||
if (this.colors[key] != null)
|
if (this.colors[key] != null)
|
||||||
return this.colors[key];
|
return this.colors[key];
|
||||||
|
|
@ -239,6 +286,14 @@ export class Circuit extends Chip {
|
||||||
this.context.stroke();
|
this.context.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawText(style: string, align: CanvasTextAlign, positionX: number, positionY: number, size: number, content: string) {
|
||||||
|
this.context.fillStyle = style;
|
||||||
|
this.context.textAlign = align;
|
||||||
|
this.context.textBaseline = "middle";
|
||||||
|
this.context.font = `bold ${size}px ${FONT}`;
|
||||||
|
this.context.fillText(content, positionX, positionY);
|
||||||
|
}
|
||||||
|
|
||||||
drawBackground() {
|
drawBackground() {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
this.drawRect(this.getColor(COLORS.background.outer), offset, offset, this.size.x, this.size.y);
|
this.drawRect(this.getColor(COLORS.background.outer), offset, offset, this.size.x, this.size.y);
|
||||||
|
|
@ -260,28 +315,15 @@ export class Circuit extends Chip {
|
||||||
|
|
||||||
drawWires() {
|
drawWires() {
|
||||||
this.wires.forEach((wire, index) => {
|
this.wires.forEach((wire, index) => {
|
||||||
const positions = [...wire.anchorPoints];
|
|
||||||
|
|
||||||
if (wire.inputPin != null)
|
|
||||||
positions.unshift(wire.inputPin.position);
|
|
||||||
if (wire.outputPin != null)
|
|
||||||
positions.push(wire.outputPin.position);
|
|
||||||
|
|
||||||
let color: string;
|
|
||||||
|
|
||||||
const isPlacingWire = this.placingWire != null && index == this.wires.length - 1;
|
const isPlacingWire = this.placingWire != null && index == this.wires.length - 1;
|
||||||
if (isPlacingWire) {
|
wire.draw(isPlacingWire);
|
||||||
color = COLORS.wire.placing;
|
|
||||||
} else if (wire.state.value === 1) {
|
|
||||||
color = `${wire.color}-a`;
|
|
||||||
} else {
|
|
||||||
color = `${wire.color}-b`;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.drawLine(this.getColor(color), positions, WIRE.width);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawChips() {
|
||||||
|
this.chips.forEach((chip) => { chip.draw(); });
|
||||||
|
}
|
||||||
|
|
||||||
drawInputOutput(state: State, isInteractable: boolean, positionX: number, positionY: number) {
|
drawInputOutput(state: State, isInteractable: boolean, positionX: number, positionY: number) {
|
||||||
let color: string;
|
let color: string;
|
||||||
|
|
||||||
|
|
@ -338,12 +380,13 @@ export class Circuit extends Chip {
|
||||||
this.drawInputOutput(pin.state, false, positionX, pin.position.y);
|
this.drawInputOutput(pin.state, false, positionX, pin.position.y);
|
||||||
});
|
});
|
||||||
|
|
||||||
super.drawPins();
|
super.drawPins(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
this.drawBackground();
|
this.drawBackground();
|
||||||
this.drawWires();
|
this.drawWires();
|
||||||
|
this.drawChips();
|
||||||
this.drawPins();
|
this.drawPins();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { Wire } from "./wire";
|
||||||
|
|
||||||
export class Pin {
|
export class Pin {
|
||||||
name: string;
|
name: string;
|
||||||
position: Vector2;
|
position = Vector2.ZERO;
|
||||||
attachedChip: Chip;
|
attachedChip: Chip;
|
||||||
index: number;
|
index: number;
|
||||||
circuit: Circuit;
|
circuit: Circuit;
|
||||||
|
|
@ -34,9 +34,9 @@ export class Pin {
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
if (this.isInput) {
|
// TO DO: clean this mess
|
||||||
this.outputWire?.setState(this.state);
|
this.outputWire?.setState(this.state);
|
||||||
}
|
this.attachedChip?.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
import { WIRE } from "../../../config/apps/logicSim.config";
|
||||||
import Vector2 from "../../math/vector2";
|
import Vector2 from "../../math/vector2";
|
||||||
|
import { Circuit } from "./circuit";
|
||||||
import { Pin } from "./pin";
|
import { Pin } from "./pin";
|
||||||
import { State } from "./state";
|
import { State } from "./state";
|
||||||
|
|
||||||
|
|
@ -8,9 +10,10 @@ export class Wire {
|
||||||
inputPin: Pin;
|
inputPin: Pin;
|
||||||
outputPin: Pin;
|
outputPin: Pin;
|
||||||
anchorPoints: Vector2[];
|
anchorPoints: Vector2[];
|
||||||
|
circuit: Circuit;
|
||||||
|
|
||||||
constructor(color: string, inputPin?: Pin, outputPin?: Pin, anchorPoints?: Vector2[]) {
|
constructor(circuit: Circuit, color: string, inputPin?: Pin, outputPin?: Pin, anchorPoints?: Vector2[]) {
|
||||||
Object.assign(this, { color, inputPin, outputPin, anchorPoints });
|
Object.assign(this, { circuit, color, inputPin, outputPin, anchorPoints });
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(state: State) {
|
setState(state: State) {
|
||||||
|
|
@ -27,4 +30,25 @@ export class Wire {
|
||||||
|
|
||||||
this.outputPin.setState(this.state);
|
this.outputPin.setState(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw(isPlacingWire: boolean) {
|
||||||
|
const positions = [...this.anchorPoints];
|
||||||
|
|
||||||
|
if (this.inputPin != null)
|
||||||
|
positions.unshift(this.inputPin.position);
|
||||||
|
if (this.outputPin != null)
|
||||||
|
positions.push(this.outputPin.position);
|
||||||
|
|
||||||
|
let color: string;
|
||||||
|
|
||||||
|
if (isPlacingWire) {
|
||||||
|
color = `${this.color}-b`;
|
||||||
|
} else if (this.state.value === 1) {
|
||||||
|
color = `${this.color}-a`;
|
||||||
|
} else {
|
||||||
|
color = `${this.color}-d`;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.circuit.drawLine(this.circuit.getColor(color), positions, WIRE.width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,22 +1,24 @@
|
||||||
:root {
|
:root {
|
||||||
--white-a: hsl(210, 54%, 95%);
|
--white-a: hsl(210, 54%, 95%);
|
||||||
--white-b: hsl(210, 45%, 90%);
|
--white-b: hsl(210, 45%, 90%);
|
||||||
--pink-a: #ff9ff3;
|
--pink-a: hsl(308, 100%, 81%);
|
||||||
--pink-b: #f368e0;
|
--pink-b: hsl(308, 85%, 68%);
|
||||||
--yellow-a: #feca57;
|
--yellow-a: hsl(41, 99%, 67%);
|
||||||
--yellow-b: #ff9f43;
|
--yellow-b: hsl(29, 100%, 63%);
|
||||||
--red-a: #ff6b6b;
|
--red-a: hsl(0, 100%, 71%);
|
||||||
--red-b: #ee5253;
|
--red-b: hsl(360, 82%, 63%);
|
||||||
--light-blue-a: #48dbfb;
|
--red-c: hsl(360, 64%, 55%);
|
||||||
--light-blue-b: #0abde3;
|
--red-d: hsl(360, 46%, 47%);
|
||||||
--green-a: #1dd1a1;
|
--light-blue-a: hsl(191, 96%, 63%);
|
||||||
--green-b: #10ac84;
|
--light-blue-b: hsl(191, 92%, 46%);
|
||||||
--cyan-a: #00d2d3;
|
--green-a: hsl(164, 76%, 47%);
|
||||||
--cyan-b: #01a3a4;
|
--green-b: hsl(165, 83%, 37%);
|
||||||
--blue-a: #54a0ff;
|
--cyan-a: hsl(180, 100%, 41%);
|
||||||
--blue-b: #2e86de;
|
--cyan-b: hsl(180, 99%, 32%);
|
||||||
--purple-a: #5f27cd;
|
--blue-a: hsl(213, 100%, 66%);
|
||||||
--purple-b: #341f97;
|
--blue-b: hsl(210, 73%, 53%);
|
||||||
|
--purple-a: hsl(260, 68%, 48%);
|
||||||
|
--purple-b: hsl(251, 66%, 36%);
|
||||||
--grey-a: hsl(210, 36%, 85%);
|
--grey-a: hsl(210, 36%, 85%);
|
||||||
--grey-aa: hsl(210, 27%, 72.5%);
|
--grey-aa: hsl(210, 27%, 72.5%);
|
||||||
--grey-b: hsl(210, 18%, 60%);
|
--grey-b: hsl(210, 18%, 60%);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue