ProzillaOS/packages/apps/logic-sim/core/pins/pin.ts
2024-06-16 21:46:44 +02:00

125 lines
No EOL
2.8 KiB
TypeScript

import { COLORS, CONTROLLER, CURSORS, PIN } from "../../../../config/apps/logicSim.config";
import { Vector2 } from "../../../math/vector2";
import { Chip } from "../chips/chip";
import { Circuit } from "../circuit";
import { State } from "../_utils/state";
import { Wire } from "../wires/wire";
export interface PinJson {
name: string;
id: number;
position: {
x: number;
y: number;
};
}
export class Pin {
id: number;
name!: string;
position = Vector2.ZERO;
attachedChip!: Chip;
circuit!: Circuit;
state = State.LOW;
isInput!: boolean;
isControlled: boolean = false;
outputWires: Wire[] = [];
constructor(circuit: Circuit, name: string, isInput: boolean, attachedChip: Chip, id?: number) {
Object.assign(this, { circuit, name, isInput, attachedChip });
this.id = id ?? this.circuit.getUniqueId();
}
addOutputWire(wire: Wire) {
this.outputWires.push(wire);
wire.setState(this.state);
}
setState(state: State) {
if (this.state.isEqual(state))
return;
this.state = state;
this.update();
}
update() {
// TO DO: clean this mess
this.outputWires.forEach((wire) => {
wire.setState(this.state);
});
this.attachedChip?.update();
}
get isPointingRight() {
return this.isInput === this.isControlled;
}
draw(isPlacing: boolean) {
let color = COLORS.pin.fill;
if (this.circuit.inputHandler.mousePosition.getDistance(this.position.x, this.position.y) <= PIN.radius) {
this.circuit.cursor = CURSORS.pointer;
color = COLORS.pin.fillHover;
// Draw label
let positionX = this.position.x;
const leftAligned = this.isPointingRight;
const textRect = this.circuit.getTextRect(PIN.label.fontSize, this.name);
if (leftAligned) {
positionX += PIN.radius + PIN.label.offset;
} else {
positionX -= PIN.radius + PIN.label.offset;
}
const backgroundSize = {
x: textRect.x + PIN.label.padding * 2,
y: textRect.y + PIN.label.padding * 2
};
this.circuit.drawRect(
this.circuit.getColor(COLORS.pin.labelBackground),
leftAligned ? positionX : positionX - backgroundSize.x, this.position.y - textRect.y / 2 - PIN.label.padding,
backgroundSize.x, backgroundSize.y
);
if (leftAligned) {
positionX += PIN.label.padding;
} else {
positionX -= PIN.label.padding;
}
this.circuit.drawText(
this.circuit.getColor(COLORS.pin.labelText),
leftAligned ? "left" : "right",
positionX, this.position.y,
PIN.label.fontSize,
this.name
);
}
if (isPlacing)
this.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);
this.circuit.drawCircle(
this.circuit.getColor(color),
this.position.x, this.position.y,
PIN.radius
);
if (isPlacing)
this.circuit.resetDrawingOpacity();
}
toJson(): PinJson {
const object = {
name: this.name,
id: this.id,
position: this.position
} as PinJson;
return object;
}
}