Newprogressview Shows Progress After Leaving The For Loop

I ran your code and got a progress bar animating like it should:

http://youtu.be/wH-aDbCa3Zs

I also get the animated progressBar, but only after the for loop has finished. Not whilst it is running. If you do get it whilst it is running, can you tell me on which level of Corona SDK you ran it? Than I can upgrade to that level…

Hi @HansVriezen,

In Corona, actions that “refresh” the screen, as in drawing to the OpenGL environment, don’t happen until after the current code “block” is completed. For example, if you were to write a “for” loop of 1 to 1000 that changes the X position of an object randomly over the 1000 iterations, the screen (and thus the position) will not update until that loop is completed… then, the object will go to the last X position that was generated by the randomizer. You won’t see it move 1000 times in fast succession. I think this is what you’re expecting from your loop (for the progress view to update like that), but it won’t work that way.

Brent

Thanks for that information, now I can stop trying  to show the progress of reading an inputfile and storing the information read into a database with  Lua. That is a disappointment, but it can’t be helped.

Hi @HansVriezen,

Does the overall process take a considerable amount of time to complete? I imagine so, if you want to use the progress view to show how much is complete. I haven’t tested it myself, but you could potentially create another function which queries the database table every 100-200 milliseconds, comparing the amount of rows you started with against the amount inserted (new total as the process goes along), and update the progress view according to that. Just food for thought…

Brent

Thank you Brent for that idea.

I tried to implement that idea, but it doesn’t seem to work.

 created a timer that is checking the database for the amount of rows every half second, but as soon as the code that inserts the records kicks in, the timer is not getting control anymore. Only after finishing the code that inserts the records, the timer gets control again, only to find that all records have already been inserted. So that doesn’t work either. Did I do something wrong here? Any other ideas?

Code


local widget = require( “widget” )

– Database connectie

require “sqlite3”

– Open test.db.  If the file doesn’t exist it will be created

local path = system.pathForFile(“test.db”, system.DocumentsDirectory)

db = sqlite3.open( path )

–Handle the applicationExit event to close the db

local function onSystemEvent( event )

   if( event.type == “applicationExit” ) then              

      db:close()

   end

end

local droptesttable = [[DROP TABLE testtable;]]

local createtesttable = [[CREATE TABLE IF NOT EXISTS testtable

    (testfield1 integer,

     testfield2 integer,

     testfield3 text);]]

db:exec (droptesttable)

if db:errcode() > 0 then

   print (“statement:”…droptesttable)

   print (“error:”…db:errcode() )

end

db:exec (createtesttable)

if db:errcode() > 0 then

   print (“statement:”…createtesttable)

   print (“error:”…db:errcode() )

end

– Create a new progressView

local newProgressView = widget.newProgressView

{

    left = 50,

    top = 200,

    width = 200,

    isAnimated = true,

}

local currentProgress = 0

amt = 5

amttodo = amt * 10

jump = 1 / amt

local progress = {}

function progress:timer( event )

   local count = event.count

   print(os.time()…": Table listener called " … count … " time(s)" )

   if amttodo == 0 then

      return

   end

   i = 0

   for row in db:nrows(“SELECT * FROM testtable”) do

      i = i + 1

   end

   rowsintable = i

   currentProgress = rowsintable * jump

   newProgressView:setProgress( currentProgress )

   print (rowsintable, amttodo)

   if rowsintable == amttodo then

      print (os.time()…": stop")

      timer.cancel(event.source)

   end

end

timer.performWithDelay( 500, progress, 0 )

local function continuewithinserts()

   print (“started:”…os.time())

   for x=1,amt do

      for y=1, 10 do

         local inserttesttable = [[INSERT INTO testtable VALUES (]]…x…[[,]]…y…[[, ‘]]…“text”…x…"_"…y…[[’);]]

         print (inserttesttable )

         db:exec (inserttesttable )

         if db:errcode() > 0 then

            print (“statement:”…inserttesttable )

            print (“error:”…db:errcode() )

         end

      end

      currentProgress = currentProgress + jump

      print(os.time()…": step by step, but no progress is shown yet!"…x, jump, currentProgress)

   end

   print (“ended:”…os.time())

end

continueButton = widget.newButton{

   onRelease = continuewithinserts,

   label = “Continue”,

   labelColor = { 

      default = { 255, 255, 255 }, 

      over = { 255, 255, 255 } 

   },

   fontSize = 16,

   width = 100,

   height = 35,

   emboss = true

}

continueButton.x = 160; continueButton .y = 350


Output


Copyright © 2009-2013  C o r o n a   L a b s   I n c .

        Version: 2.0.0

        Build: 2013.1076

1368116504: Table listener called 1 time(s)

0       50

1368116505: Table listener called 2 time(s)

0       50

started:1368116505

INSERT INTO testtable VALUES (1, 1, ‘text1_1’);

INSERT INTO testtable VALUES (1, 2, ‘text1_2’);

INSERT INTO testtable VALUES (1, 3, ‘text1_3’);

INSERT INTO testtable VALUES (1, 4, ‘text1_4’);

INSERT INTO testtable VALUES (1, 5, ‘text1_5’);

INSERT INTO testtable VALUES (1, 6, ‘text1_6’);

INSERT INTO testtable VALUES (1, 7, ‘text1_7’);

INSERT INTO testtable VALUES (1, 8, ‘text1_8’);

INSERT INTO testtable VALUES (1, 9, ‘text1_9’);

INSERT INTO testtable VALUES (1, 10, ‘text1_10’);

1368116505: step by step, but no progress is shown yet!1        0.2     0.2

INSERT INTO testtable VALUES (2, 1, ‘text2_1’);

INSERT INTO testtable VALUES (2, 2, ‘text2_2’);

INSERT INTO testtable VALUES (2, 3, ‘text2_3’);

INSERT INTO testtable VALUES (2, 4, ‘text2_4’);

INSERT INTO testtable VALUES (2, 5, ‘text2_5’);

INSERT INTO testtable VALUES (2, 6, ‘text2_6’);

INSERT INTO testtable VALUES (2, 7, ‘text2_7’);

INSERT INTO testtable VALUES (2, 8, ‘text2_8’);

INSERT INTO testtable VALUES (2, 9, ‘text2_9’);

INSERT INTO testtable VALUES (2, 10, ‘text2_10’);

1368116506: step by step, but no progress is shown yet!2        0.2     0.4

INSERT INTO testtable VALUES (3, 1, ‘text3_1’);

INSERT INTO testtable VALUES (3, 2, ‘text3_2’);

INSERT INTO testtable VALUES (3, 3, ‘text3_3’);

INSERT INTO testtable VALUES (3, 4, ‘text3_4’);

INSERT INTO testtable VALUES (3, 5, ‘text3_5’);

INSERT INTO testtable VALUES (3, 6, ‘text3_6’);

INSERT INTO testtable VALUES (3, 7, ‘text3_7’);

INSERT INTO testtable VALUES (3, 8, ‘text3_8’);

INSERT INTO testtable VALUES (3, 9, ‘text3_9’);

INSERT INTO testtable VALUES (3, 10, ‘text3_10’);

1368116507: step by step, but no progress is shown yet!3        0.2     0.6

INSERT INTO testtable VALUES (4, 1, ‘text4_1’);

INSERT INTO testtable VALUES (4, 2, ‘text4_2’);

INSERT INTO testtable VALUES (4, 3, ‘text4_3’);

INSERT INTO testtable VALUES (4, 4, ‘text4_4’);

INSERT INTO testtable VALUES (4, 5, ‘text4_5’);

INSERT INTO testtable VALUES (4, 6, ‘text4_6’);

INSERT INTO testtable VALUES (4, 7, ‘text4_7’);

INSERT INTO testtable VALUES (4, 8, ‘text4_8’);

INSERT INTO testtable VALUES (4, 9, ‘text4_9’);

INSERT INTO testtable VALUES (4, 10, ‘text4_10’);

1368116508: step by step, but no progress is shown yet!4        0.2     0.8

INSERT INTO testtable VALUES (5, 1, ‘text5_1’);

INSERT INTO testtable VALUES (5, 2, ‘text5_2’);

INSERT INTO testtable VALUES (5, 3, ‘text5_3’);

INSERT INTO testtable VALUES (5, 4, ‘text5_4’);

INSERT INTO testtable VALUES (5, 5, ‘text5_5’);

INSERT INTO testtable VALUES (5, 6, ‘text5_6’);

INSERT INTO testtable VALUES (5, 7, ‘text5_7’);

INSERT INTO testtable VALUES (5, 8, ‘text5_8’);

INSERT INTO testtable VALUES (5, 9, ‘text5_9’);

INSERT INTO testtable VALUES (5, 10, ‘text5_10’);

1368116508: step by step, but no progress is shown yet!5        0.2     1

ended:1368116508

1368116508: Table listener called 3 time(s)

50      50

1368116508: stop


I have upgraded to 2013.1076

Still have the same problem as far as I can see. Below the code I just used to test it, followed by the output in the simulator.

During the For loop, no updates are shown on the screen but after the For loop ends, the progressbar comes to life.

Am I doing something wrong here, or is the progressbar not supposed to be able to show progress from inside a For loop?


local widget = require( “widget” )

– Database connectie

require “sqlite3”

– Open test.db.  If the file doesn’t exist it will be created

local path = system.pathForFile(“test.db”, system.DocumentsDirectory)

db = sqlite3.open( path )

–Handle the applicationExit event to close the db

local function onSystemEvent( event )

   if( event.type == “applicationExit” ) then              

      db:close()

   end

end

local droptesttable = [[DROP TABLE testtable;]]

local createtesttable = [[CREATE TABLE IF NOT EXISTS testtable

    (testfield1 integer,

     testfield2 integer,

     testfield3 text);]]

db:exec (droptesttable)

if db:errcode() > 0 then

   print (“statement:”…droptesttable)

   print (“error:”…db:errcode() )

end

db:exec (createtesttable)

if db:errcode() > 0 then

   print (“statement:”…createtesttable)

   print (“error:”…db:errcode() )

end

– Create a new progressView

local newProgressView = widget.newProgressView

{

    left = 50,

    top = 200,

    width = 200,

    isAnimated = true,

}

local currentProgress = 0

amt = 5

jump = 1 / amt

print (“started:”…os.time())

for x=1,amt do

   for y=1, 10 do

      local inserttesttable = [[INSERT INTO testtable VALUES (]]…x…[[,]]…y…[[, ‘]]…“text”…x…"_"…y…[[’);]]

      print (inserttesttable )

      db:exec (inserttesttable )

      if db:errcode() > 0 then

         print (“statement:”…inserttesttable )

         print (“error:”…db:errcode() )

      end

   end

   currentProgress = currentProgress + jump

   print(“step by step, but no progress is shown yet!”…x, jump, currentProgress)

   newProgressView:setProgress( currentProgress )

end

print (“ended:”…os.time())

------------------------------------------------------------------------------------------------------------------------------------------------------------ Output below

------------------------------------------------------------------------------------------------------------------------------------------------------------Copyright © 2009-2013  C o r o n a   L a b s   I n c .

        Version: 2.0.0

        Build: 2013.1076

started:1367953134

INSERT INTO testtable VALUES (1, 1, ‘text1_1’);

INSERT INTO testtable VALUES (1, 2, ‘text1_2’);

INSERT INTO testtable VALUES (1, 3, ‘text1_3’);

INSERT INTO testtable VALUES (1, 4, ‘text1_4’);

INSERT INTO testtable VALUES (1, 5, ‘text1_5’);

INSERT INTO testtable VALUES (1, 6, ‘text1_6’);

INSERT INTO testtable VALUES (1, 7, ‘text1_7’);

INSERT INTO testtable VALUES (1, 8, ‘text1_8’);

INSERT INTO testtable VALUES (1, 9, ‘text1_9’);

INSERT INTO testtable VALUES (1, 10, ‘text1_10’);

step by step, but no progress is shown yet!1    0.2     0.2

INSERT INTO testtable VALUES (2, 1, ‘text2_1’);

INSERT INTO testtable VALUES (2, 2, ‘text2_2’);

INSERT INTO testtable VALUES (2, 3, ‘text2_3’);

INSERT INTO testtable VALUES (2, 4, ‘text2_4’);

INSERT INTO testtable VALUES (2, 5, ‘text2_5’);

INSERT INTO testtable VALUES (2, 6, ‘text2_6’);

INSERT INTO testtable VALUES (2, 7, ‘text2_7’);

INSERT INTO testtable VALUES (2, 8, ‘text2_8’);

INSERT INTO testtable VALUES (2, 9, ‘text2_9’);

INSERT INTO testtable VALUES (2, 10, ‘text2_10’);

step by step, but no progress is shown yet!2    0.2     0.4

INSERT INTO testtable VALUES (3, 1, ‘text3_1’);

INSERT INTO testtable VALUES (3, 2, ‘text3_2’);

INSERT INTO testtable VALUES (3, 3, ‘text3_3’);

INSERT INTO testtable VALUES (3, 4, ‘text3_4’);

INSERT INTO testtable VALUES (3, 5, ‘text3_5’);

INSERT INTO testtable VALUES (3, 6, ‘text3_6’);

INSERT INTO testtable VALUES (3, 7, ‘text3_7’);

INSERT INTO testtable VALUES (3, 8, ‘text3_8’);

INSERT INTO testtable VALUES (3, 9, ‘text3_9’);

INSERT INTO testtable VALUES (3, 10, ‘text3_10’);

step by step, but no progress is shown yet!3    0.2     0.6

INSERT INTO testtable VALUES (4, 1, ‘text4_1’);

INSERT INTO testtable VALUES (4, 2, ‘text4_2’);

INSERT INTO testtable VALUES (4, 3, ‘text4_3’);

INSERT INTO testtable VALUES (4, 4, ‘text4_4’);

INSERT INTO testtable VALUES (4, 5, ‘text4_5’);

INSERT INTO testtable VALUES (4, 6, ‘text4_6’);

INSERT INTO testtable VALUES (4, 7, ‘text4_7’);

INSERT INTO testtable VALUES (4, 8, ‘text4_8’);

INSERT INTO testtable VALUES (4, 9, ‘text4_9’);

INSERT INTO testtable VALUES (4, 10, ‘text4_10’);

step by step, but no progress is shown yet!4    0.2     0.8

INSERT INTO testtable VALUES (5, 1, ‘text5_1’);

INSERT INTO testtable VALUES (5, 2, ‘text5_2’);

INSERT INTO testtable VALUES (5, 3, ‘text5_3’);

INSERT INTO testtable VALUES (5, 4, ‘text5_4’);

INSERT INTO testtable VALUES (5, 5, ‘text5_5’);

INSERT INTO testtable VALUES (5, 6, ‘text5_6’);

INSERT INTO testtable VALUES (5, 7, ‘text5_7’);

INSERT INTO testtable VALUES (5, 8, ‘text5_8’);

INSERT INTO testtable VALUES (5, 9, ‘text5_9’);

INSERT INTO testtable VALUES (5, 10, ‘text5_10’);

step by step, but no progress is shown yet!5    0.2     1

ended:1367953138

I ran your code and got a progress bar animating like it should:

http://youtu.be/wH-aDbCa3Zs

I also get the animated progressBar, but only after the for loop has finished. Not whilst it is running. If you do get it whilst it is running, can you tell me on which level of Corona SDK you ran it? Than I can upgrade to that level…

Hi @HansVriezen,

In Corona, actions that “refresh” the screen, as in drawing to the OpenGL environment, don’t happen until after the current code “block” is completed. For example, if you were to write a “for” loop of 1 to 1000 that changes the X position of an object randomly over the 1000 iterations, the screen (and thus the position) will not update until that loop is completed… then, the object will go to the last X position that was generated by the randomizer. You won’t see it move 1000 times in fast succession. I think this is what you’re expecting from your loop (for the progress view to update like that), but it won’t work that way.

Brent

Thanks for that information, now I can stop trying  to show the progress of reading an inputfile and storing the information read into a database with  Lua. That is a disappointment, but it can’t be helped.

Hi @HansVriezen,

Does the overall process take a considerable amount of time to complete? I imagine so, if you want to use the progress view to show how much is complete. I haven’t tested it myself, but you could potentially create another function which queries the database table every 100-200 milliseconds, comparing the amount of rows you started with against the amount inserted (new total as the process goes along), and update the progress view according to that. Just food for thought…

Brent

Thank you Brent for that idea.

I tried to implement that idea, but it doesn’t seem to work.

 created a timer that is checking the database for the amount of rows every half second, but as soon as the code that inserts the records kicks in, the timer is not getting control anymore. Only after finishing the code that inserts the records, the timer gets control again, only to find that all records have already been inserted. So that doesn’t work either. Did I do something wrong here? Any other ideas?

Code


local widget = require( “widget” )

– Database connectie

require “sqlite3”

– Open test.db.  If the file doesn’t exist it will be created

local path = system.pathForFile(“test.db”, system.DocumentsDirectory)

db = sqlite3.open( path )

–Handle the applicationExit event to close the db

local function onSystemEvent( event )

   if( event.type == “applicationExit” ) then              

      db:close()

   end

end

local droptesttable = [[DROP TABLE testtable;]]

local createtesttable = [[CREATE TABLE IF NOT EXISTS testtable

    (testfield1 integer,

     testfield2 integer,

     testfield3 text);]]

db:exec (droptesttable)

if db:errcode() > 0 then

   print (“statement:”…droptesttable)

   print (“error:”…db:errcode() )

end

db:exec (createtesttable)

if db:errcode() > 0 then

   print (“statement:”…createtesttable)

   print (“error:”…db:errcode() )

end

– Create a new progressView

local newProgressView = widget.newProgressView

{

    left = 50,

    top = 200,

    width = 200,

    isAnimated = true,

}

local currentProgress = 0

amt = 5

amttodo = amt * 10

jump = 1 / amt

local progress = {}

function progress:timer( event )

   local count = event.count

   print(os.time()…": Table listener called " … count … " time(s)" )

   if amttodo == 0 then

      return

   end

   i = 0

   for row in db:nrows(“SELECT * FROM testtable”) do

      i = i + 1

   end

   rowsintable = i

   currentProgress = rowsintable * jump

   newProgressView:setProgress( currentProgress )

   print (rowsintable, amttodo)

   if rowsintable == amttodo then

      print (os.time()…": stop")

      timer.cancel(event.source)

   end

end

timer.performWithDelay( 500, progress, 0 )

local function continuewithinserts()

   print (“started:”…os.time())

   for x=1,amt do

      for y=1, 10 do

         local inserttesttable = [[INSERT INTO testtable VALUES (]]…x…[[,]]…y…[[, ‘]]…“text”…x…"_"…y…[[’);]]

         print (inserttesttable )

         db:exec (inserttesttable )

         if db:errcode() > 0 then

            print (“statement:”…inserttesttable )

            print (“error:”…db:errcode() )

         end

      end

      currentProgress = currentProgress + jump

      print(os.time()…": step by step, but no progress is shown yet!"…x, jump, currentProgress)

   end

   print (“ended:”…os.time())

end

continueButton = widget.newButton{

   onRelease = continuewithinserts,

   label = “Continue”,

   labelColor = { 

      default = { 255, 255, 255 }, 

      over = { 255, 255, 255 } 

   },

   fontSize = 16,

   width = 100,

   height = 35,

   emboss = true

}

continueButton.x = 160; continueButton .y = 350


Output


Copyright © 2009-2013  C o r o n a   L a b s   I n c .

        Version: 2.0.0

        Build: 2013.1076

1368116504: Table listener called 1 time(s)

0       50

1368116505: Table listener called 2 time(s)

0       50

started:1368116505

INSERT INTO testtable VALUES (1, 1, ‘text1_1’);

INSERT INTO testtable VALUES (1, 2, ‘text1_2’);

INSERT INTO testtable VALUES (1, 3, ‘text1_3’);

INSERT INTO testtable VALUES (1, 4, ‘text1_4’);

INSERT INTO testtable VALUES (1, 5, ‘text1_5’);

INSERT INTO testtable VALUES (1, 6, ‘text1_6’);

INSERT INTO testtable VALUES (1, 7, ‘text1_7’);

INSERT INTO testtable VALUES (1, 8, ‘text1_8’);

INSERT INTO testtable VALUES (1, 9, ‘text1_9’);

INSERT INTO testtable VALUES (1, 10, ‘text1_10’);

1368116505: step by step, but no progress is shown yet!1        0.2     0.2

INSERT INTO testtable VALUES (2, 1, ‘text2_1’);

INSERT INTO testtable VALUES (2, 2, ‘text2_2’);

INSERT INTO testtable VALUES (2, 3, ‘text2_3’);

INSERT INTO testtable VALUES (2, 4, ‘text2_4’);

INSERT INTO testtable VALUES (2, 5, ‘text2_5’);

INSERT INTO testtable VALUES (2, 6, ‘text2_6’);

INSERT INTO testtable VALUES (2, 7, ‘text2_7’);

INSERT INTO testtable VALUES (2, 8, ‘text2_8’);

INSERT INTO testtable VALUES (2, 9, ‘text2_9’);

INSERT INTO testtable VALUES (2, 10, ‘text2_10’);

1368116506: step by step, but no progress is shown yet!2        0.2     0.4

INSERT INTO testtable VALUES (3, 1, ‘text3_1’);

INSERT INTO testtable VALUES (3, 2, ‘text3_2’);

INSERT INTO testtable VALUES (3, 3, ‘text3_3’);

INSERT INTO testtable VALUES (3, 4, ‘text3_4’);

INSERT INTO testtable VALUES (3, 5, ‘text3_5’);

INSERT INTO testtable VALUES (3, 6, ‘text3_6’);

INSERT INTO testtable VALUES (3, 7, ‘text3_7’);

INSERT INTO testtable VALUES (3, 8, ‘text3_8’);

INSERT INTO testtable VALUES (3, 9, ‘text3_9’);

INSERT INTO testtable VALUES (3, 10, ‘text3_10’);

1368116507: step by step, but no progress is shown yet!3        0.2     0.6

INSERT INTO testtable VALUES (4, 1, ‘text4_1’);

INSERT INTO testtable VALUES (4, 2, ‘text4_2’);

INSERT INTO testtable VALUES (4, 3, ‘text4_3’);

INSERT INTO testtable VALUES (4, 4, ‘text4_4’);

INSERT INTO testtable VALUES (4, 5, ‘text4_5’);

INSERT INTO testtable VALUES (4, 6, ‘text4_6’);

INSERT INTO testtable VALUES (4, 7, ‘text4_7’);

INSERT INTO testtable VALUES (4, 8, ‘text4_8’);

INSERT INTO testtable VALUES (4, 9, ‘text4_9’);

INSERT INTO testtable VALUES (4, 10, ‘text4_10’);

1368116508: step by step, but no progress is shown yet!4        0.2     0.8

INSERT INTO testtable VALUES (5, 1, ‘text5_1’);

INSERT INTO testtable VALUES (5, 2, ‘text5_2’);

INSERT INTO testtable VALUES (5, 3, ‘text5_3’);

INSERT INTO testtable VALUES (5, 4, ‘text5_4’);

INSERT INTO testtable VALUES (5, 5, ‘text5_5’);

INSERT INTO testtable VALUES (5, 6, ‘text5_6’);

INSERT INTO testtable VALUES (5, 7, ‘text5_7’);

INSERT INTO testtable VALUES (5, 8, ‘text5_8’);

INSERT INTO testtable VALUES (5, 9, ‘text5_9’);

INSERT INTO testtable VALUES (5, 10, ‘text5_10’);

1368116508: step by step, but no progress is shown yet!5        0.2     1

ended:1368116508

1368116508: Table listener called 3 time(s)

50      50

1368116508: stop


In essence, the reason you are not getting display updates during your loop is that the graphics system only updates *outside* your functions / code. Once you enter your loop code, even though you are calling subroutines, the loop code itself is still in process so the system does not update the display (until it exits).

__________________________________________________________________

To break up a loading loop to allow the system to perform updates during the loading, try the following (pseudo code) strategy for breaking up your code a little:

  • the loading call (your code above) is passed in a “callBack” function pointer – to call / notify when the load finally completes

  • the loading call (your code above) should only set everything up, right to the loop start

  • the loading call (your code above) should then call a new function (your loading loop) on a timer.performWithDelay (100ms should be plenty of delay)

  • The looping/loading function (new, your loop code basically), should then process one record at a time / per call (or 10, or whatever chunks you prefer to process between progress updates), then it should update the progress and exit, calling itself on a timer.performWithDelay() (which will process the next record / chunk). I would recommend using at least 66 ms delays to ensure screen updates, but for all I know (and quite possible) even a 1 ms delay is enough to allow the system to grab control for a moment (and update the display).

  • Once the looping code has finished loading the data, it uses the callback function passed in at the beginning to inform the calling code that the data loading has completed. – So save off the callback parameter, and when the db is done loading you just call it back like so: callback()

In essence, the reason you are not getting display updates during your loop is that the graphics system only updates *outside* your functions / code. Once you enter your loop code, even though you are calling subroutines, the loop code itself is still in process so the system does not update the display (until it exits).

__________________________________________________________________

To break up a loading loop to allow the system to perform updates during the loading, try the following (pseudo code) strategy for breaking up your code a little:

  • the loading call (your code above) is passed in a “callBack” function pointer – to call / notify when the load finally completes

  • the loading call (your code above) should only set everything up, right to the loop start

  • the loading call (your code above) should then call a new function (your loading loop) on a timer.performWithDelay (100ms should be plenty of delay)

  • The looping/loading function (new, your loop code basically), should then process one record at a time / per call (or 10, or whatever chunks you prefer to process between progress updates), then it should update the progress and exit, calling itself on a timer.performWithDelay() (which will process the next record / chunk). I would recommend using at least 66 ms delays to ensure screen updates, but for all I know (and quite possible) even a 1 ms delay is enough to allow the system to grab control for a moment (and update the display).

  • Once the looping code has finished loading the data, it uses the callback function passed in at the beginning to inform the calling code that the data loading has completed. – So save off the callback parameter, and when the db is done loading you just call it back like so: callback()

Hello all,

For games it is logical to respond to events but for business apps, where often data is manipulated in loops, we need to have some control over the UI to show the progress. In several programming languages a ‘forced UI Update’ call can be made to trigger the displayengine to refresh the contents of the visible controls. Creating such a function like ‘display:forceUserInterfaceUpdate()’ does not seem to be rocketscience to implement IMHO (but I have no clue!).

Please add this to the Corona wishlist, in the meantime I will see if timers can offer a solution but since Hans has not reacted to this topic, I am afraid that this will not work. 

I will post an update…

Hello,

Timers do not work indeed, a recursive solution has to be made.

This is my code which works. The code could be cleaner but I only started Corona since 2 weeks, sorry for that!

Perhaps this is of some use to somebody!

Introducing a new function ‘display:forceUserInterfaceUpdate()’ would make life much more easy for building business apps!

Regards, Marc

– Define the local functions

local SaveDataCustomersWithProgress

local SaveDataCustomersEnd

– Local vars

local dbCustomers                            – Customers database SQLLite

local nProgressUpdateAmount=10      – Amount of records to be written after which we issue a GUI update

local decodedDataCustomers             – Decoded JSON data

local progressCustomers                   – newProgressView

local nRetrievedCustomers                 – Amount of Customers retrieved from the database

local nCustomersIndex                      – Current index when savind the customers

local FetchedCustomers = false         – Did we write all customers to the SQL table

– =====================================================================================

– Save the customers data with a progress bar

– =====================================================================================

SaveDataCustomersWithProgress = function ()

        

    – Build the recursion

    local function Customerslistener( event )

        SaveDataCustomersWithProgress()

    end

    

    – Check if we reached the customers

    local index = “customer”…nCustomersIndex

    local customer = decodedDataCustomers[index]

    local nProgress = 0

    local nLocalCount = 0

    print(customer)

    – Loop al customers

    while (customer ~= nil) do

        – Set the progress

        nProgress = nCustomersIndex/nRetrievedCustomers

        progressCustomers:setProgress(nProgress)

        – Insert this record in the table

        local tablefill =“INSERT INTO customers VALUES (’” … customer[1] … “’,’” … customer[2] …"’,’" … customer[3] …"’,’" … customer[4] …"’,’" … customer[5] …"’,’" … customer[6] …"’,’" … customer[7] …"’);"

        print(tablefill)

        dbCustomers:exec( tablefill )

        nCustomersIndex = nCustomersIndex+1

        – Check if we hit the max amount to write this block

        nLocalCount = nLocalCount+1

        if (nLocalCount == nProgressUpdateAmount) then

            – We have reached the max amount of records to be saved, set the timer and restart this routine again!

            – This will exit all loops

            – The UI will now be updated after which the timer will start this routine again to insert the next block of records

            timer.performWithDelay(1, Customerslistener)

            break

        end

        – Get the next customer if we did not break the loop

        index = “customer”…nCustomersIndex

        customer = decodedDataCustomers[index]

    end

    – Check if we reached the end

    if (customer == nil) then

        – We reached the end, so close the database and clean up

       SaveDataCustomersEnd() 

    end

end

– =====================================================================================

– End saving the customers

– =====================================================================================

SaveDataCustomersEnd = function ()

    

    – Everything is saved to the SQLite database; close database

    progressCustomers:setProgress(1)

    dbCustomers:close()

    

    – Set we are done with the customers

    FetchedCustomers = true

    

    – See if all listeners received their data and we can fire up statistics!

    – Various GET were fired and handled asynchronous

    AreWeReady()

    

end

– =====================================================================================

– Save the customers data

– =====================================================================================

local SaveDataCustomers = function ()

    --save new data to a sqlite file

    – open SQLite database, if it doesn’t exist, create database

    local path = system.pathForFile(“customers.sqlite”, system.DocumentsDirectory)

    dbCustomers = sqlite3.open( path )

    print(path)

    – setup the table if it doesn’t exist

    local tablesetup = “CREATE TABLE IF NOT EXISTS Customers (lastname, lastnameprefix, firstname, orderdate, deliverydate, orderid, customerid);”

    dbCustomers:exec( tablesetup )

    print(tablesetup)

    

    – The database is open and will be closed in SaveDataCustomersEnd due to the timer mechanism

    – See if we have customers

    nRetrievedCustomers = GetTableCount(decodedDataCustomers)

    if (nRetrievedCustomers > 0) then

        

        – Save data to database, get the first row

        nCustomersIndex = 1

        InfoText.text = “Save Customers”

        

        – To update the GUI, we have to leave all code and loops, so we have to use the following mechanism

        – 1 Determine the total amount of records to be inserted (nCountCustomers)

        – 2 Determina the amount of records to be written each run = 10

        – 3 Start an insert function to insert this amount if record

        – 4 If we are not finished, start a timer to restart the same method again to write the next block of records

        SaveDataCustomersWithProgress()

    end

end

Hello all,

For games it is logical to respond to events but for business apps, where often data is manipulated in loops, we need to have some control over the UI to show the progress. In several programming languages a ‘forced UI Update’ call can be made to trigger the displayengine to refresh the contents of the visible controls. Creating such a function like ‘display:forceUserInterfaceUpdate()’ does not seem to be rocketscience to implement IMHO (but I have no clue!).

Please add this to the Corona wishlist, in the meantime I will see if timers can offer a solution but since Hans has not reacted to this topic, I am afraid that this will not work. 

I will post an update…

Hello,

Timers do not work indeed, a recursive solution has to be made.

This is my code which works. The code could be cleaner but I only started Corona since 2 weeks, sorry for that!

Perhaps this is of some use to somebody!

Introducing a new function ‘display:forceUserInterfaceUpdate()’ would make life much more easy for building business apps!

Regards, Marc

– Define the local functions

local SaveDataCustomersWithProgress

local SaveDataCustomersEnd

– Local vars

local dbCustomers                            – Customers database SQLLite

local nProgressUpdateAmount=10      – Amount of records to be written after which we issue a GUI update

local decodedDataCustomers             – Decoded JSON data

local progressCustomers                   – newProgressView

local nRetrievedCustomers                 – Amount of Customers retrieved from the database

local nCustomersIndex                      – Current index when savind the customers

local FetchedCustomers = false         – Did we write all customers to the SQL table

– =====================================================================================

– Save the customers data with a progress bar

– =====================================================================================

SaveDataCustomersWithProgress = function ()

        

    – Build the recursion

    local function Customerslistener( event )

        SaveDataCustomersWithProgress()

    end

    

    – Check if we reached the customers

    local index = “customer”…nCustomersIndex

    local customer = decodedDataCustomers[index]

    local nProgress = 0

    local nLocalCount = 0

    print(customer)

    – Loop al customers

    while (customer ~= nil) do

        – Set the progress

        nProgress = nCustomersIndex/nRetrievedCustomers

        progressCustomers:setProgress(nProgress)

        – Insert this record in the table

        local tablefill =“INSERT INTO customers VALUES (’” … customer[1] … “’,’” … customer[2] …"’,’" … customer[3] …"’,’" … customer[4] …"’,’" … customer[5] …"’,’" … customer[6] …"’,’" … customer[7] …"’);"

        print(tablefill)

        dbCustomers:exec( tablefill )

        nCustomersIndex = nCustomersIndex+1

        – Check if we hit the max amount to write this block

        nLocalCount = nLocalCount+1

        if (nLocalCount == nProgressUpdateAmount) then

            – We have reached the max amount of records to be saved, set the timer and restart this routine again!

            – This will exit all loops

            – The UI will now be updated after which the timer will start this routine again to insert the next block of records

            timer.performWithDelay(1, Customerslistener)

            break

        end

        – Get the next customer if we did not break the loop

        index = “customer”…nCustomersIndex

        customer = decodedDataCustomers[index]

    end

    – Check if we reached the end

    if (customer == nil) then

        – We reached the end, so close the database and clean up

       SaveDataCustomersEnd() 

    end

end

– =====================================================================================

– End saving the customers

– =====================================================================================

SaveDataCustomersEnd = function ()

    

    – Everything is saved to the SQLite database; close database

    progressCustomers:setProgress(1)

    dbCustomers:close()

    

    – Set we are done with the customers

    FetchedCustomers = true

    

    – See if all listeners received their data and we can fire up statistics!

    – Various GET were fired and handled asynchronous

    AreWeReady()

    

end

– =====================================================================================

– Save the customers data

– =====================================================================================

local SaveDataCustomers = function ()

    --save new data to a sqlite file

    – open SQLite database, if it doesn’t exist, create database

    local path = system.pathForFile(“customers.sqlite”, system.DocumentsDirectory)

    dbCustomers = sqlite3.open( path )

    print(path)

    – setup the table if it doesn’t exist

    local tablesetup = “CREATE TABLE IF NOT EXISTS Customers (lastname, lastnameprefix, firstname, orderdate, deliverydate, orderid, customerid);”

    dbCustomers:exec( tablesetup )

    print(tablesetup)

    

    – The database is open and will be closed in SaveDataCustomersEnd due to the timer mechanism

    – See if we have customers

    nRetrievedCustomers = GetTableCount(decodedDataCustomers)

    if (nRetrievedCustomers > 0) then

        

        – Save data to database, get the first row

        nCustomersIndex = 1

        InfoText.text = “Save Customers”

        

        – To update the GUI, we have to leave all code and loops, so we have to use the following mechanism

        – 1 Determine the total amount of records to be inserted (nCountCustomers)

        – 2 Determina the amount of records to be written each run = 10

        – 3 Start an insert function to insert this amount if record

        – 4 If we are not finished, start a timer to restart the same method again to write the next block of records

        SaveDataCustomersWithProgress()

    end

end