I'm returning from a long absence of coding, but have recently started work on a new project. This is something I thought about, particularly in for things like AI where you don't want to the computer crawling to its knees if it's handling a large number of AI, or complex calculations, and instead you'd rather split the work load over several loops instead of all in 1
Here's how I worked it out (havn't coded it but it will work when written correctly)
The first step is defining a timeout value, you may need more if you are performing more than a single task in 1 go. Let's first concentrate on a singular task, loading multiple files. We want this to run, but have something like a flashing "Loading..." text, animation, whatever.
Now the simplest and most obvious way would be to simply make a list of all the files that needed to be loaded, and only load 1 file per game loop. But this is inefficient as you may have 300 files to load and this would require 300 frames. At 60fps that's a guaranteed minimum of 5 seconds to load, of course larger files will increase that time
So instead write something like...
sync on : sync rate 60
dim LoadObjects(9999) as string // define array to store names of files to load
REM LoadObjects(0)=PopulateFiles() // this = write your own function to fill the array with any files you wish to load, and store the last file number to load, i.e. "309"
timeout=60 // timeout value in ms, lets go with 60ms = 16fps target
f=1 // start with 1st file in array
Repeat
i=timer() // i=time before executing the load, will be checked against current time to see if timeout value has been reached
f=LoadFile(f,i,timeout) // update f with the last object number loaded (returned by function), upon next loop will start from last position
center text screen width()/2,screen height()/2,"Loading... "+str$((f/val(LoadObjects(0)))*100)+"%" // show the percentage of files loaded so far
sync
Until f=val(LoadObjects(0))
cls : center text screen width()/2,screen height()/2,"FINISHED LOADING! YAY!" : wait 5000 : end
function LoadFile(f,i,timeout) // keep in mind these variables are local and NOT the same as the f/i above, arrays are global
LastObjectLoaded=f // this being an integer, starts with the initial object per function call, and ends with whichever was the last file able to be loaded within the allocated time (timeout)
repeat
load object LoadObjects(LastObjectLoaded),LastObjectLoaded
inc LastObjectLoaded,1
until timer()-i=>timeout or LastObjectLoaded=val(LoadObjects(0)) // keep loading until the timeout value, or until final object has been loaded
center text screen width()/2,0,"Loaded "+str$(LastObjectLoaded-1)+" objects this loop"
endfunction LastObjectLoaded
I just quickly wrote this code and checked for syntax, I havn't actually compiled it but hopefully no bugs and it works as intended. If not there should be enough tags to work it out
Basically you define a requested framerate, 16fps should be enough for a loading screen. You can go higher or lower but the higher you longer it'll take to finish because there will be more 'sync' happening, creating extra time between the actual file loading
The idea is that the function will load as many objects as possible within that timeframe, then simply exit and continue on with the rest of your loop. Now on an awesome computer this could load in a single loop! that's a hell of a lot better than a mandatory 5 second wait, no matter how fast the computer is. And on slower computers it will take more loops, but at least they can see some progress happening, ideally at 16fps (minus overheads)
When executing again it will begin loading again, once again timing out after the defined value and continueing with the rest of the loop. Keep in mind that if there's a large file to be loaded which takes say 500ms, then it will still drop your framerate lower than 16 obviously. This is a fundamental design in the dbpro language and nothing you do will get around it.