That thread will execute all std::function<void(void)> that are added to a FIFO queue (scheduled).
(edit)
Use asynchronous threads to load and process data.
When done, the async thread will add the UI updates to the GUI work queue.
The GUI thread (main thread) will execute the work queue code before rendering the next frame.
PR: https://github.com/freeorion/freeorion/pull/2219
----
Long version:
The UI freezes were bothering me in single player games.
But I was really shocked when I tried being an observer in a multiplayer game with 6 AIs... the UI was frozen more than half of the time!!
It was so bad that I was only able to explore existing fleets and systems when the AIs started taking more than a minute to finish their turns.
In short, UI freezing became a much bigger issue for me.
In https://github.com/freeorion/freeorion/issues/2188 I learned that calculations were being done in the UI thread.
I can see that the current Universe isn't friendly to multi thread access.
Looking at the CMakeLists.txt you are targetting C++11, so you already have std::function, std::bind, and lambdas.
One way to do this is adding a thread to Universe, that would wait for work to be scheduled in a std::list<std::function<void(void)>> and execute it in FIFO order.
For single function calls scheduling with std::bind would be enough:
Code: Select all
GetUniverse().Schedule(std::bind(&Function, argument));
or
GetUniverse().Schedule(std::bind(&Class::MemberFunction, pointer_to_class_instance, argument));
Code: Select all
// do stuff in original thread
GetUniverse().Schedule([this, data] () {
// do stuff in Universe thread (lambdas can only introduce variables in C++14)
GetUniverse().UpdateSomething(data);
this->m_atomic_var = GetUniverse().GetSomething();
this->RequirePreRender();
});
// do stuff in original thread (probably before or during the lambda)
I'd like some feedback on this idea first.
What are your thoughts on this proposal?
(edit)
I tried adding a thread to Universe but it didn't seem appropriate. (post)
After trying a bunch of ways to split GUI code and data code, I submitted the most KISS alternative as a PR.
I think this approach is flexible and powerful, but there's still something I'm unsure about.
What should be done with unexpected exceptions in async threads?