diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/gui/sdl/Base.cpp | 11 | ||||
| -rw-r--r-- | src/platform/gui/sdl/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/platform/gui/sdl/UiApplication.cpp | 116 | ||||
| -rw-r--r-- | src/platform/gui/sdl/Window.cpp | 1 |
4 files changed, 94 insertions, 35 deletions
diff --git a/src/platform/gui/sdl/Base.cpp b/src/platform/gui/sdl/Base.cpp new file mode 100644 index 00000000..67c752e6 --- /dev/null +++ b/src/platform/gui/sdl/Base.cpp @@ -0,0 +1,11 @@ +#include "cru/platform/gui/sdl/Base.h" + +#include <SDL3/SDL_error.h> + +namespace cru::platform::gui::sdl { +void CheckSdlReturn(bool success) { + if (!success) { + throw SdlException(SDL_GetError()); + } +} +} diff --git a/src/platform/gui/sdl/CMakeLists.txt b/src/platform/gui/sdl/CMakeLists.txt index 7d95f681..3d128580 100644 --- a/src/platform/gui/sdl/CMakeLists.txt +++ b/src/platform/gui/sdl/CMakeLists.txt @@ -1,4 +1,5 @@ add_library(CruPlatformGuiSdl + Base.cpp UiApplication.cpp Window.cpp ) diff --git a/src/platform/gui/sdl/UiApplication.cpp b/src/platform/gui/sdl/UiApplication.cpp index a961ce84..b448d8f0 100644 --- a/src/platform/gui/sdl/UiApplication.cpp +++ b/src/platform/gui/sdl/UiApplication.cpp @@ -1,45 +1,67 @@ - #include "cru/platform/gui/sdl/UiApplication.h" #include "cru/base/Base.h" -#include "cru/platform/graphics/cairo/CairoGraphicsFactory.h" +#include "cru/platform/graphics/Factory.h" +#include "cru/platform/gui/sdl/Base.h" #include "cru/platform/gui/sdl/Window.h" +#include <SDL3/SDL_events.h> +#include <SDL3/SDL_init.h> +#include <SDL3/SDL_timer.h> #include <algorithm> +#include <chrono> +#include <functional> namespace cru::platform::gui::sdl { -SdlUiApplication::SdlUiApplication( - graphics::cairo::CairoGraphicsFactory *cairo_factory) { - release_cairo_factory_ = false; - if (cairo_factory == nullptr) { - cairo_factory = new graphics::cairo::CairoGraphicsFactory(); - release_cairo_factory_ = true; - } - cairo_factory_ = cairo_factory; +SdlUiApplication::SdlUiApplication(graphics::IGraphicsFactory* graphics_factory, + bool release_graphics_factory) + : graphics_factory_(graphics_factory), + release_graphics_factory_(release_graphics_factory), + quit_code_(0) { + CheckSdlReturn(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)); + empty_event_type_ = SDL_RegisterEvents(1); } SdlUiApplication::~SdlUiApplication() { - if (release_cairo_factory_) { - delete cairo_factory_; - } -} + SDL_Quit(); -graphics::cairo::CairoGraphicsFactory *SdlUiApplication::GetCairoFactory() { - return cairo_factory_; + if (release_graphics_factory_) { + delete graphics_factory_; + } } int SdlUiApplication::Run() { - auto exit_code = event_loop_.Run(); + while (true) { + auto now = std::chrono::steady_clock::now(); + + if (auto result = timers_.Update(now)) { + result->data(); + continue; + } + + auto timeout = timers_.NextTimeout(now); + + SDL_Event event; + CheckSdlReturn(timeout ? SDL_WaitEventTimeout(&event, timeout->count()) + : SDL_WaitEvent(&event)); + if (event.type == SDL_EVENT_QUIT) { + break; + } + } - for (const auto &handler : this->quit_handlers_) { + for (const auto& handler : this->quit_handlers_) { handler(); } - return exit_code; + return quit_code_; } void SdlUiApplication::RequestQuit(int quit_code) { - event_loop_.RequestQuit(quit_code); + quit_code_ = quit_code; + SDL_Event event; + event.type = SDL_EVENT_QUIT; + event.quit.timestamp = SDL_GetTicksNS(); + CheckSdlReturn(SDL_PushEvent(&event)); } void SdlUiApplication::AddOnQuitHandler(std::function<void()> handler) { @@ -56,47 +78,73 @@ void SdlUiApplication::SetQuitOnAllWindowClosed( } long long SdlUiApplication::SetImmediate(std::function<void()> action) { - return event_loop_.SetImmediate(std::move(action)); + return SetTimeout(std::chrono::milliseconds::zero(), std::move(action)); } long long SdlUiApplication::SetTimeout(std::chrono::milliseconds milliseconds, std::function<void()> action) { - return event_loop_.SetTimeout(std::move(action), std::move(milliseconds)); + return SetTimer(milliseconds, std::move(action), false); } long long SdlUiApplication::SetInterval(std::chrono::milliseconds milliseconds, std::function<void()> action) { - return event_loop_.SetInterval(std::move(action), std::move(milliseconds)); + return SetTimer(milliseconds, std::move(action), true); } void SdlUiApplication::CancelTimer(long long id) { - return event_loop_.CancelTimer(static_cast<int>(id)); + return timers_.Remove(static_cast<int>(id)); } -std::vector<INativeWindow *> SdlUiApplication::GetAllWindow() { - std::vector<INativeWindow *> windows(windows_.size()); +std::vector<INativeWindow*> SdlUiApplication::GetAllWindow() { + std::vector<INativeWindow*> windows(windows_.size()); std::ranges::copy(windows_, windows.begin()); return windows; } -INativeWindow *SdlUiApplication::CreateWindow() { return new SdlWindow(this); } +INativeWindow* SdlUiApplication::CreateWindow() { return new SdlWindow(this); } -cru::platform::graphics::IGraphicsFactory * +cru::platform::graphics::IGraphicsFactory* SdlUiApplication::GetGraphicsFactory() { - return cairo_factory_; + return graphics_factory_; } -ICursorManager *SdlUiApplication::GetCursorManager() { NotImplemented(); } +ICursorManager* SdlUiApplication::GetCursorManager() { NotImplemented(); } -IClipboard *SdlUiApplication::GetClipboard() { NotImplemented(); } +IClipboard* SdlUiApplication::GetClipboard() { NotImplemented(); } -IMenu *SdlUiApplication::GetApplicationMenu() { return nullptr; } +IMenu* SdlUiApplication::GetApplicationMenu() { return nullptr; } -void SdlUiApplication::RegisterWindow(SdlWindow *window) { +void SdlUiApplication::RegisterWindow(SdlWindow* window) { windows_.push_back(window); } -void SdlUiApplication::UnregisterWindow(SdlWindow *window) { +void SdlUiApplication::UnregisterWindow(SdlWindow* window) { std::erase(windows_, window); } + +void SdlUiApplication::RunOnMainThread(std::function<void()> action) { + auto p = new std::function<void()>(std::move(action)); + SDL_RunOnMainThread( + [](void* userdata) { + auto action = static_cast<std::function<void()>*>(userdata); + (*action)(); + delete action; + }, + p, false); +} + +void SdlUiApplication::PostEmptyEvent() { + SDL_Event event; + SDL_zero(event); + event.type = empty_event_type_; + event.user.timestamp = SDL_GetTicksNS(); + SDL_PushEvent(&event); +} + +long long SdlUiApplication::SetTimer(std::chrono::milliseconds milliseconds, + std::function<void()> action, + bool repeat) { + PostEmptyEvent(); + return timers_.Add(std::move(action), milliseconds, repeat); +} } // namespace cru::platform::gui::sdl diff --git a/src/platform/gui/sdl/Window.cpp b/src/platform/gui/sdl/Window.cpp index e0898cb1..72ccc873 100644 --- a/src/platform/gui/sdl/Window.cpp +++ b/src/platform/gui/sdl/Window.cpp @@ -3,7 +3,6 @@ #include "cru/platform/GraphicsBase.h" #include "cru/platform/graphics/NullPainter.h" #include "cru/platform/graphics/Painter.h" -#include "cru/platform/gui/Base.h" #include "cru/platform/gui/Window.h" #include "cru/platform/gui/sdl/UiApplication.h" |
