Persisting graph display through onShow

Hi everyone,

I developed a water level graph (for tides) using drawRectangle(). It's made of 28 rectangles, covering 24 hours.

I would like to persist the display of this graph, however when I copy paste the related code from onUpdate() to onShow(), I get a out of memory error.

The code is pretty thick as I have several nested IFs per rectangle.

Am I supposed to copy the whole code?

Thanks,

Nico

  • Sounds like you're tight on memory.  When you can run, what do you see for peak memory with view memory in the sim?

  • Hi Jim,

    There you go : 

    Memory Usage:  121 / 124.0kB

    Peak Memory : 122.9kB

    Object Usage : 75/65535

    Peak Objects : 99

  • The issue is simply that your app is too big and when you coped the code, having it in two places, you exceeded what's available.  Your peak is 122.9k so you only have 1.1k left.

  • Ok. 

    What are the best / easiest ways of saving memory? By the way I'm already using the Analog hand hack to avoid haing to load PNGs.

    I'm figuring out I have to delcare variables as global to make sure they can be used from onUpdate AND onShow. This goes against memory saving does it?

  • There are a number of threads here about reducing memory, but much depends on your specific app.  Bitmaps can take a bunch of memory based on their size and the pallet used. Custom fonts will also take more memory than native fonts.

    Even at 124k max some devices don't even have that high a limit.

    I suspect you're going to have to really dig into your code and rethink how you are doing things.  Just to give you some numbers, my most complex app with12 different screens is sitting at about 100k.  One of my widgets with a background service to get data from the web, with a glance view, is about 50k.

  • Wow....

    Yes indeed. I'm using a large amount of IFs to display this graph. Can you confirm their is no way to include display functions into FOR loops? From what I understand the onUpdate function is read constantly right? 

    The only bmp I use is my background. I'm going to work to make it simpler

  • what type of app?

    In the one I mentioned with 12 screens (100k), there are 4 different graphs as well as a breadcrumb display of the route so far.

    You can use for loops anyplace.  The problem you could run into is if you run too long and trigger the watchdog timer.  I use for loops all the time.

  • Ok. I just saved 40kb just by cleaning my code and  resizing my background.
    I'll have a look into using FOR loop. At first I thought I couldn't. 
    I ended up using 28 IFs as shown here under.

    From what I remember I couldn't run this display using FOR loops.

    This is used to compute the size rectangle and display the outline or a filled rectangle if the rectangle represents the current time.

    https://ibb.co/3pDzW8S


    If you have any idea please let me know : 

    		if ( DisplayWLGraph == true){
    		
    						// Initialises the Xpos of the first rectangle (0).
    						drawRectangleXPos = WLRectangleXPos0 +  (WLRectangleWidth*0);
    				        if(BlueRectangleIndex <= DayHrsin28Min[0]){
    				        						// Normal (White outline) Rectangle 
    				        						dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
    				        						dc.drawRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[0] + WaterLevelGraphHeightConst, WLRectangleWidth ,  WLYTopPos - ProcessedHeight[0] + WaterLevelGraphHeightConst );
    				        						
    				        						// Fills rectangle with BLUE if rectangle = now
    				        						dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
    				        						dc.fillRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[0] + WaterLevelGraphHeightConst + RectangleOutlineHeightMargine , WLRectangleWidth-RectangleOutlineWidthMargine ,  WLYTopPos - ProcessedHeight[0] + WaterLevelGraphHeightConst );
    				        						}
    						else {dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
    							  dc.drawRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[0] + WaterLevelGraphHeightConst , WLRectangleWidth ,  WLYTopPos - ProcessedHeight[0] + WaterLevelGraphHeightConst );
    							 }
    						
    						
    
    						drawRectangleXPos = WLRectangleXPos0 +  (WLRectangleWidth*1);
    				        if((DayHrsin28Min[0] < BlueRectangleIndex) & (BlueRectangleIndex <= DayHrsin28Min[1])){
    				        						// Normal (White outline) Rectangle 
    				        						dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
    				        						dc.drawRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[1] + WaterLevelGraphHeightConst, WLRectangleWidth ,  WLYTopPos - ProcessedHeight[1] + WaterLevelGraphHeightConst );
    				        						
    				        						// Fills rectangle with BLUE if rectangle = now
    				        						dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
    				        						dc.fillRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[1] + WaterLevelGraphHeightConst + RectangleOutlineHeightMargine , WLRectangleWidth-RectangleOutlineWidthMargine ,  WLYTopPos - ProcessedHeight[1] + WaterLevelGraphHeightConst );
    				        						}
    						else {dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
    							  dc.drawRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[1] + WaterLevelGraphHeightConst , WLRectangleWidth ,  WLYTopPos - ProcessedHeight[1] + WaterLevelGraphHeightConst );
    							 }
    							 
    							 
    							 
    				         drawRectangleXPos = WLRectangleXPos0 +  (WLRectangleWidth*2);
    				        if((DayHrsin28Min[1] < BlueRectangleIndex) & (BlueRectangleIndex <= DayHrsin28Min[2])){
    				        						// Normal (White outline) Rectangle 
    				        						dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
    				        						dc.drawRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[2] + WaterLevelGraphHeightConst , WLRectangleWidth , WLYTopPos - ProcessedHeight[2] + WaterLevelGraphHeightConst );
    				        						
    				        						// Fills rectangle with BLUE if rectangle = now
    				        						dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLACK);
    				        						dc.fillRectangle(drawRectangleXPos + RectangleOutlineXOffset, WLYTopPos - ProcessedHeight[2] + WaterLevelGraphHeightConst + RectangleOutlineHeightMargine , WLRectangleWidth-RectangleOutlineWidthMargine , WLYTopPos - ProcessedHeight[2] + WaterLevelGraphHeightConst );
    				        						}
    						else {dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
    							  dc.drawRectangle(drawRectangleXPos, WLYTopPos - ProcessedHeight[2] + WaterLevelGraphHeightConst, WLRectangleWidth , WLYTopPos - ProcessedHeight[2] + WaterLevelGraphHeightConst );
    							 }
    				        
    				        ...
    				        

  • Also, when onShow does not take any (dc as Dc) argument.

    By any chance do you know how I can make my dc.drawRectangle() calls work in there?

  • my onShow() function typically have nothing in them.  And yes you aren't passed the dc with onShow()

    Why do you want to move your code from onUpdate() to onShow()?  Aren't you using WatchUi.requestUpdate() at times?