aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-11-02 21:49:27 +0800
committerYuqian Yang <crupest@crupest.life>2025-11-06 18:22:51 +0800
commitebb83c66e225375212f8e82e6b1bd8d3e3eb8646 (patch)
tree44774c8303e105bce280eefad88d756ff2395984 /src
parenta458ef365e3ace2e51e1bf0c2edefa5d02d032a8 (diff)
downloadcru-ebb83c66e225375212f8e82e6b1bd8d3e3eb8646.tar.gz
cru-ebb83c66e225375212f8e82e6b1bd8d3e3eb8646.tar.bz2
cru-ebb83c66e225375212f8e82e6b1bd8d3e3eb8646.zip
Impl timer on SDL.HEADmaindev
Diffstat (limited to 'src')
-rw-r--r--src/platform/gui/sdl/Base.cpp11
-rw-r--r--src/platform/gui/sdl/CMakeLists.txt1
-rw-r--r--src/platform/gui/sdl/UiApplication.cpp116
-rw-r--r--src/platform/gui/sdl/Window.cpp1
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"