Hello,
So I just had some help on a super barebone example on a loading state using a thread. I'm reading SFML Game Development still and I've come to a halt to try to understand how they incorporate the loading state so that it is actually reading the files instead of the mock loading they do.
I could just do what I learned in my previous thread, but I'd like to learn how to incorporate it using the book's design. The loading state is called when you click "Play" from the main menu. I'm just trying to understand when and where I would pass the fonts/texture data into loading and where?
Any help would be greatly appreciated. Here is the basics of what it offers.
#include "ParallelTask.h"
ParallelTask::ParallelTask()
: m_thread(&ParallelTask::runTask, this)
, m_finished(false)
{
}
void ParallelTask::execute()
{
m_finished = false;
m_elapsedTime.restart();
m_thread.launch();
}
bool ParallelTask::isFinished()
{
sf::Lock lock(m_mutex);
return m_finished;
}
float ParallelTask::getCompletion()
{
sf::Lock lock(m_mutex);
// 100% at 10 seconds of elapsed time
return m_elapsedTime.getElapsedTime().asSeconds() / 10.f;
}
void ParallelTask::runTask()
{
// Dummy task - stall 10 seconds
bool ended = false;
while (!ended)
{
sf::Lock lock(m_mutex); // Protect the clock
if (m_elapsedTime.getElapsedTime().asSeconds() >= 10.f)
ended = true;
}
{ // mFinished may be accessed from multiple threads, protect it
sf::Lock lock(m_mutex);
m_finished = true;
}
}
#include "LoadingState.h"
#include "Utils/Helpers.h"
#include"ResourceHolder.h"
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/View.hpp>
LoadingState::LoadingState(StateStack& stack, Context context)
: State(stack, context)
{
sf::RenderWindow& window = *getContext().window;
sf::Font& font = context.fonts->get(Fonts::Sansation);
sf::Vector2f viewSize = window.getView().getSize();
m_loadingText.setFont(font);
m_loadingText.setString("Loading Resources");
Helpers::position::centerOrigin(m_loadingText);
m_loadingText.setPosition(viewSize.x / 2.f, viewSize.y / 2.f + 50.f);
m_progressBarBackground.setFillColor(sf::Color::White);
m_progressBarBackground.setSize(sf::Vector2f(viewSize.x - 20, 10));
m_progressBarBackground.setPosition(10, m_loadingText.getPosition().y + 40);
m_progressBar.setFillColor(sf::Color(32,170,14));
m_progressBar.setSize(sf::Vector2f(200, 10));
m_progressBar.setPosition(10, m_loadingText.getPosition().y + 40);
setCompletion(0.f);
m_loadingTask.execute();
}
bool LoadingState::handleEvent(const sf::Event& event) {
return true;
}
bool LoadingState::update(sf::Time) {
// Update the progress bar from the remote task or finish it
if (m_loadingTask.isFinished()) {
requestStackPop();
requestStackPush(States::Game);
}
else {
setCompletion(m_loadingTask.getCompletion());
}
return true;
}
void LoadingState::draw()
{
sf::RenderWindow& window = *getContext().window;
window.setView(window.getDefaultView());
window.draw(m_loadingText);
window.draw(m_progressBarBackground);
window.draw(m_progressBar);
}
void LoadingState::setCompletion(float percent)
{
if (percent > 1.f) // clamp
percent = 1.f;
m_progressBar.setSize(sf::Vector2f(m_progressBarBackground.getSize().x * percent, m_progressBar.getSize().y));
}
The previous thread (as in my post) a fine gentleman helped me learned how to accomplish a loading screen like this (was a barebone main.cpp example)
THIS IS NOT PART OF THE BOOK CODE, BUT AN EXAMPLE BEFORE LOOKING AT BOOK CODE// Still in main thread
std::vector<std::shared_ptr<Tile>> tilesVector;
tilesVector.reserve(Map_Height * Map_Width); // This creates the tiles with default constructor ( Tile() )
std::atomic<bool> done(false);
// Create thread to execute the bellow code while main thread continues normal execution
std::thread t([&done, &tilesVector] {
// Tile creation IS the heavy duty work
for(auto y = 0; y < Map_Height; ++y)
{
for (auto x = 0; x < Map_Width; ++x)
{
Tile * tile = tilesVector[y * Map_Width + x].get(); // Get a pointer to tile to change its attributes
tile->spr.setSize(TILE_SIZE);
tile->spr.setFillColor({ 0,255,0,15 });
tile->spr.setOutlineColor(sf::Color::White);
tile->spr.setOutlineThickness(1.f);
tile->spr.setPosition(x * TILE_SIZE.x, y * TILE_SIZE.y);
tile->spr.setOrigin(TILE_SIZE.x / 2.f, TILE_SIZE.y / 2.f);
if (y >= 240 && y <= 260 && x >= 240 && x <= 260)
{
tile->spr.setFillColor({ 200,25,22 });
}
// tiles.emplace_back(std::move(tile)); This line no longer needed, we already have our tile vector
}
}
// After building the tiles we set variable to true to signal that our work
// (tile creation) on this separate thread is done.
done = true;
});
Thank you, and have a nice day.