From 9ce9cd34326891dd64d38f99e369699da9eed0ee Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 15 Jun 2020 21:36:57 +0200 Subject: [PATCH] Added multithreading --- src/example/main.cpp | 52 +++++++++++++- src/sdlf/CMakeLists.txt | 1 - src/sdlf/Window.cpp | 103 ++++++++++++++++++++++++++- src/sdlf/Window.hpp | 37 +++++++++- src/sdlf/{maths => util}/Vector2.hpp | 0 src/sdlf/util/util.hpp | 3 + 6 files changed, 188 insertions(+), 8 deletions(-) rename src/sdlf/{maths => util}/Vector2.hpp (100%) create mode 100644 src/sdlf/util/util.hpp diff --git a/src/example/main.cpp b/src/example/main.cpp index 763ae98..72f510f 100644 --- a/src/example/main.cpp +++ b/src/example/main.cpp @@ -1,8 +1,56 @@ -#include "Window.hpp" +#include "SDLF.hpp" + +#include + +using namespace sf; + +class MyWindow : public IWindow +{ +public: + MyWindow() : + IWindow(Vec2u(800, 800), Vec2i(100, 100), "MyWindow") + { + + } + +private: + virtual bool OnCreate() override + { + printf("On Create\n"); + return true; + } + + virtual void OnClose() override + { + printf("On Close\n"); + } + + virtual bool OnUpdate(double frametime) override + { + printf("Frame took %f seconds\n", frametime); + return true; + } +}; int main(int argc, char* argv[]) { - sf::IWindow window; + SDL_Init(SDL_INIT_VIDEO); + + MyWindow window; + + try + { + window.Launch(true); + } + catch (std::string e) + { + std::cout << e << std::endl; + } + + while (window.IsOpen()) + true; + window.Stop(); + return 0; } \ No newline at end of file diff --git a/src/sdlf/CMakeLists.txt b/src/sdlf/CMakeLists.txt index e60b566..51a2e1c 100644 --- a/src/sdlf/CMakeLists.txt +++ b/src/sdlf/CMakeLists.txt @@ -5,7 +5,6 @@ add_library(sdlf STATIC target_include_directories(sdlf PRIVATE "${CMAKE_SOURCE_DIR}/3rdparty/include/SDL" - "maths" ) target_link_libraries(sdlf PRIVATE diff --git a/src/sdlf/Window.cpp b/src/sdlf/Window.cpp index 8cb3c4c..b016681 100644 --- a/src/sdlf/Window.cpp +++ b/src/sdlf/Window.cpp @@ -1,12 +1,109 @@ #include "Window.hpp" -#include +#include +#include "util/util.hpp" namespace sf { - IWindow::IWindow() : - m_pWindow(nullptr), m_pRenderer(nullptr) + + void IWindow::Create(Vector2u size, Vector2i position, std::string title, Uint32 flags /*= SDL_WINDOW_RESIZABLE*/) { + // 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."; + throw errorStream.str(); + } + + // Create SDL_Window + if (m_pWindow == nullptr) + { + m_pWindow = SDL_CreateWindow(title.c_str(), position.x, position.y, size.x, size.y, flags); + THROW_IF_NULLPTR(m_pWindow); + } + + // Create SDL_Renderer + if (m_pRenderer == nullptr) + { + m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, SDL_RENDERER_SOFTWARE); + THROW_IF_NULLPTR(m_pRenderer); + } } + + void IWindow::Destroy() + { + 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(); + + } + + IWindow::IWindow(Vector2u size, Vector2i position, std::string title, + Uint32 flags /*= SDL_WINDOW_RESIZABLE*/) : + m_pWindow(nullptr), m_pRenderer(nullptr), m_oEvent(), + m_oSize(size), m_oPosition(position), m_strTitle(title), m_uFlags(flags) + { + + } + + void IWindow::MessageLoop() + { + Create(m_oSize, m_oPosition, m_strTitle, m_uFlags); + + // 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)) + { + if (m_oEvent.type == SDL_QUIT) + { + m_atomWindowOpen = false; + } + } + + double frametime = std::chrono::duration_cast>( + std::chrono::steady_clock::now() - pastTime + ).count(); + pastTime = std::chrono::steady_clock::now(); + if (!OnUpdate(frametime)) + m_atomWindowOpen = false; + + SDL_SetRenderDrawColor(m_pRenderer, 0, 0, 0, 255); + SDL_RenderClear(m_pRenderer); + + SDL_RenderPresent(m_pRenderer); + } + + OnClose(); + Destroy(); + } + } \ No newline at end of file diff --git a/src/sdlf/Window.hpp b/src/sdlf/Window.hpp index f909824..f7ad161 100644 --- a/src/sdlf/Window.hpp +++ b/src/sdlf/Window.hpp @@ -1,16 +1,49 @@ #pragma once +#include +#include +#include + #include "SDL.h" +#include "util/Vector2.hpp" + +#define SDLF_REQUIRED_SUBSYSTEMS SDL_INIT_VIDEO namespace sf { class IWindow { public: - IWindow(); + void Create(Vector2u size, Vector2i position, std::string title, Uint32 flags = SDL_WINDOW_RESIZABLE); - private: + void Launch(bool threaded = false); + void Stop(); + + bool IsOpen() { return m_atomWindowOpen; } + + protected: + IWindow(Vector2u size, Vector2i position, std::string title, Uint32 flags = SDL_WINDOW_RESIZABLE); + + virtual bool OnCreate() { return true; } + virtual void OnClose() { } + virtual bool OnUpdate(double frametime) { return true; } + + protected: SDL_Window* m_pWindow; SDL_Renderer* m_pRenderer; + SDL_Event m_oEvent; + + private: + void MessageLoop(); + void Destroy(); + + private: + Vector2u m_oSize; + Vector2i m_oPosition; + std::string m_strTitle; + Uint32 m_uFlags; + + std::thread m_oMsgLoopThread; + std::atomic_bool m_atomWindowOpen; }; } \ No newline at end of file diff --git a/src/sdlf/maths/Vector2.hpp b/src/sdlf/util/Vector2.hpp similarity index 100% rename from src/sdlf/maths/Vector2.hpp rename to src/sdlf/util/Vector2.hpp diff --git a/src/sdlf/util/util.hpp b/src/sdlf/util/util.hpp new file mode 100644 index 0000000..82b3595 --- /dev/null +++ b/src/sdlf/util/util.hpp @@ -0,0 +1,3 @@ +#include "Vector2.hpp" + +#define THROW_IF_NULLPTR(x) { if(x == nullptr) throw SDL_GetError(); } \ No newline at end of file