// 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 . 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 = 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); } }