Looping Attention.vibrate function

Hey,

I'm trying to create a simple vibrating metronome for Garmin Venu 3. (No app available for this model in the store)

What I do (I suppose) in the code is: in MetronomeDelegate.mc I define keyState variable to false and set vibeData array with VibeProfiles. Next, if the right swipeEvent is executed I do the vibration while keyState is false. If keyState 4 appears the vibration should stop. 

Expected result is that the vibration continiues until the button 4 is pressed. However what I'm expiriencing is only 4 vibrations defined in vibeData array.

Code:

import Toybox.Lang;
import Toybox.WatchUi;
import Toybox.Application;
import Toybox.Lang;
import Toybox.System;
class MetronomeDelegate extends WatchUi.BehaviorDelegate {
    var      vibeData =
                [
                    new Attention.VibeProfile(75, 50),
                    new Attention.VibeProfile(0, 950),
                    new Attention.VibeProfile(50, 50),
                    new Attention.VibeProfile(0, 950),
                    new Attention.VibeProfile(50, 50),
                    new Attention.VibeProfile(0, 950),
                    new Attention.VibeProfile(50, 50),
                    new Attention.VibeProfile(0, 950),                
                ];
    var keyState = "false";
   
               
    function initialize() {
        BehaviorDelegate.initialize();
    }
    function onSwipe(swipeEvent) {
        System.println(swipeEvent.getDirection());
        if (swipeEvent.getDirection() == 0) {
        WatchUi.pushView(new Rez.Menus.MainMenu(), new MetronomeMenuDelegate(), WatchUi.SLIDE_UP);
        return true;
        }
        else if (swipeEvent.getDirection() == 2) {
            keyState = "false";
            vibrations(vibeData);
           
            return true;
        }
        else {
            return true;
        }
    }
    function vibrations(vibeData) {
        do {
            Attention.vibrate(vibeData);
            }
        while (keyState == "false");
    }
 
    function onKey(keyEvent) {
            System.println(keyEvent.getKey());  
            if (keyEvent.getKey() == 4) {
                keyState = "true";
                System.println(keyState);
            return true;
            }
            else {
                keyState = "false";
                return false;
            }
        }  
}



Is there a way to make vibration work until button 4 is pressed?
Thank you for your answers in advance!

Best,
Mateusz

  • Unfortunately, since the forums are broken, I resorted to putting my entire comment (except for this part), in a screeenshot. Thanks Garmin!

  • In the following example, the app, view and delegate classes are together, although in practice, each class would probably be in a different file.

    https://pastebin.com/yqLKt80P

  • In the above example, onUpdate() should be onUpdate(dc as Graphics.Dc) as Void, or at the very least, onUpdate(dc).

    The example omits types in a few places, as well as any details that aren't relevant or are unknown (e.g. the rest of MetronomeApp and MetronomeView.)

    But the basic ideas are:

    - the delegate receives a reference to the view

    - the view provides vibe-related functions for the delegate to call (the delegate doesn't need to know anything about the implementation of said functions)

    - the view uses a timer to trigger onUpdate once per second

    - every second, onUpdate triggers a vibration (if necessary) and renders the UI