Game Development Reference
In-Depth Information
if (GetPlayerWon())
{
SerializationManager::GetSingleton().ClearSave();
cout << "Congratulations, you rid the dungeon of monsters!" << endl;
cout << "Type goodbye to end" << endl;
std::string input;
cin >>input;
}
}
The first step was to create a function, LoadSaveGame , to be executed in another thread.
LoadSaveGame calls the SerializationManager::Load method. The LoadSaveGame function pointer is
passed into the packaged_task constructor. The packaged_task template has been specialized with
the type bool() . This is the type of the function; it returns a bool and does not take any parameters.
Then std::ref is used to pass the packaged_task into a thread. When a packaged_task is passed to
a thread it can be executed, as a thread object knows how to handle packaged_task objects. This
is true because a packaged_task object overloads an operator, which allows it to be called just like
a function. This overloaded function call operator calls the actual function used to construct the
packaged_task .
The main thread can now call the get_future method on the packaged_task . A future is used in
threaded programs to allow you to set up tasks that will provide returned values at some point in
the future . You could call get immediately on the future, but as get is a blocking call, your thread
would stall until the future result is available. Listing 25-9 shows an alternate implementation where
wait_for is used to check if the future result is available.
The future::wait_for method takes a value from the std::chrono set of duration classes. In this
case, we are passing in std::chrono::seconds{ 0 } , which means the method will return instantly
with a result. The possible return values in our case come from the std::future_status enum class
and are ready or timeout . The timeout value will be returned until the player's game is loaded or he
or she chooses to start a new game. At that point we can call the future::get method, which stores
the value returned from SerializationManager::Loa d, via the LoadSaveGame function passed to
loaderTask .
That wraps up your brief introduction to multithreaded C++ programming.
Summary
In this chapter you have been introduced to some of the classes C++ provides to allow you to add
multiple execution threads to your programs. You first saw how threads can be created to execute
functions. Calling functions in this manner allows the operating system to run your threads on more
than one CPU thread and speed up the execution of your program.
When you use threads you need to make sure that your threads do not conflict when accessing
variables and sharing data. You saw that the mutex can be used to manually provide mutually exclusive
access to variables. After showing a mutex in action, I then introduced you to the packaged_task
template, which automatically creates a promise and a future to better manage your concurrent
tasks at a higher level than the base thread and mutex.
 
Search WWH ::




Custom Search