@@ -128,26 +128,19 @@ struct notifying_guard_t
128
128
};
129
129
130
130
/* !
131
- * Base class for the various node types. Provides basic
132
- * functionality for setting values and propagating them to children.
131
+ * Interface for nodes capable of notifying observers.
133
132
*/
134
133
template <typename T>
135
- class reader_node : public reader_node_base
134
+ class observable_reader_node
136
135
{
137
136
public:
138
137
using value_type = T;
139
138
using signal_type = signal<const value_type&>;
140
139
141
- reader_node (T value)
142
- : current_(std::move(value))
143
- , last_(current_)
144
- {}
145
-
146
- virtual void recompute () = 0;
147
- virtual void refresh () = 0;
140
+ virtual void refresh () = 0;
148
141
149
- const value_type& current () const { return current_ ; }
150
- const value_type& last () const { return last_ ; }
142
+ const value_type& current () const { return *current_view_ ; }
143
+ const value_type& last () const { return *last_view_ ; }
151
144
152
145
void link (std::weak_ptr<reader_node_base> child)
153
146
{
@@ -159,6 +152,56 @@ class reader_node : public reader_node_base
159
152
" Child node must not be linked twice" );
160
153
children_.push_back (child);
161
154
}
155
+ auto observers () -> signal_type& { return observers_; }
156
+
157
+ protected:
158
+ observable_reader_node (const T* current, const T* last)
159
+ : current_view_(current)
160
+ , last_view_(last)
161
+ {
162
+ }
163
+
164
+ void collect ()
165
+ {
166
+ using namespace std ;
167
+ children_.erase (remove_if (begin (children_),
168
+ end (children_),
169
+ mem_fn (&weak_ptr<reader_node_base>::expired)),
170
+ end (children_));
171
+ }
172
+
173
+ const std::vector<std::weak_ptr<reader_node_base>>& children () const
174
+ {
175
+ return children_;
176
+ }
177
+
178
+ private:
179
+ const T* current_view_;
180
+ const T* last_view_;
181
+ signal_type observers_;
182
+ std::vector<std::weak_ptr<reader_node_base>> children_;
183
+ };
184
+ /* !
185
+ * Base class for the various node types. Provides basic
186
+ * functionality for setting values and propagating them to children.
187
+ */
188
+ template <typename T>
189
+ class reader_node
190
+ : public reader_node_base
191
+ , public observable_reader_node<T>
192
+ {
193
+ public:
194
+ using value_type = typename observable_reader_node<T>::value_type;
195
+ using signal_type = typename observable_reader_node<T>::signal_type;
196
+
197
+ reader_node (T value)
198
+ : observable_reader_node<T>(¤t_, &last_)
199
+ , current_(std::move(value))
200
+ , last_(current_)
201
+ {
202
+ }
203
+
204
+ virtual void recompute () = 0;
162
205
163
206
template <typename U>
164
207
void push_down (U&& value)
@@ -171,12 +214,12 @@ class reader_node : public reader_node_base
171
214
172
215
void send_down () final
173
216
{
174
- recompute ();
217
+ this -> recompute ();
175
218
if (needs_send_down_) {
176
219
last_ = current_;
177
220
needs_send_down_ = false ;
178
221
needs_notify_ = true ;
179
- for (auto & wchild : children_ ) {
222
+ for (auto & wchild : this -> children () ) {
180
223
if (auto child = wchild.lock ()) {
181
224
child->send_down ();
182
225
}
@@ -193,37 +236,24 @@ class reader_node : public reader_node_base
193
236
notifying_guard_t notifying_guard (notifying_);
194
237
bool garbage = false ;
195
238
196
- observers_ (last_);
197
- for (size_t i = 0 , size = children_. size (); i < size; ++i ) {
198
- if (auto child = children_[i] .lock ()) {
239
+ this -> observers () (last_);
240
+ for (auto & wchild : this -> children () ) {
241
+ if (auto child = wchild .lock ()) {
199
242
child->notify ();
200
243
} else {
201
244
garbage = true ;
202
245
}
203
246
}
204
247
205
248
if (garbage && !notifying_guard.value_ ) {
206
- collect ();
249
+ this -> collect ();
207
250
}
208
251
}
209
252
}
210
253
211
- auto observers () -> signal_type& { return observers_; }
212
-
213
254
private:
214
- void collect ()
215
- {
216
- using namespace std ;
217
- children_.erase (remove_if (begin (children_),
218
- end (children_),
219
- mem_fn (&weak_ptr<reader_node_base>::expired)),
220
- end (children_));
221
- }
222
-
223
255
value_type current_;
224
256
value_type last_;
225
- std::vector<std::weak_ptr<reader_node_base>> children_;
226
- signal_type observers_;
227
257
228
258
bool needs_send_down_ = false ;
229
259
bool needs_notify_ = false ;
0 commit comments