Scroom 0.14-48-ga0fee447
Loading...
Searching...
No Matches
observable.hh
Go to the documentation of this file.
1/*
2 * Scroom - Generic viewer for 2D data
3 * Copyright (C) 2009-2026 Kees-Jan Dijkzeul
4 *
5 * SPDX-License-Identifier: LGPL-2.1
6 */
7
8#pragma once
9
10#include <list>
11#include <map>
12#include <memory>
13#include <utility>
14
15#include <boost/thread.hpp>
16
17#include <scroom/bookkeeping.hh>
18#include <scroom/utilities.hh>
19
20namespace Scroom::Utils
21{
22 template <typename T>
23 class Observable;
24
25 namespace Detail
26 {
32 template <typename T>
34 {
35 public:
36 std::weak_ptr<Observable<T>> observable;
37 std::shared_ptr<T> o;
38 std::weak_ptr<T> observer;
40 using Ptr = std::shared_ptr<Registration<T>>;
41
42 public:
43 Registration() = default;
44 Registration(std::weak_ptr<Observable<T>> observable, std::shared_ptr<T> observer);
45 Registration(std::weak_ptr<Observable<T>> observable, std::weak_ptr<T> observer);
46 void set(std::shared_ptr<T> observer);
47 void set(std::weak_ptr<T> observer);
48
49 static Ptr create(std::weak_ptr<Observable<T>> observable, std::shared_ptr<T> observer);
50 static Ptr create(std::weak_ptr<Observable<T>> observable, std::weak_ptr<T> observer);
51 };
52 } // namespace Detail
53
69 template <typename T>
70 class Observable : public virtual Base
71 {
72 public:
73 using Observer = std::shared_ptr<T>;
74 using Ptr = std::shared_ptr<Observable<T>>;
75
76 private:
77 using ObserverWeak = std::weak_ptr<T>;
79
80 private:
83
84 protected:
92 std::list<Observer> getObservers();
93
94 public:
96 ~Observable() override;
97 Observable(const Observable&) = delete;
101
102 protected:
108
109 public:
112
113 private:
115
116 friend class Detail::Registration<T>;
117 };
118
120 // Detail::Registration implementation
121
122 template <typename T>
123 Detail::Registration<T>::Registration(std::weak_ptr<Observable<T>> observable_, std::shared_ptr<T> observer_)
124 : observable(std::move(observable_))
125 , o(std::move(observer_))
126 , observer(o)
127 {
128 }
129
130 template <typename T>
131 Detail::Registration<T>::Registration(std::weak_ptr<Observable<T>> observable_, std::weak_ptr<T> observer_)
132 : observable(std::move(observable_))
133 , o()
134 , observer(std::move(observer_))
135 {
136 // We don't want to store a "hard" reference, so field o is intentionally empty.
137 }
138
139 template <typename T>
140 void Detail::Registration<T>::set(std::shared_ptr<T> observer_)
141 {
142 o = std::move(observer_);
143 observer = o;
144 }
145
146 template <typename T>
147 void Detail::Registration<T>::set(std::weak_ptr<T> observer_)
148 {
149 // We don't want to store a "hard" reference, so field o is intentionally empty.
150 o.reset();
151 observer = std::move(observer_);
152 }
153
154 template <typename T>
156 Detail::Registration<T>::create(std::weak_ptr<Observable<T>> observable, std::shared_ptr<T> observer)
157 {
158 return typename Detail::Registration<T>::Ptr(new Detail::Registration<T>(std::move(observable), std::move(observer)));
159 }
160
161 template <typename T>
163 Detail::Registration<T>::create(std::weak_ptr<Observable<T>> observable, std::weak_ptr<T> observer)
164 {
165 return typename Detail::Registration<T>::Ptr(new Detail::Registration<T>(std::move(observable), std::move(observer)));
166 }
167
169 // Observable implementation
170 template <typename T>
175
176 template <typename T>
178 {
179 // Destroy strong references to any observers
180 //
181 // The one holding the token of the registration is in control
182 // of the lifetime of the registration objects. Hence, as long
183 // as the Token is valid, a reference to the Registration will
184 // exist, which may, in turn, contain a (strong) reference to an
185 // Observer. This is not desirable. As soon as the observable is
186 // deleted (which is now), it should no longer hold any
187 // references to any Observers. Hence, we should manually reset
188 // references to observers here.
189 for(const typename Registration::Ptr& registration: registrationMap->values())
190 {
191 registration->o.reset();
192 }
193 }
194
195 template <typename T>
196 std::list<typename Observable<T>::Observer> Observable<T>::getObservers()
197 {
198 std::list<typename Observable<T>::Observer> result;
199 for(const typename Registration::Ptr& registration: registrationMap->values())
200 {
201 Observer const o = registration->observer.lock();
202 if(o)
203 {
204 result.push_back(o);
205 }
206 }
207
208 return result;
209 }
210
211 template <typename T>
213 {
214 Scroom::Bookkeeping::Token t = registrationMap->reReserve(observer);
215 typename Detail::Registration<T>::Ptr r = registrationMap->get(observer);
216 if(r)
217 {
218 r->set(observer);
219 }
220 else
221 {
223 registrationMap->set(observer, r);
224 }
225
226 observerAdded(observer, t);
227
228 return t;
229 }
230
231 template <typename T>
233 {
234 Scroom::Bookkeeping::Token t = registrationMap->reReserve(observer);
235 typename Detail::Registration<T>::Ptr r = registrationMap->get(observer);
236 if(r)
237 {
238 r->set(observer);
239 }
240 else
241 {
243 registrationMap->set(observer, r);
244 }
245
246 observerAdded(typename Observable<T>::Observer(observer), t);
247
248 return t;
249 }
250
251 template <typename T>
253 {
254 registrationMap->remove(observer);
255 }
256
257 template <typename T>
259 {
260 // Do nothing
261 }
262} // namespace Scroom::Utils
std::shared_ptr< Map< K, V > > Ptr
Definition bookkeeping.hh:97
static Ptr create()
Definition bookkeepingimpl.hh:424
Definition bookkeeping.hh:50
Definition utilities.hh:34
Definition observable.hh:34
std::shared_ptr< Registration< T > > Ptr
Definition observable.hh:40
void set(std::shared_ptr< T > observer)
Definition observable.hh:140
std::weak_ptr< Observable< T > > observable
Definition observable.hh:36
std::weak_ptr< T > observer
Definition observable.hh:38
static Ptr create(std::weak_ptr< Observable< T > > observable, std::shared_ptr< T > observer)
Definition observable.hh:156
std::shared_ptr< T > o
Definition observable.hh:37
Definition observable.hh:71
Observable()
Definition observable.hh:171
Observable operator=(Observable &&)=delete
std::weak_ptr< T > ObserverWeak
Definition observable.hh:77
Observable operator=(const Observable &)=delete
~Observable() override
Definition observable.hh:177
Scroom::Bookkeeping::Map< ObserverWeak, typenameRegistration::Ptr >::Ptr registrationMap
Definition observable.hh:82
void unregisterObserver(ObserverWeak const &observer)
Definition observable.hh:252
Observable(const Observable &)=delete
Observable(Observable &&)=delete
Scroom::Bookkeeping::Token registerStrongObserver(Observer const &observer)
Definition observable.hh:212
virtual void observerAdded(Observer const &observer, Scroom::Bookkeeping::Token const &token)
Definition observable.hh:258
std::list< Observer > getObservers()
Definition observable.hh:196
std::shared_ptr< Observable< T > > Ptr
Definition observable.hh:74
std::shared_ptr< T > Observer
Definition observable.hh:73
Scroom::Bookkeeping::Token registerObserver(ObserverWeak const &observer)
Definition observable.hh:232
Definition color.hh:26
Definition tweak-view.hh:22
STL namespace.
Stuff registration
Definition observable-tests.cc:96
TestObserver::Ptr observer
Definition observable-tests.cc:91
Scroom::Bookkeeping::Token const token
Definition pipette-tests.cc:269
SampleIterator< const uint8_t > result
Definition sampleiterator-tests.cc:94
ThreadPool t(0)
Scroom::Utils::Rectangle< double > const r
Definition transformpresentation_test.cc:65