CYD-UI
A C++ library for building native graphic user interfaces
Loading...
Searching...
No Matches
impl.cppm
Go to the documentation of this file.
1
5
6export module cydui.dimensions:impl;
7
8import std;
9
10import fabric.logging;
11
12export import :types;
13export import :expression;
14export import :context;
15
16namespace cydui::dimensions {
17 export template <typename S>
19
20 export template <typename S>
21 const S& get_value(const dimension<S>& dimension);
22
23 template <typename T>
24 class dimension_impl {
25 public:
26 using value_type = T;
27 using wptr = std::weak_ptr<dimension_impl>;
28 using sptr = std::shared_ptr<dimension_impl>;
29
31 for (auto dependency: expr_.dependencies_) {
32 dependency->dependents_.erase(self);
33 }
34 }
35
38 friend typename expression<T>::node_t;
39
40 template <typename S>
41 friend const S& get_value(dimension<S>& dim);
42
43 template <typename S>
44 friend const S& get_value(const dimension<S>& dim);
45
46 template <typename S>
48 dimension<S>& dim_, const std::unordered_map<std::string, dimension<S>>& parameters
49 );
50 template <typename S>
52 typename dimension_impl<S>::sptr dim,
53 const std::unordered_map<std::string, dimension<S>>& parameters
54 );
55 template <typename S>
56 friend bool find_cycle(
57 cycle_t<S>& cycle,
58 typename dimension_impl<S>::sptr start,
59 typename dimension_impl<S>::sptr head,
60 const std::unordered_map<std::string, dimension<S>>& global_parameters
61 );
62
63 bool is_set() const {
64 return not expr_.empty();
65 }
66
67 void clear() {
68 expr_.clear();
69
70 for (auto dependency: expr_.dependencies_) {
71 dependency->dependents_.erase(self);
72 }
73
74 mark_unknown();
75 }
76
77 private:
79 : context_(new context<T>{}) {}
80
81 explicit dimension_impl(const std::shared_ptr<context<T>> ctx)
82 : context_(ctx) {}
83
84 void set_expression(const expression<T>& expression) {
85 if (expression == expr_) {
86 return;
87 }
88
89 for (const auto& param: expr_.parameters_) {
90 if (context_->contains(param.name)) {
91 auto& param_dim = context_->operator[](param.name);
92 param_dim.impl_->dependents_.erase(self);
93 }
94 }
95 for (auto dependency: expr_.dependencies_) {
96 dependency->dependents_.erase(self);
97 }
98
99 expr_ = expression;
100
101 for (const auto& param: expr_.parameters_) {
102 if (context_->contains(param.name)) {
103 auto& param_dim = context_->operator[](param.name);
104 param_dim.impl_->dependents_.insert(self);
105 }
106 }
107 for (auto dependency: expr_.dependencies_) {
108 dependency->dependents_.insert(self);
109 }
110 }
111
112 void set_context(const std::shared_ptr<context<T>>& ctx, const std::string& name = "") {
113 std::shared_ptr<context<T>> new_ctx = ctx;
114 for (const auto& param: expr_.parameters_) {
115 if (context_->contains(param.name)) {
116 auto& param_dim = context_->operator[](param.name);
117 param_dim.impl_->dependents_.erase(self);
118 }
119 }
120
121 context_.swap(new_ctx);
122 name_ = name;
123
124 for (const auto& param: expr_.parameters_) {
125 if (context_->contains(param.name)) {
126 auto& param_dim = context_->operator[](param.name);
127 param_dim.impl_->dependents_.insert(self);
128 }
129 }
130 }
131
132 void mark_unknown() {
133 unknown_ = true;
134 for (auto dependent: dependents_) {
135 if (dependent.expired()) {
136 dependents_.erase(dependent);
137 } else {
138 if (!dependent.lock()->unknown_) {
139 dependent.lock()->mark_unknown();
140 }
141 }
142 }
143 }
144
145 private:
146 expression<T>& expr() {
147 return expr_;
148 }
149 const expression<T>& expr() const {
150 return expr_;
151 }
152
153 bool is_unknown() const {
154 return unknown_;
155 }
156
157 private:
158 expression<T> expr_{};
159 T value_{};
160 bool unknown_ = true;
161 [[refl::ignore]]
162 std::unordered_set<wptr> dependents_{};
163 std::shared_ptr<context<T>> context_;
164 std::string name_{};
165
166 [[refl::ignore]]
167 wptr self;
168 };
169
170 template <typename T>
172 return std::make_shared<dimension_impl<T>>();
173 }
174} // namespace cydui::dimensions
175
176template <typename T>
177struct std::hash<std::weak_ptr<cydui::dimensions::dimension_impl<T>>> {
178 std::size_t operator()(const std::weak_ptr<cydui::dimensions::dimension_impl<T>>& it) const {
179 return reinterpret_cast<std::size_t>(it.lock().get());
180 }
181};
182
183template <typename T>
184struct std::equal_to<std::weak_ptr<cydui::dimensions::dimension_impl<T>>> {
186 const std::weak_ptr<cydui::dimensions::dimension_impl<T>>& it1,
187 const std::weak_ptr<cydui::dimensions::dimension_impl<T>>& it2
188 ) const {
189 return it1.lock() == it2.lock();
190 }
191};
friend compute_result_t< S > compute_dimension(dimension< S > &dim_, const std::unordered_map< std::string, dimension< S > > &parameters)
friend bool find_cycle(cycle_t< S > &cycle, typename dimension_impl< S >::sptr start, typename dimension_impl< S >::sptr head, const std::unordered_map< std::string, dimension< S > > &global_parameters)
std::weak_ptr< dimension_impl > wptr
Definition impl.cppm:27
friend bool evaluate_expression(typename dimension_impl< S >::sptr dim, const std::unordered_map< std::string, dimension< S > > &parameters)
std::shared_ptr< dimension_impl > sptr
Definition impl.cppm:28
friend const S & get_value(dimension< S > &dim)
Definition api.cppm:24
const S & get_value(dimension< S > &dimension)
Definition api.cppm:24
dimension_impl< T >::sptr make_dimension_impl()
Definition impl.cppm:171
bool operator()(const std::weak_ptr< cydui::dimensions::dimension_impl< T > > &it1, const std::weak_ptr< cydui::dimensions::dimension_impl< T > > &it2) const
Definition impl.cppm:185
std::size_t operator()(const std::weak_ptr< cydui::dimensions::dimension_impl< T > > &it) const
Definition impl.cppm:178