logicsimulator/ts/tristate.ts

124 lines
3.1 KiB
TypeScript

// Tri-State class for IO pis of the LogicSimulator
// Copyright (C) 2022 Sascha Nitsch
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface TriStateParam {
id?: string;
type?: string;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class TriState {
private parent: BaseComponent;
private offsetX: number;
private offsetY: number;
private state: WireState;
private readonly: boolean;
private param: TriStateParam;
public connectedWire: Wire | null;
private rotate: number;
constructor(
parent: BaseComponent,
offsetX: number,
offsetY: number,
fixed?: undefined | WireState,
param: TriStateParam = {}
) {
this.parent = parent;
this.offsetX = offsetX; // * parent.scaleX;
this.offsetY = offsetY; // * parent.scaleY;
this.connectedWire = null;
if (fixed !== undefined) {
this.state = fixed;
this.readonly = true;
} else {
this.state = WireState.float;
this.readonly = false;
}
this.param = param;
this.rotate = parent ? (parent.getRotate() / 180) * Math.PI : 0;
}
move(x: number, y: number): void {
this.offsetX = x;
this.offsetY = y;
}
x(): number {
return (
this.parent.getX() +
this.offsetX * Math.cos(this.rotate) * this.parent.getScaleX() -
this.offsetY * Math.sin(this.rotate) * this.parent.getScaleX()
);
}
y(): number {
return (
this.parent.getY() +
this.offsetX * Math.sin(this.rotate) * this.parent.getScaleX() +
this.offsetY * Math.cos(this.rotate) * this.parent.getScaleY()
);
}
get(): WireState {
return this.state;
}
getAndReset(): WireState {
const s = this.state;
if (!this.readonly) {
this.state = WireState.float;
}
return s;
}
setState(state: WireState) {
if (!this.readonly) {
this.state = state;
}
}
setBool(state: boolean) {
if (!this.readonly) {
this.state = state ? WireState.high : WireState.low;
}
}
connected(wire: Wire) {
if (this.connectedWire) {
console.log('multiple wires on', this.parent.getId(), this.param.id, this.connectedWire.getId(), wire.getId());
}
this.connectedWire = wire;
this.parent.connected(this);
}
getParent(): BaseComponent {
return this.parent;
}
getParam(): TriStateParam {
return this.param;
}
getOffsetX(): number {
return this.offsetX;
}
getOffsetY(): number {
return this.offsetY;
}
}