I have a game engine built with SFML and I was attempting to create a loading screen which is updated while assets are loaded. In this case it is one big XML file.
I wanted to use a thread as this process took about ten seconds to complete and therefore the application would be stuck until it is completed.
I decided to use the thread and detach so that the AssetManager's LoadSpriteSheets method could be called. (Essentially loads an XML sheet and initialises them as sprites)
With the game state declaring a struct it is passed through the states class to give any state access to the struct. Which in returns give access to the AssetManager.
struct GameData
{
StateMachine machine;
sf::RenderWindow window;
AssetManager assets;
InputManager input;
};
In the initalise section of the SplashStage the thread is called
std::thread t1(&AssetManager::LoadSpriteSheets, this->_data->assets);
t1.detach();
As you can see, my idea was to pass the AssetManager (this->_data->assets) to the thread and call its LoadSpriteSheets Method. It does do this but it creates a new instance of the AssetManager resulting in my later polling of the GetStatus Method to result in 0. (GetStatus essentially gets the progress of the LoadSpriteSheets Method) I was going to use that to display an informative loading bar while waiting for the application to load.
Is there a way can I call a thread on the AssetManager without initialising a new Object? Or is a rewrite required as the struct is a shared_ptr.
Feel free to correct me also if you see a better solution to what I am trying to achieve.
Relevant Classes:
#include "SplashState.h"
#include <iostream>
#include <sstream>
#include <thread>
#include "AssetManager.h"
#include "Definitions.h"
SplashState::SplashState(GameDataRef data) : _data(data)
{
}
void SplashState::Init()
{
this->_data->assets.LoadTexture("Splash State Background", SPLASH_STATE_BACKGROUND_FILEPATH);
_background.setTexture(this->_data->assets.GetTexture("Splash State Background"));
std::thread t1(&AssetManager::LoadSpriteSheets, this->_data->assets);
t1.detach();
std::cout << "Completed In Splash" << std::endl;
/*_test.setTexture(this->_data->assets.GetTexture("spaceShips_001.png"));
_test.setPosition((SCREEN_WIDTH / 2) - (_test.getGlobalBounds().width / 2), _test.getGlobalBounds().height / 2);*/
//std::thread t2(&SplashState::LoadXML, this);
/*_test.setTexture(this->_data->assets.GetTexture("spaceAstronauts_001.png"));
_test.setPosition((SCREEN_WIDTH / 2) - (_test.getGlobalBounds().width / 2), _test.getGlobalBounds().height / 2);*/
}
Game.cpp
#pragma once
#include <memory>
#include <string>
#include <SFML\Graphics.hpp>
#include "StateMachine.h"
#include "AssetManager.h"
#include "InputManager.h"
struct GameData
{
StateMachine machine;
sf::RenderWindow window;
AssetManager assets;
InputManager input;
};
typedef std::shared_ptr<GameData> GameDataRef;
class Game
{
public:
Game(int width, int height, std::string title);
private:
const float dt = 1.0f / 60.0f;
sf::Clock _clock;
GameDataRef _data = std::make_shared<GameData>();
void Run();
};
#include "Game.h"
#include "SplashState.h"
Game::Game(int width, int height, std::string title)
{
_data->window.create(sf::VideoMode(width, height), title, sf::Style::Close | sf::Style::Titlebar);
_data->machine.AddState(StateRef(new SplashState(this->_data)));
this->Run();
}