Repository navigation
Code-Review-Umsetzung + Engineer-Bugfixes (v0.2.7) - #1
Merged
Merged
Conversation
…ineer task - reader: decode frame values via from_le_bytes instead of casting &[u8] to &[T] (unaligned reads were UB; Vec<u8> guarantees no alignment) - piper install: zip-slip protection via enclosed_name(), throttle download progress broadcasts to 250ms intervals - ws handler: a closed watch/broadcast channel disables that branch instead of killing the connection (fixes reconnect loop on non-Windows and removes the need for the update task's pending() keep-alive hack) - engineer task: piper/voice installs run in their own task instead of blocking the select loop; state backlog collapses to the newest snapshot so rules never fire on stale data in bursts - tts engine: drop dead keep-alive fields (piper_process was never spawned persistently); document per-request spawn trade-off - flags: per-car blue/debris bits corrected to official irsdk_defines.h values (0x0020/0x0040; previous 0x0400/0x0800 are greenHeld/tenToGo) — needs a live-session sanity check - protocol: box Telemetry/SessionInfo variants (enum was ~720B by value) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… allocations
- standings: drop the incident-source diagnostic block (built ~64
format! strings per 4 Hz tick guarded by two global mutexes)
- snapshot: tire var names as literal arrays instead of per-frame
format!() — the 60 Hz build path is now allocation-free per lookup
- delete events.rs (todo!() stub, never called) and broadcast.rs
(placeholder enum), drop unused Config::{telemetry_hz,standings_hz}
- scope #![allow(dead_code)] to non-Windows so the shipped Windows
build keeps real dead-code analysis
- dedupe track_key derivation (track_recorder + track_map)
- clippy: is_some_and/sort_by_key/needless-ref fixes, ?-operator
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le trait - sector_tracker: extract step_car() — update() and the unit tests now drive the identical production code path (the test helper used to mirror ~80 lines of logic that could silently diverge) - Rule trait: evaluate(&mut self) — rules are owned exclusively by the dispatcher inside one task, so the AtomicU32/AtomicBool interior- mutability workaround in the temp-change rules becomes plain fields; Sync bound dropped - engineer state: wire last_sector_deltas from the standings sector data (current lap vs personal best) — SectorDeltaRule could never fire before because the array was hardcoded to [None; 3] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- registry: memoize all widgets at the single render boundary — App re-renders per telemetry frame, but standings/track-map/session-info widgets only consume 4-15 Hz snapshots; with stable prop identities memo() skips them entirely - App: useMemo'd WidgetData object, useCallback'd onDeleteTrackMap; engineer-settings updates compute outside the setState updater (StrictMode runs updaters twice — side effects were doubled) - Dashboard: memoize the GridLayout layout array (was rebuilt per frame) - extract sofFromRatings() — the SoF formula lived in both Standings and SoF; translate leftover German UI string Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- useFuelTracker/useLapHistory: frame processing moves into effects; refs are bookkeeping only, render-visible results live in useState and commit only on real events (lap completed, session change, pit exit) — no per-frame renders, React-Compiler-compatible - TrackMap: settings/interp/data refs are now written in effects, not during render - Wind: previous-render angle unwrapping via the documented guarded setState-in-render pattern instead of ref mutation - SettingsPanel: voice list derived from props + optimistic overrides (replaces the prop→state mirror effect) - TrackMapSettings: confirm-delete armed state derived from hasMap - eslint: disable react-refresh/only-export-components (HMR granularity only; widgets co-locate settings constants by design); fix no-empty/ unused-vars - drop unused uplot dependency Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the scoped dead-code allow exposed real dead code on the shipped target: RADIO_CHECK_PHRASE (frontend has its own copy), var_index(), EngineerStateTx alias, unused CommandExt import (tokio's Command has creation_flags natively), never-constructed ServerMessage variants SdkStatus/Disconnected (removed from protocol + frontend cases) - placeholder surfaces (EngineerState/FlagState/DamageState fields, PitState::InBox, forecast minutes, LapCompletion) get documented targeted allows instead of a crate-wide one - var_header: string slicing now uses the IRSDK_MAX_* layout constants - CI: single sequential workflow — cargo test (exports gitignored shared/ ts-rs bindings) → clippy -D warnings → npm ci/lint/build Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…down signal With BRIDGE_KEEP_ALIVE=1 run_watcher returns immediately, dropping the oneshot sender. serve() treated the resulting RecvError like a shutdown request and exited at startup. An Err from shutdown_rx now means 'no watcher → never shut down'. Verified with a live server: three WS connect/disconnect cycles, HTTP stays up throughout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…itions
Four related bugs, all caused by taking iRacing telemetry at face value:
- Lap times announced one lap late: iRacing publishes LapLastLapTime
~1-2 s after the Lap counter increments, so latching the value at the
increment tick recorded the previous lap's time. The aggregator now
arms a pending latch on the increment and records once the value
actually changes (10 s timeout covers identical consecutive laps).
Lap-gated pace rules key off the new lap_just_completed flag instead
of comparing lap counters, so they evaluate with the fresh lap time.
Joining mid-session no longer records a stale lap as personal best.
- Final-lap call shifted by one lap: SessionLapsRemain is deprecated
and off by one; prefer SessionLapsRemainEx with fallback.
- Gap callouts repeated the start/finish-line gap: CarIdxF2Time only
refreshes at the line during races. Standings now carry CarIdxEstTime
(backend-only, not serialized) and live_gap() derives the current gap
with lap-wrap correction; F2Time remains as fallback. The trend
("closing"/"pulling away") now compares against the gap at the last
announcement instead of the 100 ms previous tick, which always read
"holding steady".
- Wrong position announced (P14 while running P15): live position
flickers during side-by-side running and TTS adds seconds of latency.
Position changes are now debounced for 3 s before announcing, and the
tracker resets outside the Racing phase so formation-lap shuffles and
session changes stay silent.
Adds unit tests for the lap-time latch and live-gap math.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.
Bridge correctness (reader.rs from_le_bytes, ZIP slip protection, WS handler survives closed channels, non-blocking engineer installs, BRIDGE_KEEP_ALIVE fix), Perf (boxed ServerMessages, throttled download progress, widgets via React.memo → 4 Hz instead of 60 Hz), refactors (sector_tracker step_car, Rule-Trait &mut self, ESLint 0 errors, uplot removed), CI workflow.
Plus engineer bug fixes: Lap time latch, SessionLapsRemainEx, Live Gap with lap wrap, StablePositionTracker.