Array of polygons for hash marks as three-dimensional array

Working on my first watch face, I've learned that I can create an array of polygons as a three dimensional array for hash marks, and it works OK INSIDE the for loop that I set the values in. I would like to compute the coordinates of the points only once if possible instead of every update, but OUTSIDE of the for loop all the top level array rows have the same value as the last row with the result being I have the same hash mark 60 times instead of 60 distinct hash marks. I can return a two-dimensional array from a function no problem so recomputing them every update is certainly possible (and what I'm resorting to now), but it seems inefficient if I could just store them. Is this a known "feature" so that I have to compute all the hash marks every update, or is there some trick to making this work? 

  • Where are you defining the array?  Inside onUpdate, inside the for loop?  Define it at the class level as null, and then only build it in onUpdate if it's null.  You can also save it in Application.Storage, and in initialize for your view, load it and that way you only build it once even if you leave the watch face and return.  I'm guessing a bit here as I haven't seen your code.

  • I started with the SDK Analog face; I'll have more questions about that later. I currently have the array defined at the class level as "var ring new [60] Array< Array< Array<Float or Number> > >, but I've tried every combination I can think of and I can't get it to work. The result is always the same. I have since learned that when I thought it was working in the loop what was really happening is that the 2D array built for fillPolygon that I was assigning to element "i" of the top level array was in fact being assigned to every row in the top level so the 2D array is repeated 60 times. When I put a System.println(ring) in the loop to show the array in the debug console it is formatted as a 3D array so the structure looks right. When I assign a coordinate pair in a two-element 1D array into a 2D array I have something like "var poly [4] as Array< Array<Float or Number> >" and I set elements using "poly[0] = myFunction(r, a):" which has a "return [x, y] as Array<Number>" at the end and it all just works. I assumed that the same concept would work the next level up. Maybe a dictionary with the index as the hashcode()? Maybe using some typedefs, which I can't seem to get the syntax right to get the compiler to take?

  • Add some System.println calls in your code so you can see what's happening.  They will show in your console.

  • Looks like I got it. It was the nulls I needed. Thanks for the help. Here's the code:

    class AnalogView extends WatchUi.WatchFace {
        private var polyTicks = new [60];
    
    // then further down
        public function onUpdate(dc as Dc) as Void {
    
    // and down some more
            targetDc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_TRANSPARENT);
            for (var k = 0; k <= 11; k += 1) {
                if (polyTicks[k*5] == null) {
                   polyTicks[k*5] = drawLgTick(k, bigR, 0.0, littleR, 0.02);
                }
            }
            for (var j = 0; j <= 59; j += 1) {
                if (polyTicks[j] == null) {
                    polyTicks[j] = drawSmTick(j, bigR, 0.0, littleR);
                }
                targetDc.fillPolygon(polyTicks[j]);
            }
    

    The arrays for the large ticks are four points whereas the small ticks are two, and even that is working. It turns out fillPolygon is conveniently the same as drawLine for two points.