Skip to content

Fix: Replace polling with async runtime events#51

Merged
phranck merged 8 commits into
mainfrom
issue/9-async-event-loop
Jul 20, 2026
Merged

Fix: Replace polling with async runtime events#51
phranck merged 8 commits into
mainfrom
issue/9-async-event-loop

Conversation

@phranck

@phranck phranck commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replace the synchronous MainActor polling loop with serialized runtime events for state, input readiness, signals, animation deadlines, and shutdown.
  • Use dispatch-backed signal and input sources, monotonic injectable deadlines, and deterministic source/task/terminal cleanup.
  • Retry interrupted reads and interrupted or partial writes, then surface permanent terminal I/O failures after cleanup.
  • Update runtime tests and DocC for the event-driven architecture.

Closes #9

Checklist

  • Swift 6.0 compatible (no features requiring a newer compiler)
  • Builds on macOS and Linux (swift build succeeds on both)
  • All tests pass (swift test)
  • No new SwiftLint warnings (swiftlint)
  • Public APIs match the reviewed TUIkit/SwiftUI surface
  • Modifiers propagate through the View hierarchy

Test Plan

  • Full macOS quality gate with Xcode 16.2 / Swift 6.0.3: 1,238 tests, strict lint, compile contracts, consumer build, and DocC.
  • Full Linux quality gate in the pinned Swift 6.0.3 container: 1,238 tests, strict lint, compile contracts, consumer build, and DocC.
  • Added focused coverage for MainActor .task progress, idle suspension, real signal/input delivery, injected animation deadlines, interrupted and partial terminal I/O, permanent I/O errors, and shutdown cleanup.

phranck added 7 commits July 20, 2026 00:32
- Replace MainActor polling with a serialized async event channel.
- Deliver terminal input and POSIX signals through Dispatch sources.
- Cover task resumption and macOS/Linux event delivery.
- Derive focus and cursor phases from an injectable ContinuousClock.
- Keep one deadline task only while visible focus animation is active.
- Verify idle runtimes stay asleep and phase timing is deterministic.
- Route terminal I/O through injectable POSIX calls.
- Allow isolated descriptors in integration tests.
- Preserve current terminal behavior.
- Retry interrupted reads and interrupted or partial writes.
- Preserve the first permanent POSIX failure for runtime handling.
- Cover retry, partial-write, and hard-error behavior.
- Throw terminal I/O failures from the asynchronous app entry point.
- Restore terminal state before propagating runtime failures.
- Verify error propagation and cleanup through AppRunner.
- Confirm shutdown cancels active view tasks.
- Assert raw mode, cursor state, and alternate screen are restored.
- Replace polling and signal-flag descriptions with runtime events.
- Document idle suspension, deadline scheduling, and deterministic cleanup.
- Clarify terminal retries and animation phase behavior.
- Keep the public App.main symbol compatible with SwiftUI.
- Run the asynchronous application runtime through dispatchMain.
- Report runtime failures before returning a nonzero exit status.
@phranck
phranck merged commit 9f9aaed into main Jul 20, 2026
6 checks passed
@phranck
phranck deleted the issue/9-async-event-loop branch July 20, 2026 07:42
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.

[P0-04] Replace polling and unsafe signal flags with an async event source

1 participant