Skip to content

♻️ Introduce explicit PlaybackState machine#288

Merged
Gudsfile merged 5 commits into
mainfrom
refactor/playback-state-machine
Jun 20, 2026
Merged

♻️ Introduce explicit PlaybackState machine#288
Gudsfile merged 5 commits into
mainfrom
refactor/playback-state-machine

Conversation

@Gudsfile

@Gudsfile Gudsfile commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replace PlaybackSession (flat mutable Pydantic model) with PlaybackState = Idle | Playing | Waiting | Paused frozen dataclasses. Illegal states are now unrepresentable by construction.
  • Extract all transition logic into a pure transition(state, tag_event, disc, ctx) function: no I/O, no mocks needed in tests.
  • HandleTagEvent becomes a thin executor: resolve disc, call transition(), execute player command, manage retry state via RetryState.
  • Delete DetermineAction, PlaybackSession, PlaybackCommandRetry, PlaybackAction (replaced entirely).

Test plan

Tested end-to-end with --player pn532 --reader dryrun: PLAY, CONTINUE, WAITING, PAUSE transitions confirmed in logs

Base

Stacks on #287.

@Gudsfile Gudsfile changed the title Introduce explicit PlaybackState machine (Chantier 2) Introduce explicit PlaybackState machine Jun 20, 2026
@Gudsfile Gudsfile force-pushed the refactor/playback-state-machine branch 2 times, most recently from 5636ed3 to a159cf9 Compare June 20, 2026 13:17
@Gudsfile Gudsfile changed the title Introduce explicit PlaybackState machine ♻️ Introduce explicit PlaybackState machine Jun 20, 2026
Base automatically changed from refactor/decouple-current-tag-sync to main June 20, 2026 15:21
@Gudsfile Gudsfile force-pushed the refactor/playback-state-machine branch 3 times, most recently from 3b86c20 to ead4424 Compare June 20, 2026 15:51
@Gudsfile Gudsfile self-assigned this Jun 20, 2026
@Gudsfile Gudsfile force-pushed the refactor/playback-state-machine branch 3 times, most recently from d622a99 to 91944d0 Compare June 20, 2026 18:31
@Gudsfile Gudsfile marked this pull request as ready for review June 20, 2026 18:37
@Gudsfile Gudsfile force-pushed the refactor/playback-state-machine branch 2 times, most recently from 217c9df to f964b66 Compare June 20, 2026 20:03
Gudsfile added 5 commits June 20, 2026 22:11
Replaces flat PlaybackSession fields with sum-type states: Idle, Playing,
Waiting, Paused — each frozen dataclass carrying only the fields it needs.
Illegal states (e.g. paused_at without playing_tag) are now unrepresentable.

RetryState replaces PlaybackCommandRetry; TransitionContext and PlaybackCommand
introduced alongside.
Maps (PlaybackState, TagEvent, Disc | None, TransitionContext) to
(success_state, command) without any I/O. Command is one of
play | pause | resume | stop | None; the caller executes it.
HandleTagEvent is now a thin executor: resolves disc, calls the pure
transition() function, executes the player command, manages retry state.
DetermineAction is replaced by TransitionContext (config bundle).

PlaybackSession replaced by PlaybackState (Idle | Playing | Waiting | Paused)
throughout CLIController, di_container, and all call sites.
…backAction

All replaced by the PlaybackState sum type and transition() function.
@Gudsfile Gudsfile force-pushed the refactor/playback-state-machine branch from f964b66 to 93fd5e0 Compare June 20, 2026 20:12
@Gudsfile Gudsfile merged commit 768ad2e into main Jun 20, 2026
5 checks passed
@Gudsfile Gudsfile deleted the refactor/playback-state-machine branch June 20, 2026 20:18
Gudsfile added a commit that referenced this pull request Jun 20, 2026
## Summary

Applies the same architectural pattern as the PlaybackState machine
(#288) to the current-tag feature.

- Add `NoTag | TagPresent | TagRemoved` frozen dataclasses and
`CurrentTagContext` config bundle
- Add pure `transition_current_tag(state, tag_event, ctx)` function
- Rewrite `SyncCurrentTag` as a thin executor: calls
`transition_current_tag`, executes repository command, stamps
`last_event_timestamp` unconditionally on return
- Update `CLIController` to thread `CurrentTagState` as an immutable
return value instead of mutating a session
- Delete `DetermineCurrentTagAction`, `ApplyCurrentTagAction`,
`CurrentTagAction`, `CurrentTagSession`
- Rename `transition` to `transition_playback` so both pure functions
are self-describing at their call sites
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant