Added centralized SDL initialization
This commit is contained in:
parent
23e69bfdfc
commit
f0f644102b
13 changed files with 189 additions and 53 deletions
1
other/TODO.txt
Normal file
1
other/TODO.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
Add Color constants to ostd::Color
|
||||
|
|
@ -1 +1 @@
|
|||
2040
|
||||
2041
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
[0.2.1958]
|
||||
Added ostd::OutputHandlerBase::tab() virtual function
|
||||
Added ogfx::WindowBaseOutputHandler class
|
||||
|
||||
[0.2.1936]
|
||||
Added JsonFile class to handle Json files
|
||||
Added MidiParser class to parse Midi files
|
||||
|
||||
[0.2.1923]
|
||||
Added MacOS support
|
||||
|
||||
[0.1.1823]
|
||||
Added more Builtin signals
|
||||
|
||||
[0.1.1818]
|
||||
Added ostd::String::fixedLength(...) method, with corresponding 'new_fixedLength' version.
|
||||
Added "KeyboardController" class to <Console.hpp> (implemented in <Keyboard.cpp>) to handle
|
||||
keypresses in the console in a cross-platform way
|
||||
Added helper functions in ostd::Utils for dealing with raw arrays
|
||||
|
|
@ -20,15 +20,11 @@
|
|||
|
||||
#include "Window.hpp"
|
||||
#include "../../ostd/utils/Time.hpp"
|
||||
#include "io/IOHandlers.hpp"
|
||||
#include "string/String.hpp"
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
const Uint32 REDRAW_EVENT = SDL_RegisterEvents(1);
|
||||
|
||||
WindowCore::~WindowCore(void)
|
||||
{
|
||||
__on_window_destroy();
|
||||
|
|
@ -36,21 +32,18 @@ namespace ogfx
|
|||
SDL_DestroyCursor(m_cursor_Arrow);
|
||||
SDL_DestroyRenderer(m_renderer);
|
||||
SDL_DestroyWindow(m_window);
|
||||
SDL_Quit();
|
||||
TTF_Quit();
|
||||
SDLSysten::release();
|
||||
}
|
||||
|
||||
void WindowCore::initialize(int32_t width, int32_t height, const ostd::String& title)
|
||||
{
|
||||
if (m_initialized) return;
|
||||
SDLSysten::acquire();
|
||||
m_windowWidth = width;
|
||||
m_windowHeight = height;
|
||||
m_title = title;
|
||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||
{
|
||||
printf( "SDL could not initialize! Error: %s\n", SDL_GetError() );
|
||||
exit(1);
|
||||
}
|
||||
setBlockingEventsRefreshFPS(DefaultBlockingEventsFPS);
|
||||
|
||||
m_window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOW_RESIZABLE);
|
||||
m_renderer = SDL_CreateRenderer(m_window, nullptr);
|
||||
SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight);
|
||||
|
|
@ -60,6 +53,13 @@ namespace ogfx
|
|||
m_cursor_Arrow = SDL_CreateSystemCursor(SDL_SystemCursor::SDL_SYSTEM_CURSOR_DEFAULT);
|
||||
m_cursor_IBeam = SDL_CreateSystemCursor(SDL_SystemCursor::SDL_SYSTEM_CURSOR_TEXT);
|
||||
|
||||
m_wout.attachWindow(*this);
|
||||
m_wout.setFontSize(22);
|
||||
m_wout.setConsoleMaxCharacters({ 1000, 1000 });
|
||||
m_wout.setConsolePosition({ 5, 5 });
|
||||
m_wout.setWrapMode(ogfx::GraphicsWindowOutputHandler::eWrapMode::NewLine);
|
||||
m_wout.setDefaultForegroundColor({ 255, 255, 255, 255 });
|
||||
|
||||
m_initialized = true;
|
||||
m_running = true;
|
||||
|
||||
|
|
@ -81,6 +81,12 @@ namespace ogfx
|
|||
__on_window_init(width, height, title);
|
||||
}
|
||||
|
||||
void WindowCore::mainLoop(void)
|
||||
{
|
||||
if (isInitialized())
|
||||
__main_loop();
|
||||
}
|
||||
|
||||
void WindowCore::close(void)
|
||||
{
|
||||
__on_window_close();
|
||||
|
|
@ -136,6 +142,24 @@ namespace ogfx
|
|||
SDL_DestroySurface(appIcon);
|
||||
}
|
||||
|
||||
void WindowCore::setBlockingEventsRefreshFPS(uint32_t fps)
|
||||
{
|
||||
if (fps == 0 || fps > MaxBlockingEventsFPS)
|
||||
{
|
||||
setBlockingEventsRefreshFPS(DefaultBlockingEventsFPS);
|
||||
return;
|
||||
}
|
||||
m_blockingEventsDelay = static_cast<int>(std::floor((1.0 / (double)fps) * 1000));
|
||||
}
|
||||
|
||||
void WindowCore::requestRedraw(void)
|
||||
{
|
||||
SDL_Event e{};
|
||||
SDL_zero(e);
|
||||
e.type = REDRAW_EVENT;
|
||||
SDL_PushEvent(&e);
|
||||
}
|
||||
|
||||
MouseEventData WindowCore::get_mouse_state(void)
|
||||
{
|
||||
float mx = 0, my = 0;
|
||||
|
|
@ -159,7 +183,7 @@ namespace ogfx
|
|||
|
||||
if (isBlockingEventsEnabled())
|
||||
{
|
||||
if (SDL_WaitEventTimeout(&event, 16))
|
||||
if (SDL_WaitEventTimeout(&event, m_blockingEventsDelay))
|
||||
__handle_event(event);
|
||||
}
|
||||
else
|
||||
|
|
@ -169,9 +193,26 @@ namespace ogfx
|
|||
}
|
||||
}
|
||||
|
||||
void WindowCore::before_render(void)
|
||||
{
|
||||
SDL_SetRenderDrawColor(m_renderer, getClearColor().r, getClearColor().g, getClearColor().b, getClearColor().a);
|
||||
if (m_refreshScreen)
|
||||
SDL_RenderClear(m_renderer);
|
||||
wout().beginFrame();
|
||||
}
|
||||
|
||||
void WindowCore::after_render(void)
|
||||
{
|
||||
SDL_RenderPresent(m_renderer);
|
||||
}
|
||||
|
||||
void WindowCore::__handle_event(SDL_Event& event)
|
||||
{
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
if (event.type == REDRAW_EVENT)
|
||||
{
|
||||
//Doesn't need to do anything, the event exists just to make SDL_WaitEventTimeout() return early
|
||||
}
|
||||
else if (event.type == SDL_EVENT_QUIT)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
|
@ -254,13 +295,11 @@ namespace ogfx
|
|||
void GraphicsWindow::__main_loop(void)
|
||||
{
|
||||
handle_events();
|
||||
SDL_SetRenderDrawColor(m_renderer, getClearColor().r, getClearColor().g, getClearColor().b, getClearColor().a);
|
||||
if (m_refreshScreen)
|
||||
SDL_RenderClear(m_renderer);
|
||||
before_render();
|
||||
m_fixedUpdateTImer.update();
|
||||
onUpdate();
|
||||
onRender();
|
||||
SDL_RenderPresent(m_renderer);
|
||||
after_render();
|
||||
m_frameTimeAcc += m_fpsUpdateClock.restart(ostd::eTimeUnits::Seconds);
|
||||
m_frameCount++;
|
||||
m_fpsUpdateTimer.update();
|
||||
|
|
@ -299,10 +338,10 @@ namespace ogfx
|
|||
while (isRunning())
|
||||
{
|
||||
handle_events();
|
||||
SDL_SetRenderDrawColor(m_renderer, getClearColor().r, getClearColor().g, getClearColor().b, getClearColor().a);
|
||||
SDL_RenderClear(m_renderer);
|
||||
before_render();
|
||||
onRedraw(m_gfx);
|
||||
m_gfx.drawString("Hello World", { 100, 100 }, { 255, 0, 0 });
|
||||
SDL_RenderPresent(m_renderer);
|
||||
after_render();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <ogfx/utils/SDLInclude.hpp>
|
||||
#include <ostd/utils/Signals.hpp>
|
||||
#include <ostd/utils/Time.hpp>
|
||||
#include <ostd/io/IOHandlers.hpp>
|
||||
#include <ogfx/gui/Events.hpp>
|
||||
#include <ogfx/render/BasicRenderer.hpp>
|
||||
#include <ogfx/gui/WindowOutputHandler.hpp>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
|
|
@ -38,13 +38,15 @@ namespace ogfx
|
|||
virtual ~WindowCore(void);
|
||||
inline WindowCore(int32_t width, int32_t height, const ostd::String& title) { initialize(width, height, title); }
|
||||
void initialize(int32_t width, int32_t height, const ostd::String& title);
|
||||
inline void mainLoop(void) { if (isInitialized()) __main_loop(); }
|
||||
void mainLoop(void);
|
||||
void close(void);
|
||||
void setSize(int32_t width, int32_t height);
|
||||
void setTitle(const ostd::String& title);
|
||||
void setCursor(eCursor cursor);
|
||||
void enableResizable(bool enable = true);
|
||||
void setIcon(const ostd::String& iconFilePath);
|
||||
void setBlockingEventsRefreshFPS(uint32_t fps);
|
||||
void requestRedraw(void);
|
||||
|
||||
inline bool isInitialized(void) const { return m_initialized; }
|
||||
inline bool isRunning(void) const { return m_running; }
|
||||
|
|
@ -60,10 +62,14 @@ namespace ogfx
|
|||
inline SDL_Renderer* getSDLRenderer(void) { return m_renderer; }
|
||||
inline void enableBlockingEvents(bool enable = true) { m_blockingEvents = enable; }
|
||||
inline bool isBlockingEventsEnabled(void) const { return m_blockingEvents; }
|
||||
inline ostd::ConsoleOutputHandler& out(void) { return m_out; }
|
||||
inline GraphicsWindowOutputHandler& wout(void) { return m_wout; }
|
||||
|
||||
protected:
|
||||
MouseEventData get_mouse_state(void);
|
||||
virtual void handle_events(void);
|
||||
virtual void before_render(void);
|
||||
virtual void after_render(void);
|
||||
inline virtual void __on_event(SDL_Event& event) { }
|
||||
inline virtual void __on_window_init(int32_t width, int32_t height, const ostd::String& title) { }
|
||||
inline virtual void __on_window_destroy(void) { }
|
||||
|
|
@ -76,6 +82,8 @@ namespace ogfx
|
|||
protected:
|
||||
SDL_Window* m_window { nullptr };
|
||||
SDL_Renderer* m_renderer { nullptr };
|
||||
ostd::ConsoleOutputHandler m_out;
|
||||
GraphicsWindowOutputHandler m_wout;
|
||||
|
||||
private:
|
||||
ostd::Color m_clearColor { 10, 10, 10, 255 };
|
||||
|
|
@ -83,15 +91,21 @@ namespace ogfx
|
|||
int32_t m_windowWidth { 0 };
|
||||
int32_t m_windowHeight { 0 };
|
||||
ostd::String m_title { "" };
|
||||
int32_t m_blockingEventsDelay { 33 };
|
||||
|
||||
bool m_running { false };
|
||||
bool m_initialized { false };
|
||||
bool m_visible { true };
|
||||
bool m_blockingEvents { false };
|
||||
bool m_resizeable { true };
|
||||
bool m_refreshScreen { true };
|
||||
|
||||
SDL_Cursor* m_cursor_IBeam { nullptr };
|
||||
SDL_Cursor* m_cursor_Arrow { nullptr };
|
||||
|
||||
public:
|
||||
inline static constexpr int32_t MaxBlockingEventsFPS { 240 };
|
||||
inline static constexpr int32_t DefaultBlockingEventsFPS { 30 };
|
||||
};
|
||||
class GraphicsWindow : public WindowCore
|
||||
{
|
||||
|
|
@ -124,7 +138,6 @@ namespace ogfx
|
|||
ostd::Timer m_fpsUpdateClock;
|
||||
uint64_t m_frameTimeAcc { 0 };
|
||||
int32_t m_frameCount { 0 };
|
||||
bool m_refreshScreen { true };
|
||||
};
|
||||
namespace gui
|
||||
{
|
||||
|
|
@ -139,6 +152,7 @@ namespace ogfx
|
|||
inline virtual void onDestroy(void) { }
|
||||
inline virtual void onClose(void) { }
|
||||
inline virtual void onSDLEvent(SDL_Event& event) { }
|
||||
inline virtual void onRedraw(BasicRenderer2D& gfx) { }
|
||||
|
||||
protected:
|
||||
void __on_window_init(int32_t width, int32_t height, const ostd::String& title) override;
|
||||
|
|
@ -148,8 +162,7 @@ namespace ogfx
|
|||
void __main_loop(void) override;
|
||||
|
||||
private:
|
||||
ogfx::BasicRenderer2D m_gfx;
|
||||
ostd::ConsoleOutputHandler m_out;
|
||||
BasicRenderer2D m_gfx;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace ogfx
|
|||
{
|
||||
using namespace ostd;
|
||||
|
||||
|
||||
GraphicsWindowOutputHandler::GraphicsWindowOutputHandler(void)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,24 @@
|
|||
|
||||
namespace ogfx
|
||||
{
|
||||
TTFRenderer::SignalHandler::SignalHandler(TTFRenderer& parent) : m_parent(parent)
|
||||
{
|
||||
enableSignals();
|
||||
connectSignal(ostd::tBuiltinSignals::BeforeSDLShutdown);
|
||||
setTypeName("ostd::GraphicsWindowOutputHandler::SignalHandler");
|
||||
validate();
|
||||
}
|
||||
|
||||
void TTFRenderer::SignalHandler::handleSignal(ostd::tSignal& signal)
|
||||
{
|
||||
if (signal.ID == ostd::tBuiltinSignals::BeforeSDLShutdown)
|
||||
{
|
||||
m_parent.closeFont();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TTFRenderer::~TTFRenderer(void)
|
||||
{
|
||||
closeFont();
|
||||
|
|
@ -179,12 +197,6 @@ namespace ogfx
|
|||
{
|
||||
if (TTFRenderer::m_initialized) return set_error_state(tErrors::NoError);
|
||||
if (renderer == nullptr) return set_error_state(tErrors::NullRenderer);
|
||||
if (!TTF_Init())
|
||||
{
|
||||
print_ttf_error("TTF_Init");
|
||||
SDL_Quit();
|
||||
return set_error_state(tErrors::FailedToLoad);
|
||||
}
|
||||
m_renderer = renderer;
|
||||
TTFRenderer::m_initialized = true;
|
||||
return set_error_state(tErrors::NoError);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,15 @@ namespace ogfx
|
|||
{
|
||||
class TTFRenderer
|
||||
{
|
||||
private: class SignalHandler : public ostd::BaseObject
|
||||
{
|
||||
public:
|
||||
SignalHandler(TTFRenderer& parent);
|
||||
void handleSignal(ostd::tSignal& signal) override;
|
||||
|
||||
private:
|
||||
TTFRenderer& m_parent;
|
||||
};
|
||||
public: struct tErrors
|
||||
{
|
||||
inline static constexpr int32_t NoError = 0;
|
||||
|
|
@ -68,6 +77,7 @@ namespace ogfx
|
|||
|
||||
private:
|
||||
ostd::ConsoleOutputHandler m_out;
|
||||
SignalHandler m_sigHndl { *this };
|
||||
bool m_initialized { false };
|
||||
bool m_fontOpen { false };
|
||||
TTF_Font* m_font { nullptr };
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/utils/Defines.hpp>
|
||||
#include <ostd/io/Logger.hpp>
|
||||
#include <ostd/utils/Signals.hpp>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.h>
|
||||
|
|
@ -29,3 +31,55 @@
|
|||
#include <SDL3/SDL_surface.h>
|
||||
#include <SDL3/SDL_rect.h>
|
||||
#include <SDL3/SDL_render.h>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
class SDLSysten
|
||||
{
|
||||
public:
|
||||
static inline void acquire(void)
|
||||
{
|
||||
if (s_refCount == 0)
|
||||
init_sdl();
|
||||
s_refCount++;
|
||||
}
|
||||
|
||||
static inline void release(void)
|
||||
{
|
||||
s_refCount--;
|
||||
if (s_refCount == 0)
|
||||
shutdown_sdl();
|
||||
}
|
||||
|
||||
private:
|
||||
static inline void init_sdl(void)
|
||||
{
|
||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||
{
|
||||
OX_FATAL("SDL could not initialize! Error: %s\n", SDL_GetError());
|
||||
exit(ErrorSDLInitFailed);
|
||||
}
|
||||
if (!TTF_Init())
|
||||
{
|
||||
OX_FATAL("SDL_ttf could not initialize! Error: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(ErrorSDLTTFInitFailed);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void shutdown_sdl(void)
|
||||
{
|
||||
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::BeforeSDLShutdown, ostd:: tSignalPriority::RealTime);
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
private:
|
||||
inline static int s_refCount { 0 };
|
||||
|
||||
public:
|
||||
inline static constexpr int32_t ErrorSDLInitFailed { 1 };
|
||||
inline static constexpr int32_t ErrorSDLTTFInitFailed { 2 };
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,3 +45,11 @@
|
|||
|
||||
#include <ostd/utils/Signals.hpp>
|
||||
#include <ostd/utils/Time.hpp>
|
||||
|
||||
namespace ostd
|
||||
{
|
||||
inline void initialize(void)
|
||||
{
|
||||
ostd::SignalHandler::init(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ namespace ostd
|
|||
SignalHandler::m_delegatedSignals.reserve(SignalHandler::__DELEGATED_SIGNALS_BUFFER_START_SIZE);
|
||||
SignalHandler::m_onGuiEventRecievers.clear();
|
||||
SignalHandler::m_onGuiEventRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE);
|
||||
SignalHandler::m_beforeSDLShutdownRecievers.clear();
|
||||
SignalHandler::m_beforeSDLShutdownRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE);
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +73,8 @@ namespace ostd
|
|||
sig_list = &m_windowClosedRecievers;
|
||||
else if (signal_id == tBuiltinSignals::OnGuiEvent)
|
||||
sig_list = &m_onGuiEventRecievers;
|
||||
else if (signal_id == tBuiltinSignals::BeforeSDLShutdown)
|
||||
sig_list = &m_beforeSDLShutdownRecievers;
|
||||
else if (signal_id > tBuiltinSignals::CustomSignalBase)
|
||||
sig_list = &m_customRecievers;
|
||||
if (sig_list == nullptr)
|
||||
|
|
@ -110,6 +114,8 @@ namespace ostd
|
|||
m_windowClosedRecievers.push_back({ &object, signal_id });
|
||||
else if (signal_id == tBuiltinSignals::OnGuiEvent)
|
||||
m_onGuiEventRecievers.push_back({ &object, signal_id });
|
||||
else if (signal_id == tBuiltinSignals::BeforeSDLShutdown)
|
||||
m_beforeSDLShutdownRecievers.push_back({ &object, signal_id });
|
||||
else if (signal_id > tBuiltinSignals::CustomSignalBase)
|
||||
m_customRecievers.push_back({ &object, signal_id });
|
||||
else
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ namespace ostd
|
|||
|
||||
inline static constexpr uint32_t OnGuiEvent = 0x2001;
|
||||
|
||||
inline static constexpr uint32_t BeforeSDLShutdown = 0x3001;
|
||||
|
||||
inline static constexpr uint32_t WindowResized = 0x1001;
|
||||
inline static constexpr uint32_t WindowClosed = 0x1002;
|
||||
/*********************/
|
||||
|
|
@ -106,6 +108,7 @@ namespace ostd
|
|||
inline static std::vector<tSignalObjPair> m_windowResizedRecievers;
|
||||
inline static std::vector<tSignalObjPair> m_windowClosedRecievers;
|
||||
inline static std::vector<tSignalObjPair> m_onGuiEventRecievers;
|
||||
inline static std::vector<tSignalObjPair> m_beforeSDLShutdownRecievers;
|
||||
/************************************/
|
||||
|
||||
inline static constexpr uint16_t __SIGNAL_BUFFER_START_SIZE { 128 };
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
* ListBox
|
||||
* ComboBox
|
||||
* TreeView
|
||||
* Save/Open File Dialogs (and folder dialogs)
|
||||
* Tab Panel
|
||||
*/
|
||||
|
||||
#include <ogfx/ogfx.hpp>
|
||||
|
|
@ -58,11 +60,17 @@ class Window : public ogfx::gui::Window
|
|||
}
|
||||
}
|
||||
|
||||
void onRedraw(ogfx::BasicRenderer2D& gfx) override
|
||||
{
|
||||
wout().fg(ostd::Color { 255, 0, 0 }).p("Hello ").fg(ostd::Color { 0, 0, 255 }).p("World");
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ostd::initialize();
|
||||
Window window;
|
||||
window.initialize(800, 600, "OmniaFramework - Test Window");
|
||||
window.setClearColor({ 0, 0, 0 });
|
||||
|
|
|
|||
Loading…
Reference in a new issue