Files
logic-gates/js/simulation.js
Jose Luis Montañes 7409a96cf1 refactor: modularize into ES6 modules
Split monolithic index.html into:
- js/constants.js - gate config, colors, dimensions
- js/state.js     - shared application state
- js/gates.js     - evaluation logic, port geometry
- js/renderer.js  - canvas drawing
- js/waveform.js  - GTKWave-style signal viewer
- js/simulation.js - clock tick engine
- js/events.js    - mouse, keyboard, UI handlers
- js/app.js       - entry point
- css/style.css   - all styles
2026-03-19 22:00:02 +01:00

67 lines
2.0 KiB
JavaScript

// Clock simulation engine
import { state } from './state.js';
import { evaluateAll } from './gates.js';
import { forceRecordSample } from './waveform.js';
export function simTick() {
// Toggle all CLOCK gates
state.gates.forEach(g => {
if (g.type === 'CLOCK') {
g.value = g.value ? 0 : 1;
}
});
evaluateAll();
// Force record even if evaluateAll didn't detect change
if (state.recording && state.waveformVisible) {
forceRecordSample();
}
}
export function startSim() {
if (state.simRunning) return;
const hasClocks = state.gates.some(g => g.type === 'CLOCK');
if (!hasClocks) { alert('Place a CLOCK gate first!'); return; }
state.simRunning = true;
// Auto-open waveform panel
if (!state.waveformVisible) {
state.waveformVisible = true;
document.getElementById('waveform-panel').classList.add('visible');
document.getElementById('sim-btn').classList.add('active');
// Trigger resize via event so renderer picks it up
window.dispatchEvent(new Event('resize'));
}
state.simInterval = setInterval(simTick, state.simSpeed);
updateSimUI();
}
export function stopSim() {
state.simRunning = false;
if (state.simInterval) clearInterval(state.simInterval);
state.simInterval = null;
updateSimUI();
}
export function updateSimUI() {
const btn = document.getElementById('sim-run-btn');
if (state.simRunning) {
btn.textContent = '⏹ Stop';
btn.classList.add('active');
} else {
btn.textContent = '▶ Run';
btn.classList.remove('active');
}
document.getElementById('sim-speed-label').textContent = `${state.simSpeed}ms`;
}
export function adjustSpeed(delta) {
state.simSpeed = Math.max(50, Math.min(2000, state.simSpeed + delta));
if (state.simRunning) {
clearInterval(state.simInterval);
state.simInterval = setInterval(simTick, state.simSpeed);
}
updateSimUI();
}