So, how do you do it?

• This question asks about emulating the behaviour of multi threading. There is also no real use for having its own tag. I am reverting the edit to this post, as multithreading seems suitable; an expert in multithreading should be aware of similar implementations where multi threading is not supported. – Gnemlock May 11 '17 at 14:06

You basically have to break down the loaded data into smaller chunks, and intersperse UI updates in between those bits of processing. The finer the granularity of the chunks of data you synchronously load / process, the more frequently your UI can update. In essence, poor man's multi-threading. (This is how it was done before the advent of multi-core machines.)

Breaking down into smaller chunks may well not be possible unless you do one or more of:

• Restructure your data (possibly a major change).

So you'd do something like:

while (chunksRemaining > 0)
{
UpdateUI();
}


Notice that the LoadNextChunk() call could take nanoseconds or whole seconds, but prevents us proceeding to UpdateUI() until Chunk's processing is done. So ensure LoadNextChunk() runs fast!

• P.S. This is a form of time-slicing. – Engineer Aug 20 '19 at 14:27

In very, very generic terms, you write something like this (pseudo-code):

while (!isNewLevelLoaded) {
}

for (int i = 0; i < bytes; i++) {
}
}

• Hmm. You've made an assumption about the format the OP is loading in. What if, for example, they're using JSON or XML, or some other externally-defined format? We can't necessarily assume a byte-loader. – Engineer May 10 '17 at 17:40
• I used bytes just to show that he has to decide how big must be the next chunk of data to load between two updates of the loading screen. – Galandil May 10 '17 at 17:55
• @ArcaneEngineer It's an abstract example. LoadNewLevelBytes could easily be LoadJson or LoadXml. – Pharap May 11 '17 at 16:51

I'm not sure what kind of "single-threaded machines" you have in mind, but you could also have a single-threaded programme running on a system that supports asynchronous I/O. In this case there is stuff happening in parallel with your code being executed but it's handled by the OS.

So in pseudocode your programme might look like this:

for (fileToLoad) {
}

}



Some languages provide coroutines, which are similar to threads in that they allow a degree of multi-tasking, but can actually exist on one thread.

A couroutine is essentially a block of code that at some point decides to yield back to its caller, so you get code like this:

(Hypothetical Lua code)

function loadFile(path)
--code
end

for i, file in ipairs(fileList) do
coroutine.yield(result)
end
end

--code
end

--code
end