Acknowledged

Add onTimerLapUndo() event to signify that the previous onTimerLap() event was undone

Background:

- newer watches give the user the ability to undo a manual lap by pressing the Down button while the lap banner is displayed (for 8 seconds)

Issue:

- any CIQ data field that tracks lap data will be negatively affected if and when a user undoes a lap, because apps aren't notified of this event

- this will cause CIQ data fields to calculate, display and write incorrect lap data following an undone lap

Request for CIQ changes:

- add onTimerLapUndo() event to the CIQ API, signifying that the previous lap event was undone

- add onTimerLapFinalized() event (for convenience) to the CIQ API, signifying that it's no longer possible to undo the previous lap event

- document what devs needs to do to handle lap undo properly (see next section)

What I think devs of CIQ data field apps would need to do (please correct me if I'm missing something):

- constantly maintain *two* sets of lap data at the same time: S_current_lap (the current lap data as if the current lap will not be undone), and S_previous_lap (the previous lap data, as if the current lap will be undone)

- when calculating and displaying lap data, or calling FitContributor.Field.setData() on a field of MESG_TYPE_LAP, continue to use values based on the apps *current conception* of the correct lap values. i.e. as long as the current lap is not undone, use S_current_lap. If and when the current lap is undone, copy/assign S_previous_lap to S_current_lap

(note that CIQ data fields need to be constantly calling setData() for fields of MESG_TYPE_LAP, as in the MoxyField SDK sample, since it's too late to call setData() in onTimerLap()).

- if onTimerLapFinalized() is implemented, this frees the dev from the burden of constantly maintaining two sets of lap data (they would only have to do so for up to the first 8 seconds of every lap). This would save battery life / CPU cycles, and possibly allow additional functionality due to having additional memory to spare (depends on whether that functionality can be restricted while a lap can be undone)

For example, assuming that the first activity lap is Lap 1, when onTimerLap() is triggered for the first time, the app now has to track/calculate data for both Lap 2 (the new lap) and Lap 1 (as if Lap 2 never existed). As long as Lap 2 is not undone, the data for Lap 2 should be displayed where applicable, and passed to FitContributor.Field.setData() for applicable MESG_TYPE_LAP fields. During this time, data for Lap 1 should still be tracked/calculated. If and when Lap 2 is undone, the app should start using the data for Lap 1 again (as if Lap 2 never existed).

Related discussion:

https://forums.garmin.com/developer/connect-iq/f/discussion/403749/what-event-is-triggered-when-a-lap-is-discarded/1899120#1899120

Parents
  • > And fit cotrib data for laps wasn't written to the fit file until that time too.

    This was also covered in the linked discussion.

    FIT contrib data is not a problem, as it can be handled in exactly the same way that native data is handled. Keep in mind that setData() does not cause data to be written, it only sets the next value to be written.

    I can think of two ways that the writing of native lap data can be handled in a way that works with undoing laps:

    1) Lap data is always written immediately (for either auto or manual laps - only manual laps can be undone, though). If the user undoes a manual lap, the firmware writes a marker to the FIT file telling the reader (e.g. Connect) to ignore the previous lap

    2) Lap data writes are delayed with an 8-second buffer in the case of a manual lap). (Presumably record data would have be delayed as well). If the user doesn't undo the lap after 8 seconds, then the lap data is finally written. If the user does undo the lap, then the lap data is not written (but the other data would be written).

    Personally I think 1) would be a better choice from a data integrity POV (so if the activity crashes, you don't run the risk of losing 8 seconds of data, although arguably 8 seconds is not a huge amount to lose). But whether the real implementation is 1) or 2), CIQ data field apps absolutely do not need to care, imo.

    Currently, for MESG_TYPE_LAP fields, CIQ data fields should be continuously calling setData() with the current lap value, just as in the moxyfield sample. It's well known that it's too late to call setData at onTimerLap() (although even if this were possible, it wouldn't change the situation with regards to handling lap undo).

    CIQ data fields can simply continue to call setData() continously with their conception of the current lap value - that part doesn't need to change at all, regardless of how the actual FIT field writes are implemented in firmware.

    The only thing devs would need to change would be to keep track of two sets of lap data (current and previous) during the time in which a lap can be undone, and to switch back to the previous lap data if and when the most recent lap event is undone.

Comment
  • > And fit cotrib data for laps wasn't written to the fit file until that time too.

    This was also covered in the linked discussion.

    FIT contrib data is not a problem, as it can be handled in exactly the same way that native data is handled. Keep in mind that setData() does not cause data to be written, it only sets the next value to be written.

    I can think of two ways that the writing of native lap data can be handled in a way that works with undoing laps:

    1) Lap data is always written immediately (for either auto or manual laps - only manual laps can be undone, though). If the user undoes a manual lap, the firmware writes a marker to the FIT file telling the reader (e.g. Connect) to ignore the previous lap

    2) Lap data writes are delayed with an 8-second buffer in the case of a manual lap). (Presumably record data would have be delayed as well). If the user doesn't undo the lap after 8 seconds, then the lap data is finally written. If the user does undo the lap, then the lap data is not written (but the other data would be written).

    Personally I think 1) would be a better choice from a data integrity POV (so if the activity crashes, you don't run the risk of losing 8 seconds of data, although arguably 8 seconds is not a huge amount to lose). But whether the real implementation is 1) or 2), CIQ data field apps absolutely do not need to care, imo.

    Currently, for MESG_TYPE_LAP fields, CIQ data fields should be continuously calling setData() with the current lap value, just as in the moxyfield sample. It's well known that it's too late to call setData at onTimerLap() (although even if this were possible, it wouldn't change the situation with regards to handling lap undo).

    CIQ data fields can simply continue to call setData() continously with their conception of the current lap value - that part doesn't need to change at all, regardless of how the actual FIT field writes are implemented in firmware.

    The only thing devs would need to change would be to keep track of two sets of lap data (current and previous) during the time in which a lap can be undone, and to switch back to the previous lap data if and when the most recent lap event is undone.

Children