I see three options:
- You load the table at app startup: this delays the startup, possibly significantly (5 seconds will be noticeable if otherwise it would be 1 second), and table may never be needed (if user doesn't go to that scene) but after that, the table is instantly ready for display
- You load the table on demand (say when user clicks something): app startup fast, and table only loaded if needed, but this delays transition to scene that shows table so user may think GUI hung, so you need to let user know and provide progress indicator
- You start loading table at startup in a separate thread, and most likely it will take more than 5 seconds for user to get to scene that shows table so the app startup will be fast AND it will appear to the user that table load is instantaneous when going to scene that shows table. However, there is a chance that user will try to go to that scene before the table has been completely loaded, in which case you need to provide some indication that GUI not hung but load in progress.
- You just load the part of table that is visible. This may not be an option (for instance, you need to show table sorted, but database doesn't provide items with same sort so you need to load all items).
I get the impression that you can handle 1 and 2, and most likely #4 too. For 1 and 2 you need to provide some indication that a load operation is taking some time, but otherwise nothing too difficult. For 4 there is no progress needed but you need to determine which rows to load based on the "view" of table (subset of rows visible).
Option is technically more challenging. You are right that you should use coroutines. They are actually quite easy to use:
- you create the coroutine at startup:
thread = coroutine.create(loadTable)
loadTable should be designed to do only small chunks of work at a time, and yield in between chunks, such as
function loadTable() ...init... coroutine.yield() while haveMoreRows do read 10 rows coroutine.yield() end ...cleanup... end
your code resumes the thread repeatedly, until the thread dies:
coroutine.resume(thread)
. A good place to do this would be in the enterFrame handler of corona's Runtime since this is called at every time frame.function enterFrame(e) if thread ~= nil then if coroutines.status(thread) == 'dead' then create table display so it is instantly available in table scene if showing progress, hide it thread = nil else coroutine.resume(thread) end end
In your scene transition (to the scene that shows the table), you should check if thread is not nil, if so then the load is not yet done so you show the message (in new scene) that table is loading; the message will get removed in the enterFrame as soon as load completed.
An important thing to know about a coroutine (cooperative thread) is that the threaded function can have multiple yield points; at the next resume, the function continues to execute from where it left off, with the correct local state.
Hopefully you have looked at http://lua-users.org/wiki/CoroutinesTutorial.