none
GraphicsWindow draw image isn't drawing every image RRS feed

  • Question

  • MXK111

    Hello

    Every now and then this program reads the line of code to Draw a Resized image onto the GW but doesn't do it. The result is that the program stalls for a second, skips a draw (can see this in the TW), and then draws the next one.

    The pics are d/loaded in the b/ground using a Tick once Timer thread. I included some code to prevent the program using the same variable at the same time, although this doesn't seem to make difference.

    So, I've got 2 questions:

    1. why does it refuse to draw an Image every now & then?; and
    2. is it a good idea to put some code in to prevent simultaneously using/setting a variable? (in this case b/w the Event loop and the Timer thread).
    Saturday, December 7, 2013 9:39 PM
    Moderator

Answers

  • Multi-threading is a complex affair in any programming and especially in SmallBasic since it was not designed with the required control to really do it.

    I believe that threaded subroutines (events and timer) are not re-entrant.  They will not be recalled before they have finished doing the last call, so sometimes an event sub may not be called if is still running. However they are queued and can build up out of control waiting to call the event sub (I think).

    Also all SmallBasic variables are global so the answer to point 2 is yes, but for simple non arrays you are probably OK sharing them.  Main problems are array indices etc.

    On question 1 you are trying to pass control between threads using global variables like "inUse" and "drawQuickPic".  Possibly the problem is that the main runEventLoop does not start until Buffering is finished (i.e buffer <= totalPicsLoaded).  buffer =5, so the first 5 are downloaded before the main loop starts.  From then on it works OK I think downloading and displaying when it can.

    This is quite complicated - the structure is good, but is hard to debug (all multi threading is). 

    I had a go at a basic version - just the treading bits.

    gw = 600
    gh = 600
    GraphicsWindow.Width = gw
    GraphicsWindow.Height = gh
    numImage = 0
    maxImage = 20
    imageKeyword = "car"
    
    Timer.Interval = 10 'Short is fine since it is paused until finished
    Timer.Tick = OnTick
    
    While ("True")
      If (numImage > 0) Then
        i = Math.GetRandomNumber(numImage)
        image = images[i]
        GraphicsWindow.DrawResizedImage(image,0,0, gw, gh)
        GraphicsWindow.Title = "Image "+i+" of "+numImage
      EndIf
      Program.Delay(100) 'Fast update
    EndWhile
    
    Sub OnTick
      Timer.Pause() ' Pause the time to prevent recalling it untill we are finished
      images[numImage+1] = ImageList.LoadImage(Flickr.GetRandomPicture(imageKeyword))
      numImage = numImage+1
      Timer.Resume() 'Restart the time to get the next image
      If (numImage = maxImage) Then 'We have do all the images we want so pause Timer completely
        Timer.Pause()
      EndIf
    EndSub

    Sunday, December 8, 2013 6:43 PM
    Moderator
  • As another thing I noticed - a big delay every so often.

    This is a simple (and slightly better) version of the test code, SPD246.

    Apart from just calling the timer once and doing everything in one call to the timer sub, I added a variable 'count' to be updated every time an image is drawn.

    We can see that the delay occurs every 100 images drawn.  This is because SB rasterises all Drawn objects to an image every time there are 100 drawn objects added.

    The rasterising, just takes all the current drawn images (last 100) and combines them into a single background image for performance reasons, but does introduce a delay that might also be affecting your program.


    Sunday, December 8, 2013 9:05 PM
    Moderator

All replies

  • Multi-threading is a complex affair in any programming and especially in SmallBasic since it was not designed with the required control to really do it.

    I believe that threaded subroutines (events and timer) are not re-entrant.  They will not be recalled before they have finished doing the last call, so sometimes an event sub may not be called if is still running. However they are queued and can build up out of control waiting to call the event sub (I think).

    Also all SmallBasic variables are global so the answer to point 2 is yes, but for simple non arrays you are probably OK sharing them.  Main problems are array indices etc.

    On question 1 you are trying to pass control between threads using global variables like "inUse" and "drawQuickPic".  Possibly the problem is that the main runEventLoop does not start until Buffering is finished (i.e buffer <= totalPicsLoaded).  buffer =5, so the first 5 are downloaded before the main loop starts.  From then on it works OK I think downloading and displaying when it can.

    This is quite complicated - the structure is good, but is hard to debug (all multi threading is). 

    I had a go at a basic version - just the treading bits.

    gw = 600
    gh = 600
    GraphicsWindow.Width = gw
    GraphicsWindow.Height = gh
    numImage = 0
    maxImage = 20
    imageKeyword = "car"
    
    Timer.Interval = 10 'Short is fine since it is paused until finished
    Timer.Tick = OnTick
    
    While ("True")
      If (numImage > 0) Then
        i = Math.GetRandomNumber(numImage)
        image = images[i]
        GraphicsWindow.DrawResizedImage(image,0,0, gw, gh)
        GraphicsWindow.Title = "Image "+i+" of "+numImage
      EndIf
      Program.Delay(100) 'Fast update
    EndWhile
    
    Sub OnTick
      Timer.Pause() ' Pause the time to prevent recalling it untill we are finished
      images[numImage+1] = ImageList.LoadImage(Flickr.GetRandomPicture(imageKeyword))
      numImage = numImage+1
      Timer.Resume() 'Restart the time to get the next image
      If (numImage = maxImage) Then 'We have do all the images we want so pause Timer completely
        Timer.Pause()
      EndIf
    EndSub

    Sunday, December 8, 2013 6:43 PM
    Moderator
  • Hi Litdev, thanks for your reply and helpful sample.

    Briefly, on another note, but perhaps relevant feedback to a learning forum:

    I recently joined a Math forum and I'm amazed at how useful, well administered and moderated these forums are. It's great to see how things change for the better. While some are busy packing their bags to board Mars 1 and the like, all are being freed of adversity. Thanks in part to the internet.

    It's amazing. When I was a kid I saw decimation now I see this: http://www.wbacc.gov.au/content/gudjahgahmiamia-early-learning-centre

    The priority of access guidelines are complex but I think of them as a bit like triage in a hospital. And I'm sure the guidelines will change as fast as they can.

    Thanks again, (social science s/ware)


    Sunday, December 8, 2013 8:34 PM
    Moderator
  • As another thing I noticed - a big delay every so often.

    This is a simple (and slightly better) version of the test code, SPD246.

    Apart from just calling the timer once and doing everything in one call to the timer sub, I added a variable 'count' to be updated every time an image is drawn.

    We can see that the delay occurs every 100 images drawn.  This is because SB rasterises all Drawn objects to an image every time there are 100 drawn objects added.

    The rasterising, just takes all the current drawn images (last 100) and combines them into a single background image for performance reasons, but does introduce a delay that might also be affecting your program.


    Sunday, December 8, 2013 9:05 PM
    Moderator
  • Wow. Thanks for the internal info.

    I'll have a go at seeing that myself.

    I'll be sure to practice limiting d/loads and notifying user of what the program is doing to their property as well.

    Sunday, December 8, 2013 9:19 PM
    Moderator