aboutsummaryrefslogtreecommitdiff
path: root/src/ui/style
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/style')
-rw-r--r--src/ui/style/StyleRuleSet.cpp34
1 files changed, 26 insertions, 8 deletions
diff --git a/src/ui/style/StyleRuleSet.cpp b/src/ui/style/StyleRuleSet.cpp
index 537d1956..88109350 100644
--- a/src/ui/style/StyleRuleSet.cpp
+++ b/src/ui/style/StyleRuleSet.cpp
@@ -6,12 +6,30 @@
#include <unordered_set>
namespace cru::ui::style {
-StyleRuleSet::StyleRuleSet(StyleRuleSet* parent) { SetParent(parent); }
+namespace {
+bool CheckCycle(StyleRuleSet* t, StyleRuleSet* p) {
+ while (p != nullptr) {
+ if (p == t) {
+ return true;
+ }
+ p = p->GetParent().get();
+ }
+
+ return false;
+}
+} // namespace
-void StyleRuleSet::SetParent(StyleRuleSet* parent) {
+StyleRuleSet::StyleRuleSet(std::shared_ptr<StyleRuleSet> parent) {
+ SetParent(std::move(parent));
+}
+
+void StyleRuleSet::SetParent(std::shared_ptr<StyleRuleSet> parent) {
if (parent == parent_) return;
+ if (CheckCycle(this, parent.get())) {
+ throw Exception(u"Cycle detected in StyleRuleSet parent.");
+ }
parent_change_event_guard_.Reset();
- parent_ = parent;
+ parent_ = std::move(parent);
if (parent != nullptr) {
parent_change_event_guard_.Reset(parent->ChangeEvent()->AddSpyOnlyHandler(
[this] { this->RaiseChangeEvent(); }));
@@ -44,12 +62,12 @@ void StyleRuleSet::Set(const StyleRuleSet& other, bool set_parent) {
}
StyleRuleSetBind::StyleRuleSetBind(controls::Control* control,
- StyleRuleSet* ruleset)
- : control_(control), ruleset_(ruleset) {
+ std::shared_ptr<StyleRuleSet> ruleset)
+ : control_(control), ruleset_(std::move(ruleset)) {
Expects(control);
- Expects(ruleset);
+ Expects(ruleset_);
- ruleset->ChangeEvent()->AddSpyOnlyHandler([this] {
+ ruleset_->ChangeEvent()->AddSpyOnlyHandler([this] {
UpdateRuleSetChainCache();
UpdateChangeListener();
UpdateStyle();
@@ -60,7 +78,7 @@ void StyleRuleSetBind::UpdateRuleSetChainCache() {
ruleset_chain_cache_.clear();
auto parent = ruleset_;
while (parent != nullptr) {
- ruleset_chain_cache_.push_back(parent);
+ ruleset_chain_cache_.push_back(parent.get());
parent = parent->GetParent();
}
}