aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-11-18 17:31:23 +0800
committerYuqian Yang <crupest@crupest.life>2025-11-18 17:31:23 +0800
commit04d243699cbde40fe69472f4c4df38c36f7942ef (patch)
treeaf2a2031ab7f2d9ce03cf677eba066e11f32a0c9
parent358dc1498623d53f1d8bedf5172743deb6c03811 (diff)
downloadcru-04d243699cbde40fe69472f4c4df38c36f7942ef.tar.gz
cru-04d243699cbde40fe69472f4c4df38c36f7942ef.tar.bz2
cru-04d243699cbde40fe69472f4c4df38c36f7942ef.zip
Move delete later to platform::gui.
-rw-r--r--include/cru/platform/gui/DeleteLater.h (renamed from include/cru/ui/DeleteLater.h)21
-rw-r--r--include/cru/platform/gui/UiApplication.h14
-rw-r--r--include/cru/platform/gui/win/UiApplication.h3
-rw-r--r--include/cru/ui/components/Component.h7
-rw-r--r--include/cru/ui/controls/Control.h4
-rw-r--r--src/ThemeBuilder/components/StyleRuleSetEditor.cpp19
-rw-r--r--src/ThemeBuilder/components/StyleRuleSetEditor.h6
-rw-r--r--src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp6
-rw-r--r--src/ThemeBuilder/components/conditions/CompoundConditionEditor.h2
-rw-r--r--src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp6
-rw-r--r--src/ThemeBuilder/components/stylers/CompoundStylerEditor.h4
-rw-r--r--src/platform/gui/UiApplication.cpp18
-rw-r--r--src/platform/gui/win/UiApplication.cpp6
-rw-r--r--src/ui/CMakeLists.txt1
-rw-r--r--src/ui/DeleteLater.cpp23
-rw-r--r--test/platform/CMakeLists.txt1
-rw-r--r--test/platform/DeleteLaterTest.cpp (renamed from test/ui/DeleteLaterTest.cpp)4
-rw-r--r--test/ui/CMakeLists.txt6
18 files changed, 82 insertions, 69 deletions
diff --git a/include/cru/ui/DeleteLater.h b/include/cru/platform/gui/DeleteLater.h
index 95301bc0..c0578974 100644
--- a/include/cru/ui/DeleteLater.h
+++ b/include/cru/platform/gui/DeleteLater.h
@@ -1,20 +1,21 @@
#pragma once
-#include "Base.h"
+#include "UiApplication.h"
#include <cru/base/Guard.h>
#include <memory>
#include <utility>
-namespace cru::ui {
-class CRU_UI_API DeleteLaterImpl {
- CRU_DEFINE_CLASS_LOG_TAG("cru::ui::DeleteLaterImpl")
+namespace cru::platform::gui {
+template <typename TSelf>
+class DeleteLaterImpl {
+ CRU_DEFINE_CLASS_LOG_TAG("cru::platform::gui::DeleteLaterImpl")
+
public:
- DeleteLaterImpl();
- virtual ~DeleteLaterImpl();
- void DeleteLater();
+ virtual ~DeleteLaterImpl() {}
- private:
- bool delete_later_scheduled_;
+ void DeleteLater() {
+ IUiApplication::GetInstance()->DeleteLater(static_cast<TSelf*>(this));
+ }
};
namespace details {
@@ -37,4 +38,4 @@ DeleteLaterPtr<T> MakeDeleteLater(Args&&... args) {
return DeleteLaterPtr<T>(new T(std::forward<Args>(args)...));
}
-} // namespace cru::ui
+} // namespace cru::platform::gui
diff --git a/include/cru/platform/gui/UiApplication.h b/include/cru/platform/gui/UiApplication.h
index 84011275..c4454b2e 100644
--- a/include/cru/platform/gui/UiApplication.h
+++ b/include/cru/platform/gui/UiApplication.h
@@ -16,6 +16,18 @@ struct INativeWindow;
struct IInputMethodContext;
struct IClipboard;
+class CRU_PLATFORM_GUI_API DeleteLaterPool : public Object {
+ public:
+ void Add(Object* object);
+
+ void Clean();
+
+ private:
+ // May contain duplicate object pointer. When performing deleting, use a set
+ // to record deleted objects to avoid double delete.
+ std::vector<Object*> pool_;
+};
+
// The entry point of a ui application.
struct CRU_PLATFORM_GUI_API IUiApplication : public virtual IPlatformResource {
public:
@@ -51,6 +63,8 @@ struct CRU_PLATFORM_GUI_API IUiApplication : public virtual IPlatformResource {
// result in no-op.
virtual void CancelTimer(long long id) = 0;
+ virtual void DeleteLater(Object* object) = 0;
+
virtual std::vector<INativeWindow*> GetAllWindow() = 0;
virtual INativeWindow* CreateWindow() = 0;
diff --git a/include/cru/platform/gui/win/UiApplication.h b/include/cru/platform/gui/win/UiApplication.h
index b2d1f39b..c5057c4b 100644
--- a/include/cru/platform/gui/win/UiApplication.h
+++ b/include/cru/platform/gui/win/UiApplication.h
@@ -48,6 +48,8 @@ class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource,
std::function<void()> action) override;
void CancelTimer(long long id) override;
+ void DeleteLater(Object* object) override;
+
std::vector<INativeWindow*> GetAllWindow() override;
INativeWindow* CreateWindow() override;
@@ -79,6 +81,7 @@ class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource,
graph_factory_;
TimerRegistry<std::function<void()>> timers_;
+ DeleteLaterPool delete_later_pool_;
std::unique_ptr<WindowClass> general_window_class_;
std::vector<WinNativeWindow*> windows_;
diff --git a/include/cru/ui/components/Component.h b/include/cru/ui/components/Component.h
index d8966a89..1e002e5f 100644
--- a/include/cru/ui/components/Component.h
+++ b/include/cru/ui/components/Component.h
@@ -1,6 +1,7 @@
#pragma once
#include "../Base.h"
-#include "../DeleteLater.h"
+
+#include <cru/platform/gui/DeleteLater.h>
namespace cru::ui::components {
/**
@@ -8,7 +9,9 @@ namespace cru::ui::components {
* \remarks Component should respect children's Component::IsDeleteByParent
* value and decide whether to delete it.
*/
-class CRU_UI_API Component : public Object, public DeleteLaterImpl {
+class CRU_UI_API Component
+ : public Object,
+ public cru::platform::gui::DeleteLaterImpl<Component> {
public:
virtual controls::Control* GetRootControl() = 0;
diff --git a/include/cru/ui/controls/Control.h b/include/cru/ui/controls/Control.h
index 9e5e86b8..6a85d25a 100644
--- a/include/cru/ui/controls/Control.h
+++ b/include/cru/ui/controls/Control.h
@@ -1,6 +1,5 @@
#pragma once
#include "../Base.h"
-#include "../DeleteLater.h"
#include "../events/KeyEventArgs.h"
#include "../events/MouseWheelEventArgs.h"
#include "../events/UiEvents.h"
@@ -9,6 +8,7 @@
#include "../style/StyleRuleSet.h"
#include <cru/base/SelfResolvable.h>
+#include <cru/platform/gui/DeleteLater.h>
namespace cru::ui::controls {
@@ -22,7 +22,7 @@ namespace cru::ui::controls {
* The last two methods are totally for convenient control tree management.
*/
class CRU_UI_API Control : public Object,
- public DeleteLaterImpl,
+ public cru::platform::gui::DeleteLaterImpl<Control>,
public SelfResolvable<Control> {
friend class ControlHost;
diff --git a/src/ThemeBuilder/components/StyleRuleSetEditor.cpp b/src/ThemeBuilder/components/StyleRuleSetEditor.cpp
index fd159a44..9159e966 100644
--- a/src/ThemeBuilder/components/StyleRuleSetEditor.cpp
+++ b/src/ThemeBuilder/components/StyleRuleSetEditor.cpp
@@ -1,5 +1,5 @@
#include "StyleRuleSetEditor.h"
-#include "cru/ui/DeleteLater.h"
+#include "cru/platform/gui/DeleteLater.h"
#include "cru/ui/ThemeManager.h"
#include "cru/ui/controls/FlexLayout.h"
#include "cru/ui/model/IListChangeNotify.h"
@@ -49,11 +49,11 @@ void StyleRuleSetEditor::BindStyleRuleSet(
}
Index StyleRuleSetEditor::IndexOfRuleEditor(StyleRuleEditor* editor) {
- auto iter =
- std::find_if(style_rule_editors_.cbegin(), style_rule_editors_.cend(),
- [editor](const ui::DeleteLaterPtr<StyleRuleEditor>& p) {
- return p.get() == editor;
- });
+ auto iter = std::find_if(
+ style_rule_editors_.cbegin(), style_rule_editors_.cend(),
+ [editor](const platform::gui::DeleteLaterPtr<StyleRuleEditor>& p) {
+ return p.get() == editor;
+ });
return iter - style_rule_editors_.cbegin();
}
@@ -66,7 +66,8 @@ void StyleRuleSetEditor::UpdateView(
for (auto i = change->position; i < change->position + change->count;
++i) {
const auto& rule = style_rule_set->GetStyleRule(i);
- auto style_rule_editor = ui::MakeDeleteLater<StyleRuleEditor>();
+ auto style_rule_editor =
+ platform::gui::MakeDeleteLater<StyleRuleEditor>();
style_rule_editor->SetValue(rule, false);
style_rule_editor->RemoveEvent()->AddSpyOnlyHandler(
[this, editor = style_rule_editor.get()] {
@@ -80,8 +81,8 @@ void StyleRuleSetEditor::UpdateView(
});
style_rule_editors_.insert(style_rule_editors_.cbegin() + i,
std::move(style_rule_editor));
- rules_layout_.InsertChildAt(style_rule_editors_.back()->GetRootControl(),
- i);
+ rules_layout_.InsertChildAt(
+ style_rule_editors_.back()->GetRootControl(), i);
}
break;
}
diff --git a/src/ThemeBuilder/components/StyleRuleSetEditor.h b/src/ThemeBuilder/components/StyleRuleSetEditor.h
index 03148889..36ac8626 100644
--- a/src/ThemeBuilder/components/StyleRuleSetEditor.h
+++ b/src/ThemeBuilder/components/StyleRuleSetEditor.h
@@ -1,8 +1,8 @@
#pragma once
#include "StyleRuleEditor.h"
-#include "cru/ui/DeleteLater.h"
+#include "cru/platform/gui/DeleteLater.h"
#include "cru/ui/components/Component.h"
-#include "cru/ui/controls/Button.h"
+#include "cru/ui/controls/IconButton.h"
#include "cru/ui/controls/Control.h"
#include "cru/ui/controls/FlexLayout.h"
#include "cru/ui/controls/ScrollView.h"
@@ -36,7 +36,7 @@ class StyleRuleSetEditor : public ui::components::Component {
ui::controls::ScrollView scroll_view_;
ui::controls::FlexLayout container_;
ui::controls::FlexLayout rules_layout_;
- std::vector<ui::DeleteLaterPtr<StyleRuleEditor>> style_rule_editors_;
+ std::vector<platform::gui::DeleteLaterPtr<StyleRuleEditor>> style_rule_editors_;
ui::controls::IconButton add_button_;
bool suppress_next_set_ = false;
diff --git a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp
index d7324350..8501d7cd 100644
--- a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp
+++ b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp
@@ -7,7 +7,7 @@
#include "cru/base/ClonePtr.h"
#include "cru/platform/Color.h"
#include "cru/ui/Base.h"
-#include "cru/ui/DeleteLater.h"
+#include "cru/platform/gui/DeleteLater.h"
#include "cru/ui/ThemeManager.h"
#include "cru/ui/controls/FlexLayout.h"
#include "cru/ui/style/Condition.h"
@@ -69,7 +69,7 @@ CompoundConditionEditor::CompoundConditionEditor() {
this->children_container_.RemoveChildAt(index);
RaiseChangeEvent();
});
- children_.push_back(ui::ToDeleteLaterPtr(std::move(editor)));
+ children_.push_back(platform::gui::ToDeleteLaterPtr(std::move(editor)));
children_container_.AddChild(children_.back()->GetRootControl());
RaiseChangeEvent();
}
@@ -100,7 +100,7 @@ void CompoundConditionEditor::SetChildren(
this->children_container_.RemoveChildAt(index);
RaiseChangeEvent();
});
- children_.push_back(ui::ToDeleteLaterPtr(std::move(editor)));
+ children_.push_back(platform::gui::ToDeleteLaterPtr(std::move(editor)));
children_container_.AddChild(children_.back()->GetRootControl());
}
if (trigger_change) {
diff --git a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h
index af632758..c0f0891a 100644
--- a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h
+++ b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h
@@ -23,7 +23,7 @@ class CompoundConditionEditor : public ConditionEditor {
private:
ui::components::PopupMenuIconButton add_child_button_;
ui::controls::FlexLayout children_container_;
- std::vector<ui::DeleteLaterPtr<ConditionEditor>> children_;
+ std::vector<platform::gui::DeleteLaterPtr<ConditionEditor>> children_;
};
class AndConditionEditor : public CompoundConditionEditor {
diff --git a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp
index 90d19a68..698cc699 100644
--- a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp
+++ b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp
@@ -7,7 +7,7 @@
#include "PaddingStylerEditor.h"
#include "PreferredSizeStylerEditor.h"
#include "cru/base/ClonePtr.h"
-#include "cru/ui/DeleteLater.h"
+#include "cru/platform/gui/DeleteLater.h"
#include "cru/ui/ThemeManager.h"
#include "cru/ui/style/Styler.h"
@@ -71,7 +71,7 @@ CompoundStylerEditor::CompoundStylerEditor() {
this->children_container_.RemoveChildAt(index);
RaiseChangeEvent();
});
- children_.push_back(ui::ToDeleteLaterPtr(std::move(editor)));
+ children_.push_back(platform::gui::ToDeleteLaterPtr(std::move(editor)));
children_container_.AddChild(editor->GetRootControl());
RaiseChangeEvent();
}
@@ -100,7 +100,7 @@ void CompoundStylerEditor::SetValue(ui::style::CompoundStyler* value,
this->children_container_.RemoveChildAt(index);
RaiseChangeEvent();
});
- children_.push_back(ui::ToDeleteLaterPtr(std::move(editor)));
+ children_.push_back(platform::gui::ToDeleteLaterPtr(std::move(editor)));
children_container_.AddChild(children_.back()->GetRootControl());
}
}
diff --git a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h
index f9265fbf..454b3622 100644
--- a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h
+++ b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h
@@ -1,7 +1,7 @@
#pragma once
#include "StylerEditor.h"
#include "cru/base/ClonePtr.h"
-#include "cru/ui/DeleteLater.h"
+#include "cru/platform/gui/DeleteLater.h"
#include "cru/ui/components/PopupButton.h"
#include "cru/ui/controls/FlexLayout.h"
#include "cru/ui/style/Styler.h"
@@ -24,7 +24,7 @@ class CompoundStylerEditor : public StylerEditor {
private:
ui::controls::FlexLayout children_container_;
- std::vector<ui::DeleteLaterPtr<StylerEditor>> children_;
+ std::vector<platform::gui::DeleteLaterPtr<StylerEditor>> children_;
ui::components::PopupMenuIconButton add_child_button_;
};
} // namespace cru::theme_builder::components::stylers
diff --git a/src/platform/gui/UiApplication.cpp b/src/platform/gui/UiApplication.cpp
index f035224f..56570125 100644
--- a/src/platform/gui/UiApplication.cpp
+++ b/src/platform/gui/UiApplication.cpp
@@ -1,9 +1,23 @@
#include "cru/platform/gui/UiApplication.h"
-
#include "cru/base/Base.h"
+#include <unordered_set>
+
namespace cru::platform::gui {
+void DeleteLaterPool::Add(Object* object) { pool_.push_back(object); }
+
+void DeleteLaterPool::Clean() {
+ std::unordered_set<Object*> deleted;
+ for (auto object : pool_) {
+ if (!deleted.contains(object)) {
+ deleted.insert(object);
+ delete object;
+ }
+ }
+ pool_.clear();
+}
+
namespace {
IUiApplication* instance = nullptr;
}
@@ -12,7 +26,7 @@ IUiApplication* IUiApplication::GetInstance() { return instance; }
IUiApplication::IUiApplication() {
if (instance) {
- throw std::runtime_error("An ui application has already been created.");
+ throw Exception("A ui application has already been created.");
}
instance = this;
diff --git a/src/platform/gui/win/UiApplication.cpp b/src/platform/gui/win/UiApplication.cpp
index eb85ef90..e1c21d59 100644
--- a/src/platform/gui/win/UiApplication.cpp
+++ b/src/platform/gui/win/UiApplication.cpp
@@ -71,6 +71,8 @@ int WinUiApplication::Run() {
break;
}
}
+
+ delete_later_pool_.Clean();
}
for (const auto& handler : quit_handlers_) handler();
@@ -103,6 +105,10 @@ long long WinUiApplication::SetInterval(std::chrono::milliseconds milliseconds,
void WinUiApplication::CancelTimer(long long id) { timers_.Remove(id); }
+void WinUiApplication::DeleteLater(Object* object) {
+ delete_later_pool_.Add(object);
+}
+
std::vector<INativeWindow*> WinUiApplication::GetAllWindow() {
std::vector<INativeWindow*> result;
for (const auto w : windows_) {
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index e931b678..d2188e0b 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -1,5 +1,4 @@
add_library(CruUi
- DeleteLater.cpp
Helper.cpp
ThemeManager.cpp
ThemeResourceDictionary.cpp
diff --git a/src/ui/DeleteLater.cpp b/src/ui/DeleteLater.cpp
deleted file mode 100644
index 90b07b71..00000000
--- a/src/ui/DeleteLater.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "cru/ui/DeleteLater.h"
-
-#include "Helper.h"
-#include "cru/base/log/Logger.h"
-#include "cru/platform/gui/UiApplication.h"
-
-namespace cru::ui {
-
-DeleteLaterImpl::DeleteLaterImpl() : delete_later_scheduled_(false) {}
-
-DeleteLaterImpl::~DeleteLaterImpl() {
- CRU_LOG_TAG_DEBUG("Delete later object being deleted {}.",
- static_cast<void*>(this));
-}
-
-void DeleteLaterImpl::DeleteLater() {
- if (!delete_later_scheduled_) {
- CRU_LOG_TAG_DEBUG("Schedule delete later {}.", static_cast<void*>(this));
- GetUiApplication()->SetImmediate([this] { delete this; });
- delete_later_scheduled_ = true;
- }
-}
-} // namespace cru::ui
diff --git a/test/platform/CMakeLists.txt b/test/platform/CMakeLists.txt
index e4237cd3..ea6493c4 100644
--- a/test/platform/CMakeLists.txt
+++ b/test/platform/CMakeLists.txt
@@ -1,5 +1,6 @@
add_executable(CruPlatformBaseTest
ColorTest.cpp
+ DeleteLaterTest.cpp
MatrixTest.cpp
)
target_link_libraries(CruPlatformBaseTest PRIVATE CruPlatformBase CruTestBase)
diff --git a/test/ui/DeleteLaterTest.cpp b/test/platform/DeleteLaterTest.cpp
index c9d600de..932ac357 100644
--- a/test/ui/DeleteLaterTest.cpp
+++ b/test/platform/DeleteLaterTest.cpp
@@ -1,4 +1,4 @@
-#include "cru/ui/DeleteLater.h"
+#include "cru/platform/gui/DeleteLater.h"
#include <catch2/catch_test_macros.hpp>
@@ -9,7 +9,7 @@ struct MockDeleteLater {
};
TEST_CASE("DeleteLaterPtr should work.", "[delete-later]") {
- auto ptr = cru::ui::MakeDeleteLater<MockDeleteLater>();
+ auto ptr = cru::platform::gui::MakeDeleteLater<MockDeleteLater>();
auto p = ptr.get();
ptr.reset();
REQUIRE(p->triggered);
diff --git a/test/ui/CMakeLists.txt b/test/ui/CMakeLists.txt
index 66a7cd27..e69de29b 100644
--- a/test/ui/CMakeLists.txt
+++ b/test/ui/CMakeLists.txt
@@ -1,6 +0,0 @@
-add_executable(CruUiTest
- DeleteLaterTest.cpp
-)
-target_link_libraries(CruUiTest PRIVATE CruUi CruTestBase)
-
-cru_catch_discover_tests(CruUiTest)