From 802e725db2117c1a1a9517b14f55b4473ee60b84 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 18 Jun 2020 12:50:56 +0200 Subject: [PATCH] Added Screen system --- src/example/main.cpp | 36 +++++++++++++++++++++++++++++++----- src/sdlf/Screen.hpp | 12 ++++++------ src/sdlf/Window.cpp | 41 ++++++++++++++++++++++++++++++++++++----- src/sdlf/Window.hpp | 10 ++++++++++ src/sdlf/util/util.hpp | 4 +++- 5 files changed, 86 insertions(+), 17 deletions(-) diff --git a/src/example/main.cpp b/src/example/main.cpp index 48f5054..256923d 100644 --- a/src/example/main.cpp +++ b/src/example/main.cpp @@ -4,11 +4,35 @@ using namespace sf; -int Callback(void* userdata, SDL_Event* event) +class MyScreen : public IScreen { - std::cout << event->type << std::endl; - return 0; -} +public: + virtual void OnFocus() override + { + printf("Received Focus\n"); + } + + virtual void OnDefocus() override + { + printf("Lost Focus\n"); + } + + virtual void OnRender(SDL_Renderer* renderer) override + { + SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); + SDL_RenderClear(renderer); + } + + static MyScreen* Get() + { + static MyScreen* instance = new MyScreen; + return instance; + } +private: + MyScreen() = default; +}; + + class MyWindow : public IWindow { @@ -22,6 +46,7 @@ public: private: virtual bool OnCreate() override { + SwitchScreen(MyScreen::Get()); printf("On Create\n"); return true; } @@ -38,12 +63,13 @@ private: } }; + + int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); MyWindow window; - window.AddEventCallback(Callback, nullptr); try { diff --git a/src/sdlf/Screen.hpp b/src/sdlf/Screen.hpp index 12a742c..b901a1f 100644 --- a/src/sdlf/Screen.hpp +++ b/src/sdlf/Screen.hpp @@ -7,15 +7,15 @@ namespace sf class IScreen { public: + virtual void OnFocus() {} // Called when the screen is being switched to + virtual void OnDefocus() {} // Called when the screen is being switched from + virtual bool OnUpdate(double frametime) { return true; } // Called every frame + virtual void OnEvent(const SDL_Event& event) {} // Called after an event occurs + virtual void OnRender(SDL_Renderer* renderer) {} // Called for rendering protected: - IScreen(); + IScreen() = default; - virtual void OnFocus() = 0; // Called when the screen is being switched to - virtual void OnDefocus() = 0; // Called when the screen is being switched from - virtual void OnUpdate(double frametime) = 0; // Called every frame - virtual void OnEvent(const SDL_Event& event) = 0; // Called after an event occurs - private: }; } \ No newline at end of file diff --git a/src/sdlf/Window.cpp b/src/sdlf/Window.cpp index dd7feeb..b38607a 100644 --- a/src/sdlf/Window.cpp +++ b/src/sdlf/Window.cpp @@ -33,6 +33,10 @@ namespace sf THROW_IF_NULLPTR(m_pRenderer); } + m_oEventFunction = std::bind(&IWindow::OnEvent, this, std::placeholders::_1); + m_oUpdateFunction = std::bind(&IWindow::OnUpdate, this, std::placeholders::_1); + m_oRenderFunction = std::bind(&IWindow::OnRender, this, std::placeholders::_1); + } void IWindow::Destroy() @@ -67,10 +71,38 @@ namespace sf SDL_AddEventWatch(*(callback.target()), userdata); } + 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(&IScreen::OnUpdate, m_pCurrentScreen, std::placeholders::_1); + m_oRenderFunction = std::bind(&IScreen::OnRender, m_pCurrentScreen, std::placeholders::_1); + + m_pCurrentScreen->OnFocus(); + } + else + { + m_oEventFunction = std::bind(&IWindow::OnEvent, this, std::placeholders::_1); + m_oUpdateFunction = std::bind(&IWindow::OnUpdate, this, std::placeholders::_1); + m_oRenderFunction = std::bind(&IWindow::OnRender, this, std::placeholders::_1); + + } + } + 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) + m_oSize(size), m_oPosition(position), m_strTitle(title), m_uFlags(flags), + m_pCurrentScreen(nullptr) { } @@ -88,7 +120,7 @@ namespace sf { while (SDL_PollEvent(&m_oEvent)) { - OnEvent(m_oEvent); + m_oEventFunction(m_oEvent); if (m_oEvent.type == SDL_QUIT) { @@ -100,11 +132,10 @@ namespace sf std::chrono::steady_clock::now() - pastTime ).count(); pastTime = std::chrono::steady_clock::now(); - if (!OnUpdate(frametime)) + if (!m_oUpdateFunction(frametime)) m_atomWindowOpen = false; - SDL_SetRenderDrawColor(m_pRenderer, 0, 0, 0, 255); - SDL_RenderClear(m_pRenderer); + m_oRenderFunction(m_pRenderer); SDL_RenderPresent(m_pRenderer); } diff --git a/src/sdlf/Window.hpp b/src/sdlf/Window.hpp index ea98a73..e56abbd 100644 --- a/src/sdlf/Window.hpp +++ b/src/sdlf/Window.hpp @@ -7,6 +7,7 @@ #include "SDL.h" #include "util/Vector2.hpp" +#include "Screen.hpp" #define SDLF_REQUIRED_SUBSYSTEMS SDL_INIT_VIDEO @@ -26,6 +27,8 @@ namespace sf void AddEventCallback(EventCallback callback, void* userdata); + void SwitchScreen(IScreen* screen); + protected: IWindow(Vector2u size, Vector2i position, std::string title, Uint32 flags = SDL_WINDOW_RESIZABLE); @@ -33,6 +36,7 @@ namespace sf virtual void OnClose() { } virtual void OnEvent(const SDL_Event& event) { } virtual bool OnUpdate(double frametime) { return true; } + virtual void OnRender(SDL_Renderer* renderer) { } protected: SDL_Window* m_pWindow; @@ -49,7 +53,13 @@ namespace sf std::string m_strTitle; Uint32 m_uFlags; + IScreen* m_pCurrentScreen; + std::thread m_oMsgLoopThread; std::atomic_bool m_atomWindowOpen; + + std::function m_oEventFunction; + std::function m_oUpdateFunction; + std::function m_oRenderFunction; }; } \ No newline at end of file diff --git a/src/sdlf/util/util.hpp b/src/sdlf/util/util.hpp index 82b3595..184e946 100644 --- a/src/sdlf/util/util.hpp +++ b/src/sdlf/util/util.hpp @@ -1,3 +1,5 @@ #include "Vector2.hpp" -#define THROW_IF_NULLPTR(x) { if(x == nullptr) throw SDL_GetError(); } \ No newline at end of file +#define THROW_IF_NULLPTR(x) { if(x == nullptr) throw SDL_GetError(); } +#define IS_NULLPTR(x) ( x == nullptr ? true : false ) +#define IS_NOT_NULLPTR(x) !IS_NULLPTR(x) \ No newline at end of file