[#314][#404] Audio Tape automation refactor and C4 architecture docs - #405
Merged
Conversation
- Reduce tape input mixing amplitude from MAX_SAMPLE_AMPLITUDE/10 to MAX_SAMPLE_AMPLITUDE/25 (40% of previous level) - Beeper volume unchanged
- Replace JList-based TimelinePanel with JTable (two columns: #, Event) - Remove custom TimelineCellRenderer with circle/connector painting - Add active row highlighting via prepareRenderer override - Update TapePlayerGui to use JTable API (getSelectedRow, setRowSelectionInterval, scrollRectToVisible) - Rename GUI icon resources for clarity
- Rename AutomationRunner to AutomationController - Add lifecycle states: PLAYING, STOPPED, CLOSED - Use ExecutorService instead of raw Thread - Add AutomationListener interface for state/index changes - Move event deserialization from runner to call sites - Replace Thread.sleep with preciseSleepNanos - Replace parseSeconds with RadixUtils.parseRadix - TapePlayerGui implements AutomationListener directly - Disable add/remove/move buttons during automation play - Update buttons when automation finishes via stateChanged - Add word wrap renderer to timeline event column - Rename automation toolbar icons to auto-* prefix - Add AutomationControllerTest with async state tests - Remove old AutomationRunnerTest
Add C4 model architecture documentation (context, containers, components, code) in AsciiDoc under docs/, with C4-PlantUML diagrams. Add a 'doc' Gradle task using the asciidoctor.jvm.convert plugin to render docs/ to HTML in docs/output/. Ignore the generated docs/output/ directory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
notifyStateChange() eagerly evaluated listener::stateChanged as the ifPresent argument, throwing NPE whenever no listener was set (headless automation via DeviceImpl.reset()). This broke stop(), close() and play-completion. Drain the queue and notify only when a listener exists, matching the null-guard already used in play(). Add regression tests for the no-listener path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace machine-specific local paths with GitHub links and instruct the agent to look for sibling repos as local checkouts, reporting when a repo is not available locally instead of guessing paths. Prepares the file for public availability. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AbstractMemoryStub's constructor invokes the overridable clear(), which TimingMemoryStub overrides to call clearCounters(). This ran before the subclass map fields were initialized, causing a NullPointerException in setUp() and failing 146 z80-cpu tests. Guard clearCounters() against the not-yet-initialized maps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR bundles work from two tickets:
doctask to render it to HTML #404 (Architecture docs): C4 architecture documentation, a Gradledoctask, andAGENTS.mdcleanup.Audio Tape Player automation (#314)
AutomationRunnerwith a newAutomationController:PLAYING,STOPPED,CLOSED).ExecutorServiceinstead of a raw thread.AutomationListenerinterface for state / current-index callbacks.preciseSleepNanosinstead ofThread.sleep;RadixUtils.parseRadixinstead of custom parsing.TimelinePanelas aJTable(index + event columns) with active-row highlighting and word-wrapped event text.AutomationControllerwhen no listener is set (headless automation): drain the queue and notify only when a listener exists; add regression tests for the no-listener path.Beeper).auto-*,play,stop,reset, …).AutomationRunnerTestwithAutomationControllerTest(async state coverage).Architecture documentation (#404)
docs/(context, containers, components, code, index) in AsciiDoc.doctask to render the docs to HTML (build.gradle).AGENTS.md: GitHub links instead of local paths, and instruct the agent to look for local checkouts and report when a repo is missing rather than guessing.Testing
:plugins:device:audiotape-player:test— all tests pass, including the newAutomationControllerTest.