SDLFramework/src/sdlf/Window.cpp

168 lines
4.3 KiB
C++
Raw Normal View History

2020-06-15 20:03:08 +02:00
#include "Window.hpp"
2020-06-15 21:36:57 +02:00
#include <sstream>
2020-07-02 22:42:21 +02:00
#include <iostream>
2020-07-02 22:47:23 +02:00
#include <cstring>
2020-06-15 21:36:57 +02:00
#include "util/util.hpp"
2020-06-15 20:03:08 +02:00
namespace sf
{
2020-06-15 21:36:57 +02:00
2020-06-18 17:22:24 +02:00
void IWindow::Create(Vector2u size, Vector2i position, std::string title,
Uint32 windowFlags /*= SDL_WINDOW_RESIZABLE*/, Uint32 renderFlags /*= SDL_RENDERER_SOFTWARE*/)
2020-06-15 21:36:57 +02:00
{
2020-07-02 22:42:21 +02:00
m_pCurrentException = "";
2020-06-15 21:36:57 +02:00
// Check if SDL was initialized
Uint32 mask = SDL_WasInit(0);
if ((mask & SDLF_REQUIRED_SUBSYSTEMS) != SDLF_REQUIRED_SUBSYSTEMS)
{
std::ostringstream errorStream;
errorStream << "One or more required subsystems were not initialized. (Expected " <<
SDLF_REQUIRED_SUBSYSTEMS << " but got " << mask << " instead). \n" <<
"Make sure to call SDL_Init(" << SDLF_REQUIRED_SUBSYSTEMS << ") before instantiating sf::IWindow.";
2020-07-02 22:42:21 +02:00
m_pCurrentException = const_cast<char*>(errorStream.str().c_str());
return;
2020-06-15 21:36:57 +02:00
}
// Create SDL_Window
if (m_pWindow == nullptr)
{
2020-06-18 17:22:24 +02:00
m_pWindow = SDL_CreateWindow(title.c_str(), position.x, position.y, size.x, size.y, windowFlags);
2020-07-02 22:42:21 +02:00
if (IS_NULLPTR(m_pWindow))
{
m_pCurrentException = const_cast<char*>(SDL_GetError());
return;
}
2020-06-15 21:36:57 +02:00
}
// Create SDL_Renderer
if (m_pRenderer == nullptr)
{
2020-06-18 17:22:24 +02:00
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, renderFlags);
2020-07-02 22:42:21 +02:00
if (IS_NULLPTR(m_pRenderer))
{
m_pCurrentException = const_cast<char*>(SDL_GetError());
return;
}
2020-06-15 21:36:57 +02:00
}
2020-06-18 12:50:56 +02:00
m_oEventFunction = std::bind(&IWindow::OnEvent, this, std::placeholders::_1);
m_oUpdateFunction = std::bind<bool>(&IWindow::OnUpdate, this, std::placeholders::_1);
m_oRenderFunction = std::bind(&IWindow::OnRender, this, std::placeholders::_1);
2020-06-15 21:36:57 +02:00
}
void IWindow::Destroy()
2020-06-15 20:03:08 +02:00
{
2020-06-15 21:36:57 +02:00
SDL_DestroyRenderer(m_pRenderer);
SDL_DestroyWindow(m_pWindow);
}
void IWindow::Launch(bool threaded /*= false*/)
{
m_atomWindowOpen = true;
if (threaded)
{
m_oMsgLoopThread = std::thread(&IWindow::MessageLoop, this);
}
else {
MessageLoop();
}
}
void IWindow::Stop()
{
m_atomWindowOpen = false;
if(m_oMsgLoopThread.joinable())
m_oMsgLoopThread.join();
2020-06-15 20:03:08 +02:00
}
2020-06-15 21:36:57 +02:00
2020-06-15 21:49:10 +02:00
void IWindow::AddEventCallback(EventCallback callback, void* userdata)
{
SDL_AddEventWatch(*(callback.target<SDL_EventFilter>()), userdata);
}
2020-06-18 12:50:56 +02:00
void IWindow::SwitchScreen(IScreen* screen)
{
if (m_pCurrentScreen == screen)
return;
if (IS_NOT_NULLPTR(m_pCurrentScreen))
m_pCurrentScreen->OnDefocus();
m_pCurrentScreen = screen;
if (IS_NOT_NULLPTR(m_pCurrentScreen))
{
m_oEventFunction = std::bind(&IScreen::OnEvent, m_pCurrentScreen, std::placeholders::_1);
m_oUpdateFunction = std::bind<bool>(&IScreen::OnUpdate, m_pCurrentScreen, std::placeholders::_1);
m_oRenderFunction = std::bind(&IScreen::OnRender, m_pCurrentScreen, std::placeholders::_1);
2020-06-18 15:16:10 +02:00
m_pCurrentScreen->OnFocus(this);
2020-06-18 12:50:56 +02:00
}
else
{
m_oEventFunction = std::bind(&IWindow::OnEvent, this, std::placeholders::_1);
m_oUpdateFunction = std::bind<bool>(&IWindow::OnUpdate, this, std::placeholders::_1);
m_oRenderFunction = std::bind(&IWindow::OnRender, this, std::placeholders::_1);
}
}
2020-06-15 21:36:57 +02:00
IWindow::IWindow(Vector2u size, Vector2i position, std::string title,
2020-06-18 17:25:50 +02:00
Uint32 windowFlags /*= SDL_WINDOW_RESIZABLE*/, Uint32 renderFlags /*= SDL_RENDERER_SOFTWARE*/) :
2020-06-15 21:36:57 +02:00
m_pWindow(nullptr), m_pRenderer(nullptr), m_oEvent(),
2020-06-18 17:25:50 +02:00
m_oSize(size), m_oPosition(position), m_strTitle(title), m_uWindowFlags(windowFlags),
2020-07-02 22:42:21 +02:00
m_uRenderFlags(renderFlags), m_pCurrentScreen(nullptr), m_pCurrentException("")
2020-06-15 21:36:57 +02:00
{
}
void IWindow::MessageLoop()
{
2020-06-18 17:25:50 +02:00
Create(m_oSize, m_oPosition, m_strTitle, m_uWindowFlags, m_uRenderFlags);
2020-07-02 22:47:23 +02:00
if (std::strcmp(m_pCurrentException, ""))
2020-07-02 22:42:21 +02:00
{
std::cerr << "ERROR: " << m_pCurrentException << std::endl;
return;
}
2020-06-15 21:36:57 +02:00
// Test if the user instance's creation succeeded
if (!OnCreate())
m_atomWindowOpen = false;
std::chrono::steady_clock::time_point pastTime = std::chrono::steady_clock::now();
while (m_atomWindowOpen)
{
while (SDL_PollEvent(&m_oEvent))
{
2020-06-18 15:16:10 +02:00
if (m_oEventFunction(m_oEvent))
2020-06-15 21:36:57 +02:00
{
2020-06-18 15:16:10 +02:00
if (m_oEvent.type == SDL_QUIT)
{
m_atomWindowOpen = false;
}
2020-06-15 21:36:57 +02:00
}
}
double frametime = std::chrono::duration_cast<std::chrono::duration<double>>(
std::chrono::steady_clock::now() - pastTime
).count();
pastTime = std::chrono::steady_clock::now();
2020-06-18 12:50:56 +02:00
if (!m_oUpdateFunction(frametime))
2020-06-15 21:36:57 +02:00
m_atomWindowOpen = false;
2020-06-18 12:50:56 +02:00
m_oRenderFunction(m_pRenderer);
2020-06-15 21:36:57 +02:00
SDL_RenderPresent(m_pRenderer);
}
OnClose();
Destroy();
}
2020-06-15 20:03:08 +02:00
}