fr955: Crash when overusing onDrag();

Heya !


I'm working on a 'lil watch app (device-app) and I'm encountering an issue when the user drags on the screen.

I want to find out the direction of the drag ( x or y ) and change some variables according to it while the user is dragging. The code I have so far works perfectly, but if the user drags multiple times or in quick succession, the watch crashes with no debug output; just a blue triangle.

My code is below -- I've tried to keep it as simple as possible, but it is a bit nested. Is it the case that the watch can't process fast enough or is it an issue with my code ?

Thanks !!

[ P.S. It's not in a code block because whenever inserting one, the website tells me that my IP has been blocked, even though that is not the case. Maybe it's too much code ? ]

Delegate.mc:

class Delegate extends WatchUi.BehaviorDelegate {
// ...
    function onDrag(dragEvent) {

        if(!gameStarted) {

            switch(dragEvent.getType()) {

                case 0: // New tap
                    startX = dragEvent.getCoordinates()[0];
                    startY = dragEvent.getCoordinates()[1];
                    System.println(dragEvent.getCoordinates()[0] + ", " + dragEvent.getCoordinates()[1]);
                    break;
                case 1: // Dragging

                    deltaX = (dragEvent.getCoordinates()[0] - startX);
                    deltaY = (dragEvent.getCoordinates()[1] - startY) * -1; // Y-Axis is inverted.

                    switch(axis) {
                        case "N":

                            /*
                            .abs function doesn't work with "Number/Method" variables -- deltaX.toNumber().abs doesn't work either.
                            absX and absY are just placeholder variables representing the absolute value. This is my solution until I find something more elegant
                            */
                            if(deltaX < 0) {
                                absX = deltaX * -1;
                            } else {
                                absX = deltaX;
                            }

                            if(deltaY < 0) {
                                absY = deltaY * -1;
                            } else {
                                absY = deltaY;
                            }

                            if(absX > swipeThreshold || absY > swipeThreshold) {

                                System.println(deltaY + ", " + deltaX);

                                if(absX > absY) {
                                    axis = "X";
                                } else {
                                    axis = "Y";
                                }

                            }

                            break;
                        case "X":
                            System.println("x: " + dragEvent.getCoordinates()[0]);
                            // TODO: Add Increment for every N units in the x-axis
                            break;
                        case "Y":
                            System.println("y: " + dragEvent.getCoordinates()[1]);
                            // TODO: Add Time for every N units in the y-axis
                            break;
                    }
                    break;
                case 2: // End drag
                    axis = "N";
                    break;
            }
        } else if(dragEvent.getType() == 0) { // Ease of use; An accidental drag while the game is going shouldn't disrupt the game. [ The watch screen is already hard enough to tap . . ]
            changeSidesAndAddIncrement();
        }
        return true;
    }
}
// ...

  • What device? real or sim? what SDK version?

    Is it intentional that axis only gets value when you finish the drag? So it's only used in the switch in the next drag? Not sure if it's just because you removed unrelated code, or this is really the case. What is it's value the 1st time onDrag is called?

    Add print in all the possible code branches, then make it crash and look at the last few lines, that'll give you an idea where it crashes, even if there's no stack trace.

    Also can you post more details in a separate thread (so we don't mix 2 things) about the abs issue you have?

  • Aye, sorry for not elaborating. I'll walk through the code and what each part is for

    As in the title, this is on a Forerunner 955 [ sim ]. I'm using SDK version 8.1.1 on Linux

    --

    When dragEvent.getType() == 0, it means that a drag has just started, and this is the origin point. startX and startY store these values

    When dragging before the game has started, it checks axis. "N" is the default value.
    If "N", it checks if the absolute value of the difference between the start and current points of the drag are greater than 10. If so, "axis" is set to x or y based off if absX or absY is greater.

    After the drag ends, axis is reset to "N" so that a new drag can start.

    It always crashes after the entire onDrag() function has concluded. Most likely on "return true;". Again though, it doesn't crash every time a drag happens; only when multiple drags occur in a short time or when many drags have occurred.

  • Strange. I would expect some bug in your code that causes some null pointer exception or some illegal value or whatever, but all these would create a usable stack trace.

    So my next guess is that it's not crashing. I think you just exit the app. Add a log in onStop() of the app. And if you have onBack(), then add a log there too. If not, then add one:

    onBack() {
      System.println("onBack");
      return false;
    }

    And if you change it to return true, then maybe you won't see the blue triangle...

  • Damn, good call ! Something is exiting the app after onDrag() concludes

    I wish I had more time to test right now, but I'm aught to go to Guitar lessons. Can't just post the code because the website throws an error if my message is too large. I'll try running it on my actual watch when I get back though ! I'll keep ya posted

    Thanks mate

  • Just got back from lessons and loaded it onto my watch. The issue became pretty clear with what you told me when I tried it out.

    Every app that isn't a built-in activity will close if you swipe right, regardless of if drags are handled. I guess it counts as both a swipe and a drag ? Regardless, adding the following to Delegate.mc now prevents that behaviour:

    function onSwipe(swipeEvent) {
        return true;
    }


    You have my infinite thanks !! <3