aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cru/base/Guard.h112
-rw-r--r--include/cru/base/platform/win/Base.h73
-rw-r--r--include/cru/platform/gui/TimerHelper.h69
-rw-r--r--include/cru/platform/gui/UiApplication.h9
-rw-r--r--include/cru/platform/gui/xcb/Window.h2
-rw-r--r--include/cru/ui/controls/TextHostControlService.h1
-rw-r--r--include/cru/ui/host/LayoutPaintCycler.h1
-rw-r--r--include/cru/ui/render/ScrollBar.h1
8 files changed, 115 insertions, 153 deletions
diff --git a/include/cru/base/Guard.h b/include/cru/base/Guard.h
index 6b6cf851..65e2dee4 100644
--- a/include/cru/base/Guard.h
+++ b/include/cru/base/Guard.h
@@ -1,7 +1,11 @@
#pragma once
+#include "Base.h"
+#include "cru/base/Base.h"
+
#include <cstdlib>
#include <functional>
+#include <optional>
namespace cru {
struct Guard {
@@ -25,18 +29,23 @@ struct Guard {
ExitFunc on_exit;
};
-template <typename T>
-struct FreeLater {
- FreeLater(T* ptr) : ptr(ptr) {}
- ~FreeLater() { ::free(ptr); }
+/**
+ * FreeFunc must handle nullptr correctly.
+ */
+template <typename T, void (*FreeFunc)(T*) noexcept>
+struct TAutoFreePtr {
+ TAutoFreePtr(T* ptr) : ptr(ptr) {}
+ ~TAutoFreePtr() { FreeFunc(ptr); }
- FreeLater(const FreeLater& other) = delete;
- FreeLater& operator=(const FreeLater& other) = delete;
+ CRU_DELETE_COPY(TAutoFreePtr)
- FreeLater(FreeLater&& other) : ptr(other.ptr) { other.ptr = nullptr; }
- FreeLater& operator=(FreeLater&& other) {
+ TAutoFreePtr(TAutoFreePtr&& other) noexcept : ptr(other.ptr) {
+ other.ptr = nullptr;
+ }
+
+ TAutoFreePtr& operator=(TAutoFreePtr&& other) noexcept {
if (this != &other) {
- ::free(ptr);
+ FreeFunc(ptr);
ptr = other.ptr;
other.ptr = nullptr;
}
@@ -49,4 +58,89 @@ struct FreeLater {
T* ptr;
};
+namespace details {
+template <typename T>
+inline void MyFree(T* p) noexcept {
+ ::free(p);
+}
+} // namespace details
+
+template <typename T>
+using AutoFreePtr = TAutoFreePtr<T, details::MyFree<T>>;
+
+template <typename T, void (*DestructFunc)(T value) noexcept>
+class AutoDestruct {
+ public:
+ AutoDestruct() : value_(std::nullopt), auto_destruct_(false) {}
+
+ AutoDestruct(T value, bool auto_destruct = true)
+ : value_(std::move(value)), auto_destruct_(auto_destruct) {}
+
+ CRU_DELETE_COPY(AutoDestruct)
+
+ AutoDestruct(AutoDestruct&& other) noexcept
+ : value_(std::move(other.value_)), auto_destruct_(other.auto_destruct_) {
+ other.value_ = std::nullopt;
+ other.auto_destruct_ = false;
+ }
+
+ AutoDestruct& operator=(AutoDestruct&& other) noexcept {
+ if (this != &other) {
+ DoDestruct();
+ value_ = other.value_;
+ auto_destruct_ = other.auto_destruct_;
+ other.value_ = std::nullopt;
+ other.auto_destruct_ = false;
+ }
+ return *this;
+ }
+
+ ~AutoDestruct() { DoDestruct(); }
+
+ public:
+ bool IsValid() const { return value_.has_value(); }
+
+ void CheckValid(
+ std::optional<std::string_view> additional_message = std::nullopt) const {
+ if (!IsValid()) {
+ std::string message("AutoDestruct contains no object.");
+ if (additional_message) {
+ message += " ";
+ message += *additional_message;
+ }
+ throw Exception(std::move(message));
+ }
+ }
+
+ const T& Get() const {
+ CheckValid();
+ return *value_;
+ }
+
+ T Release() {
+ CheckValid();
+ auto value = std::move(*value_);
+ value_ = std::nullopt;
+ auto_destruct_ = false;
+ return value;
+ }
+
+ void Reset(std::optional<T> value = std::nullopt) {
+ DoDestruct();
+ value_ = std::move(value);
+ }
+
+ explicit operator bool() const { return value_.has_value(); }
+
+ private:
+ void DoDestruct() {
+ if (auto_destruct_ && value_) {
+ DestructFunc(*value_);
+ }
+ }
+
+ private:
+ std::optional<T> value_;
+ bool auto_destruct_;
+};
} // namespace cru
diff --git a/include/cru/base/platform/win/Base.h b/include/cru/base/platform/win/Base.h
index 8d221c83..cdd92541 100644
--- a/include/cru/base/platform/win/Base.h
+++ b/include/cru/base/platform/win/Base.h
@@ -6,8 +6,8 @@
#include "../../Base.h"
#include "../../Bitmask.h"
+#include "../../Guard.h"
-#include <optional>
#include <string_view>
#define NOMINMAX
@@ -54,80 +54,11 @@ inline void CheckWinReturn(BOOL r, std::string_view message = "") {
}
}
-template <typename H, void (*CloseFunc)(H handle) noexcept>
-class CRU_BASE_API TWin32Handle {
- public:
- TWin32Handle() : handle_(std::nullopt), auto_close_(false) {}
-
- TWin32Handle(H handle, bool auto_close)
- : handle_(handle), auto_close_(auto_close) {}
-
- CRU_DELETE_COPY(TWin32Handle)
-
- TWin32Handle(TWin32Handle&& other) noexcept
- : handle_(other.handle_), auto_close_(other.auto_close_) {
- other.handle_ = std::nullopt;
- other.auto_close_ = false;
- }
-
- TWin32Handle& operator=(TWin32Handle&& other) noexcept {
- if (this != &other) {
- DoClose();
- handle_ = other.handle_;
- auto_close_ = other.auto_close_;
- other.handle_ = std::nullopt;
- other.auto_close_ = false;
- }
- return *this;
- }
-
- ~TWin32Handle() { DoClose(); }
-
- public:
- bool IsValid() const { return handle_.has_value(); }
-
- void CheckValid(
- std::optional<std::string_view> additional_message = std::nullopt) const {
- if (!IsValid()) {
- std::string message("The win32 handle is invalid.");
- if (additional_message) {
- message += " ";
- message += *additional_message;
- }
- throw Exception(std::move(message));
- }
- }
-
- H Get() const {
- CheckValid();
- return *handle_;
- }
-
- H Release() {
- CheckValid();
- auto handle = *handle_;
- handle_ = std::nullopt;
- auto_close_ = false;
- return handle;
- }
-
- private:
- void DoClose() {
- if (auto_close_ && handle_) {
- CloseFunc(*handle_);
- }
- }
-
- private:
- std::optional<H> handle_;
- bool auto_close_;
-};
-
namespace details {
inline void MyCloseHandle(HANDLE handle) noexcept { ::CloseHandle(handle); }
} // namespace details
-using Win32Handle = TWin32Handle<HANDLE, details::MyCloseHandle>;
+using Win32Handle = AutoDestruct<HANDLE, details::MyCloseHandle>;
struct UniDirectionalWin32PipeResult {
Win32Handle read;
diff --git a/include/cru/platform/gui/TimerHelper.h b/include/cru/platform/gui/TimerHelper.h
deleted file mode 100644
index 91d436a4..00000000
--- a/include/cru/platform/gui/TimerHelper.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-#include "UiApplication.h"
-
-namespace cru::platform::gui {
-
-class TimerAutoCanceler {
- public:
- TimerAutoCanceler() : id_(0) {}
- explicit TimerAutoCanceler(long long id) : id_(id) {}
-
- CRU_DELETE_COPY(TimerAutoCanceler)
-
- TimerAutoCanceler(TimerAutoCanceler&& other) : id_(other.id_) {
- other.id_ = 0;
- }
-
- TimerAutoCanceler& operator=(TimerAutoCanceler&& other) {
- if (&other == this) {
- return *this;
- }
- Reset(other.id_);
- other.id_ = 0;
- return *this;
- }
-
- TimerAutoCanceler& operator=(long long other) {
- return this->operator=(TimerAutoCanceler(other));
- }
-
- ~TimerAutoCanceler() { Reset(); }
-
- long long Release() {
- auto temp = id_;
- id_ = 0;
- return temp;
- }
-
- void Reset(long long id = 0) {
- if (id_ > 0) IUiApplication::GetInstance()->CancelTimer(id_);
- id_ = id;
- }
-
- explicit operator bool() const { return id_; }
-
- private:
- long long id_;
-};
-
-class TimerListAutoCanceler {
- public:
- TimerListAutoCanceler() = default;
- CRU_DELETE_COPY(TimerListAutoCanceler)
- CRU_DEFAULT_MOVE(TimerListAutoCanceler)
- ~TimerListAutoCanceler() = default;
-
- TimerListAutoCanceler& operator+=(long long id) {
- list_.push_back(TimerAutoCanceler(id));
- return *this;
- }
-
- void Clear() { list_.clear(); }
-
- bool IsEmpty() const { return list_.empty(); }
-
- private:
- std::vector<TimerAutoCanceler> list_;
-};
-
-} // namespace cru::platform::gui
diff --git a/include/cru/platform/gui/UiApplication.h b/include/cru/platform/gui/UiApplication.h
index d15a3c72..84011275 100644
--- a/include/cru/platform/gui/UiApplication.h
+++ b/include/cru/platform/gui/UiApplication.h
@@ -3,6 +3,7 @@
#include "Menu.h"
#include "SaveOpenDialogOptions.h"
+#include <cru/base/Guard.h>
#include <cru/platform/graphics/Factory.h>
#include <chrono>
@@ -74,4 +75,12 @@ struct CRU_PLATFORM_GUI_API IUiApplication : public virtual IPlatformResource {
virtual std::optional<std::vector<std::string>> ShowOpenDialog(
OpenDialogOptions options);
};
+
+namespace details {
+inline void CancelTimer(long long id) noexcept {
+ IUiApplication::GetInstance()->CancelTimer(id);
+}
+} // namespace details
+
+using TimerAutoCanceler = AutoDestruct<long long, details::CancelTimer>;
} // namespace cru::platform::gui
diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h
index 4cb5f6da..293732c5 100644
--- a/include/cru/platform/gui/xcb/Window.h
+++ b/include/cru/platform/gui/xcb/Window.h
@@ -2,7 +2,7 @@
#pragma once
#include "Base.h"
-#include <cru/platform/gui/TimerHelper.h>
+#include <cru/platform/gui/UiApplication.h>
#include <cru/platform/gui/Window.h>
#include <cairo.h>
diff --git a/include/cru/ui/controls/TextHostControlService.h b/include/cru/ui/controls/TextHostControlService.h
index a9f4f22b..d4a1218f 100644
--- a/include/cru/ui/controls/TextHostControlService.h
+++ b/include/cru/ui/controls/TextHostControlService.h
@@ -1,7 +1,6 @@
#pragma once
#include "../render/TextRenderObject.h"
#include "cru/platform/gui/InputMethod.h"
-#include "cru/platform/gui/TimerHelper.h"
#include "cru/platform/gui/UiApplication.h"
#include "cru/ui/DeleteLater.h"
#include "cru/ui/controls/Control.h"
diff --git a/include/cru/ui/host/LayoutPaintCycler.h b/include/cru/ui/host/LayoutPaintCycler.h
index e95ed81d..e4ff7aa8 100644
--- a/include/cru/ui/host/LayoutPaintCycler.h
+++ b/include/cru/ui/host/LayoutPaintCycler.h
@@ -1,7 +1,6 @@
#pragma once
#include "../Base.h"
-#include "cru/platform/gui/TimerHelper.h"
#include "cru/platform/gui/UiApplication.h"
#include <chrono>
diff --git a/include/cru/ui/render/ScrollBar.h b/include/cru/ui/render/ScrollBar.h
index 50b21386..13c7d8b0 100644
--- a/include/cru/ui/render/ScrollBar.h
+++ b/include/cru/ui/render/ScrollBar.h
@@ -6,7 +6,6 @@
#include "cru/platform/graphics/Geometry.h"
#include "cru/platform/graphics/Painter.h"
#include "cru/platform/gui/Cursor.h"
-#include "cru/platform/gui/TimerHelper.h"
#include "cru/platform/gui/UiApplication.h"
#include "cru/ui/Base.h"
#include "cru/ui/controls/Control.h"