Lap function: double-click Select, CMD_LAP, brief summary, phone-side in progress (#46) #115
No reviewers
Labels
No labels
area:companion
area:docs
area:shared
area:tooling
area:watchapp
blocker
kind:chore
kind:feature
kind:spike
kind:test
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
robert/PedalPebble!115
Loading…
Reference in a new issue
No description provided.
Delete branch "area/lap-function"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lap function (#46)
Implements the button gesture + state machine + wire usage + brief on-watch summary for marking a
lap mid-ride. The wire contract this needed (
RIDE_CMD_LAP,LAP_NUMBER/LAP_DISTANCE_M/LAP_TIME_S/LAP_AVG_SPEED_MMS, keys 30-33) was already fully specified and code-generated byissue #7 — this PR wires real code to it, it does not add any new message keys.
Status
Follow-up commits will land here before this is ready to merge. Opening now per request rather than
waiting, since the watch half is independently complete and verified.
Watch side
watchapp/src/c/state.h/state.c:ride_state_lap_mark(time_t now)queuesRIDE_CMD_LAPon thesame D43 dropout-survival command queue start/pause/stop already use — only while
RIDE_STATE_RUNNINGand no stop confirmation pending. Touches noRideStateSnapshotfield and doesnot set
checkpoint_dirty: "without disturbing the ride state" holds literally, not just in spirit.watchapp/src/c/ride_link.h/ride_link.c:ride_link_lap_mark()wraps it with a vibration and animmediate send attempt;
ride_link_handle_inbox()now also decodes the four inbound lap keys intofield_storeand callscarousel_show_lap_summary()the moment they arrive.watchapp/src/c/carousel.h/carousel.c: double-click Select is the chosen gesture. An audit ofevery button's existing single/long bindings (#60) found every slot already claimed — double-click is
the one SDK click type nothing in this app used yet, and it composes cleanly with the existing
subscriptions on Select.
carousel_show_lap_summary()shows a QUAD-template overlay (the fourFIELD_LAP_*ids #7 already reserved) for 4 seconds, or until any button press, then returns towhatever page was already showing.
watchapp/tests/test_state.c: 7 new host tests (no-op cases, queue-share/queue-full behaviour, andthat every persisted snapshot field is bit-for-bit unchanged across a lap mark).
docs/DECISIONS.mdD65: records the gesture audit, the phone-computes/watch-displays split, theoverlay-not-a-page design, the GPX point-marker-not-a-new-segment call for the companion side, and
the #4 (PebbleKit transport) gap stated below.
Known scope gap, stated plainly
Issue #4 (the real PebbleKit Android transport) is still open and explicitly gates Phase 2 —
PebbleTransportis currently a placeholder interface with no real inbound/outbound AppMessage pathon the phone side at all. That means "laps sent to the phone" cannot be a genuine Bluetooth round trip
yet. The watch side above is real and independently verified (see below); the phone side is pure,
host-tested logic (lap-split computation reusing
DerivedMetrics' average-speed definition, a GPXpoint-level lap marker, a Room
lapstable + migration, a lap list in ride history) with a named seamfor #4 to call once it lands — not a fabricated Bluetooth round trip.
Verified for real
state.c(compiled directly withgcc -std=c11 -Wall -Wextra -Werror, mirroringtests/CMakeLists.txt's flags exactly —cmakeitself isn't installed in thissandbox).
pebble build: emery/gabbro/basalt all link clean. Static RAM cost is 796 bytes on everytarget (117820 -> 117024 bytes free heap on emery/gabbro, 52284 -> 51488 on basalt, measured by
diffing against a stashed pre-change build) — no new dynamic allocation anywhere in this change.
pebble emu-button click select --repeat 2 --interval 100for a genuine double-click and confirmed viapebble logsthat exactly oneCMD=4(RIDE_CMD_LAP) was queued, not two start/pause commands — proving the gesture doesn'tcollide with #60's existing bindings; injected a synthetic
STATE_ACKand the fourLAP_*fieldsvia
pebble send-app-messageand screenshotted the real, rendered QUAD summary; confirmedauto-dismiss after ~4s back to the prior page; confirmed a button press mid-overlay dismisses it
without also performing its own action; confirmed the ride state was
RUNNINGthroughout byobserving a subsequent single Select press correctly send
CMD=1(pause).Companion-side test/build output will be added in a follow-up comment once those commits land.