AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
Observer.hpp
1#pragma once
2
3#include <list>
4#include <utility>
5
6#include <amdis/Output.hpp>
7#include <amdis/common/ConceptsBase.hpp>
8#include <amdis/common/Index.hpp>
9#include <amdis/common/TypeTraits.hpp>
10
11namespace AMDiS
12{
13 namespace event
14 {
19 struct preAdapt { bool value = true; };
20
25 struct adapt { bool value = true; };
26
30 struct postAdapt {};
31 }
32
33
34 template <class Event>
36 {
37 public:
38 virtual ~ObserverInterface() = default;
39 virtual void update(Event e) = 0;
40 virtual void unset() = 0;
41 };
42
43
45
53 template <class Event, class... Events>
55 : public Notifier<Event>
56 , public Notifier<Events...>
57 {
58 public:
59 using Notifier<Event>::notify;
60 using Notifier<Events...>::notify;
61 };
62
63 template <class Event>
64 class Notifier<Event>
65 {
66 public:
67 virtual ~Notifier()
68 {
69 // Remove remaining pointers to this to avoid segfaults
70 for (ObserverInterface<Event>* o : observers_)
71 o->unset();
72 }
73
75 void notify(Event const& e)
76 {
77 for (ObserverInterface<Event>* o : observers_)
78 o->update(e);
79 }
80
83 {
84 // insert only if not yet in the list
85 if (std::find(observers_.begin(), observers_.end(), o) == observers_.end())
86 observers_.push_back(o);
87 }
88
91 {
92 observers_.remove(o);
93 }
94
95 private:
96 std::list<ObserverInterface<Event>*> observers_;
97 };
98
99
101 template <class Event, class... Tags>
103 : public ObserverInterface<Event>
104 {
105 public:
106 template <class N,
107 REQUIRES(std::is_base_of_v<Notifier<Event>,N>)>
108 Observer(N const& notifier)
109 : notifier_(const_cast<N*>(&notifier))
110 {
111 notifier_->attach(this);
112 }
113
114 template <class N,
115 REQUIRES(not std::is_base_of_v<Notifier<Event>,N>)>
116 Observer(N const& notifier)
117 {
118 warning("Ignoring Notifier. Use AdaptiveGrid wrapper.");
119 }
120
121
123 virtual ~Observer()
124 {
125 if (notifier_)
126 notifier_->detach(this);
127 }
128
130 Observer(Observer const& other)
131 : notifier_(other.notifier_)
132 {
133 notifier_->attach(this);
134 }
135
138 {
139 if (&other != this) {
140 notifier_->detach(this);
141 notifier_ = other.notifier_;
142 notifier_->attach(this);
143 }
144 return *this;
145 }
146
149 void unset() final
150 {
151 notifier_ = nullptr;
152 }
153
156 void update(Event e) final
157 {
158 updateImpl(e, Tags{}...);
159 }
160
161 protected:
163 // NOTE: The additional `Tags...` arguments can be used to distinguish
164 // between multiple observers of the same event.
165 virtual void updateImpl(Event e, Tags...) = 0;
166
167 private:
168 Notifier<Event>* notifier_ = nullptr;
169 };
170
171
172 namespace Impl
173 {
174 template <class Event, class Tags>
175 class ObserverSequenceImpl;
176
178 template <class Event, std::size_t... Is>
179 class ObserverSequenceImpl<Event, std::index_sequence<Is...>>
180 : private Observer<Event,index_t<Is>>...
181 {
182 public:
183 template <class... Notifiers,
184 REQUIRES(sizeof...(Notifiers) == sizeof...(Is))>
185 ObserverSequenceImpl(Notifiers&&... notifiers)
186 : Observer<Event,index_t<Is>>(FWD(notifiers))...
187 {}
188 };
189
190 } // end namespace Impl
191
192 template <class Event, std::size_t N>
193 using ObserverSequence = Impl::ObserverSequenceImpl<Event, std::make_index_sequence<N>>;
194
195} // end namespace AMDiS
Definition: Observer.hpp:65
void detach(ObserverInterface< Event > *o)
Detaches the passed observer from the list, if stored.
Definition: Observer.hpp:90
void attach(ObserverInterface< Event > *o)
Attach a new observer that gets called on notify.
Definition: Observer.hpp:82
void notify(Event const &e)
Call the update method on all attached observers.
Definition: Observer.hpp:75
Mixin for signaling of certain events.
Definition: Observer.hpp:57
Definition: Observer.hpp:36
Implementation of the ObserverInterface.
Definition: Observer.hpp:104
virtual ~Observer()
Destructor, detaches from the notifier.
Definition: Observer.hpp:123
virtual void updateImpl(Event e, Tags...)=0
Implementation of the update method in derived class.
void unset() final
Definition: Observer.hpp:149
void update(Event e) final
Definition: Observer.hpp:156
Observer & operator=(Observer const &other)
Copy-assignment operator, copies the notifier and attaches this.
Definition: Observer.hpp:137
Observer(Observer const &other)
Copy constructor. Attaches this to the copied notifier.
Definition: Observer.hpp:130
Definition: Observer.hpp:25
Definition: Observer.hpp:30
Definition: Observer.hpp:19