diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/cru/base/Guard.h | 112 | ||||
| -rw-r--r-- | include/cru/base/platform/win/Base.h | 73 | ||||
| -rw-r--r-- | include/cru/platform/gui/TimerHelper.h | 69 | ||||
| -rw-r--r-- | include/cru/platform/gui/UiApplication.h | 9 | ||||
| -rw-r--r-- | include/cru/platform/gui/xcb/Window.h | 2 | ||||
| -rw-r--r-- | include/cru/ui/controls/TextHostControlService.h | 1 | ||||
| -rw-r--r-- | include/cru/ui/host/LayoutPaintCycler.h | 1 | ||||
| -rw-r--r-- | include/cru/ui/render/ScrollBar.h | 1 |
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" |
