KiCad PCB EDA Suite
Loading...
Searching...
No Matches
observable.cpp
Go to the documentation of this file.
1/*
2* This program source code file is part of KICAD, a free EDA CAD application.
3*
4* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5*
6* This program is free software; you can redistribute it and/or
7* modify it under the terms of the GNU General Public License
8* as published by the Free Software Foundation; either version 2
9* of the License, or (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20#include <core/observable.h>
21#include <algorithm>
22
23namespace UTIL {
24
25 namespace DETAIL {
26
27 template<typename T>
28 struct equals {
29 equals( const T& val ) : val_( val ) {}
30
31 bool operator()( const T& val ) const
32 {
33 return val == val_;
34 }
35
36 private:
37 const T& val_;
38 };
39
40
42 : iteration_count_( 0 ), owned_by_( owned_by )
43 {}
44
45
47 {
48 return owned_by_ == nullptr;
49 }
50
51
53 {
54 owned_by_ = nullptr;
55 }
56
57
61
62
67
68
70 {
72
73 if( iteration_count_ == 0 )
74 collect();
75 }
77
79 {
80 return iteration_count_ != 0;
81 }
82
85 {
86 assert( !is_iterating() );
87 observers_.push_back( observer );
88 }
89
90
92 {
93 auto it = std::find( observers_.begin(), observers_.end(), observer );
94
95 if( it == observers_.end() )
96 {
97 assert( false );
98 return;
99 }
100
101 if( is_iterating() )
102 *it = nullptr;
103 else
104 observers_.erase( it );
105 }
106
107
109 {
110 auto it = std::remove_if( observers_.begin(), observers_.end(), DETAIL::equals<void*>( nullptr ) );
111 observers_.erase( it, observers_.end() );
112 }
113 }
114
115
117 : observer_( nullptr )
118 {
119 }
120
121
122 LINK::LINK( std::shared_ptr<DETAIL::OBSERVABLE_BASE::IMPL> token, void* observer )
123 : token_( std::move( token ) ), observer_( observer )
124 {
125 }
126
127
128 LINK::LINK( LINK&& other )
129 : token_( std::move( other.token_ ) ), observer_( other.observer_ )
130 {
131 other.token_.reset();
132 }
133
134
136 {
137 token_ = std::move( other.token_ );
138 other.token_.reset();
139 observer_ = other.observer_;
140 return *this;
141 }
142
143
144 LINK::operator bool() const
145 {
146 return token_ ? true : false;
147 }
148
149
151 {
152 reset();
153 }
154
155
157 {
158 if(token_)
159 {
160 token_->remove_observer( observer_ );
161 token_.reset();
162 }
163 }
164
165
166 namespace DETAIL {
167
171
172
177
178
182
183
185 {
186 if(!impl_)
187 impl_ = std::make_shared<IMPL>( this );
188 }
189
190
192 {
193 if(!impl_)
194 impl_ = std::make_shared<IMPL>();
195 else
196 impl_->set_shared();
197 }
198
199
201 impl_.reset();
202 }
203
204
205 std::shared_ptr<OBSERVABLE_BASE::IMPL> OBSERVABLE_BASE::get_shared_impl()
206 {
208 return impl_;
209 }
210
211
212 void OBSERVABLE_BASE::add_observer( void* observer )
213 {
215 impl_->add_observer( observer );
216 }
217
218
219 void OBSERVABLE_BASE::remove_observer( void* observer )
220 {
221 assert( impl_ );
222 impl_->remove_observer( observer );
223 }
224
225
227 {
228 if( impl_ )
229 impl_->enter_iteration();
230 }
231
232
234 {
235 if( impl_)
236 {
237 impl_->leave_iteration();
238
239 if( !impl_->is_iterating() && !impl_->is_shared() && impl_.use_count() == 1 )
240 impl_.reset();
241 }
242 }
243
244
246 {
247 if( impl_ )
248 return impl_->observers_.size();
249 else
250 return 0;
251 }
252
253
255 {
256 // called by an impl that is owned by this, ie. it is a non-shared impl
257 // also it is not iterating
259 }
260
261 }
262
263}
A model subscriber implementation using links to represent connections.
STL namespace.
void remove_observer(void *observer)
void add_observer(void *observer)
std::vector< void * > observers_
Definition observable.h:68
IMPL(OBSERVABLE_BASE *owned_by=nullptr)
void remove_observer(void *observer)
std::shared_ptr< IMPL > get_shared_impl()
void add_observer(void *observer)
std::shared_ptr< IMPL > impl_
Definition observable.h:89
equals(const T &val)
bool operator()(const T &val) const