8-bit-computer/dynamicclock.ts

77 lines
2.4 KiB
TypeScript

// Clock generator component for the LogicSimulator used on the 8-bit-computer
// 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/>.
interface DynamicClockParam extends BaseComponentParam {
speed?: string;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class DynamicClock extends BaseComponent {
private q = false;
private clockState = false;
private speed: number;
private input = '';
private speedInput: HTMLInputElement | null = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private timer: any;
constructor(simulator: Simulator, id: string, param: DynamicClockParam) {
super(simulator, id, param);
this.pins.set('q', new TriState(this, 30, 0));
if (param.speed) {
this.speed = 0;
this.input = param.speed;
} else {
this.speed = 1;
}
}
tick() {
this.clockState = !this.clockState;
this.simulator.tick();
}
setup(canvas: SVGElement) {
super.doSetup('dynamicclock', canvas);
if (this.speed === 0) {
this.speedInput = <HTMLInputElement>document.getElementById(this.input);
if (this.speedInput) {
this.speedInput.addEventListener('change', this.changeSpeed.bind(this));
this.speed = parseFloat(this.speedInput.value);
this.timer = setInterval(this.tick.bind(this), 500 / this.speed);
}
} else {
this.timer = setInterval(this.tick.bind(this), 500 / this.speed);
}
}
update(): boolean {
const oldstate = this.q;
this.q = this.clockState;
this.getPin('q').setBool(this.q);
return oldstate !== this.q;
}
changeSpeed() {
if (!this.speedInput) return;
this.speed = parseFloat(this.speedInput.value);
clearInterval(this.timer);
this.timer = setInterval(this.tick.bind(this), 500 / this.speed);
}
close() {
clearInterval(this.timer);
}
}