Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
observer.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//bertini2/detail/observer.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//bertini2/detail/observer.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with bertini2/detail/observer.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
30
31#ifndef BERTINI_DETAIL_OBSERVER_HPP
32#define BERTINI_DETAIL_OBSERVER_HPP
33
34#include <tuple>
35#include <typeindex>
36#include <utility>
37#include <vector>
38
39#include <boost/fusion/adapted/std_tuple.hpp>
40
41#include <boost/fusion/algorithm/iteration/for_each.hpp>
42#include <boost/fusion/include/for_each.hpp>
43
45
46namespace bertini{
47
48
60
61
68 { BOOST_TYPE_INDEX_REGISTER_CLASS
69 public:
70 virtual ~AnyObserver() = default;
71
82 virtual ObserveResult Observe(AnyEvent const& e) = 0;
83
93 virtual std::vector<std::type_index> SubscribedEventTypes() const { return {}; }
94
103 virtual std::type_index ObservedKind() const { return typeid(void); }
104 };
105
106
115 template<class ObservedT>
116 class Observer : public AnyObserver
117 { BOOST_TYPE_INDEX_REGISTER_CLASS
118 public:
119 virtual ~Observer() = default;
120
121 std::type_index ObservedKind() const override { return typeid(ObservedT); }
122 };
123
124
125
126
137 template<class ObservedT, template<class> class... ObserverTypes>
138 class MultiObserver : public Observer<ObservedT>
139 { BOOST_TYPE_INDEX_REGISTER_CLASS
140 public:
141
151 ObserveResult Observe(AnyEvent const& e) override
152 {
153 using namespace boost::fusion;
154 bool keep = false;
155 // Route through the AnyObserver interface: a glued-in observer may be a
156 // TypedObserver, whose typed Observe(ConcreteEvent const&) overloads hide
157 // the untyped Observe(AnyEvent const&) for ordinary name lookup. The
158 // virtual call reaches the right dispatcher in every case.
159 auto f = [&e,&keep](auto &obs) {
160 if (static_cast<AnyObserver&>(obs).Observe(e) == ObserveResult::KeepObserving)
161 keep = true;
162 };
163 for_each(observers_, f);
165 }
166
167 std::tuple<ObserverTypes<ObservedT>...> observers_;
168 virtual ~MultiObserver() = default;
169 };
170
171
199 template<class Derived, class ObservedT, class... ConcreteEvents>
200 class TypedObserver : public Observer<ObservedT>
201 { BOOST_TYPE_INDEX_REGISTER_CLASS
202 public:
203 std::vector<std::type_index> SubscribedEventTypes() const override
204 {
205 return { std::type_index(typeid(ConcreteEvents))... };
206 }
207
208 ObserveResult Observe(AnyEvent const& e) override
209 {
211 bool matched = false;
212 // try each subscribed type; the first whose dynamic type matches wins.
213 (TryDispatch<ConcreteEvents>(e, result, matched), ...);
214 return result;
215 }
216
217 virtual ~TypedObserver() = default;
218
219 private:
220 template<class Ev>
221 void TryDispatch(AnyEvent const& e, ObserveResult& result, bool& matched)
222 {
223 if (matched)
224 return;
225 if (auto p = dynamic_cast<const Ev*>(&e))
226 {
227 matched = true;
228 result = static_cast<Derived*>(this)->OnEvent(*p);
229 }
230 }
231 };
232
233
234}
235
236#endif
Strawman Event type, enabling polymorphism.
Definition events.hpp:57
Strawman base class for Observer objects.
Definition observer.hpp:68
virtual std::type_index ObservedKind() const
The type this observer expects to observe.
Definition observer.hpp:103
virtual ObserveResult Observe(AnyEvent const &e)=0
Observe the observable object being observed.
virtual std::vector< std::type_index > SubscribedEventTypes() const
Declares which event types this observer wants to receive.
Definition observer.hpp:93
virtual ~AnyObserver()=default
A class which can glob together observer types into a new, single observer type.
Definition observer.hpp:139
std::tuple< ObserverTypes< ObservedT >... > observers_
The held sub-observers, one per observer type.
Definition observer.hpp:167
ObserveResult Observe(AnyEvent const &e) override
Observe override which calls the overrides for the types you glued together.
Definition observer.hpp:151
virtual ~MultiObserver()=default
Actual observer type, which you should derive from to extract custom information from observable type...
Definition observer.hpp:117
virtual ~Observer()=default
std::type_index ObservedKind() const override
The type this observer expects to observe.
Definition observer.hpp:121
CRTP base that turns an observer into a set of typed Observe() overloads.
Definition observer.hpp:201
virtual ~TypedObserver()=default
ObserveResult Observe(AnyEvent const &e) override
Observe the observable object being observed.
Definition observer.hpp:208
std::vector< std::type_index > SubscribedEventTypes() const override
Declares which event types this observer wants to receive.
Definition observer.hpp:203
Contains the detail/events base types.
Definition algorithm_builder.hpp:36
ObserveResult
The result an observer returns from Observe(), telling the observable whether to keep sending it even...
Definition observer.hpp:59
@ Unsubscribe
Definition observer.hpp:59
@ KeepObserving
Definition observer.hpp:59