Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Event.h
Aller à la documentation de ce fichier.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Event.h (C) 2000-2025 */
9/* */
10/* Gestionnaires d'évènements. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_EVENT_H
13#define ARCANE_UTILS_EVENT_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18#include "arcane/utils/Array.h"
19
20#include <functional>
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25namespace Arcane
26{
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30/*!
31 * \internal
32 * \brief Classe de base d'un handler d'évènement.
33 */
34class ARCANE_UTILS_EXPORT EventObservableBase
35{
36 friend EventObserverBase;
37 class Impl;
38
39 public:
40
41 EventObservableBase();
42 virtual ~EventObservableBase();
43
44 public:
45
46 EventObservableBase(const EventObservableBase&) = delete;
47 EventObservableBase(EventObservableBase&&) = delete;
48 EventObservableBase& operator=(const EventObservableBase&) = delete;
49 EventObservableBase& operator=(EventObservableBase&&) = delete;
50
51 public:
52
53 bool hasObservers() const { return !m_observers_array.empty(); }
54 void detachAllObservers();
55
56 protected:
57
58 void _attachObserver(EventObserverBase* obs, bool is_auto_destroy);
59 void _detachObserver(EventObserverBase* obs);
60 ConstArrayView<EventObserverBase*> _observers() const
61 {
62 return m_observers_array;
63 }
64
65 private:
66
67 Impl* m_p = nullptr;
68 UniqueArray<EventObserverBase*> m_observers_array;
69
70 private:
71
72 void _rebuildObserversArray();
73};
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77/*!
78 * \internal
79 * \brief Classe de base d'un observateur d'évènement.
80 *
81 * L'ajoute ou la suppression d'un observeur se fait via les opérateurs
82 * EventObservable::operator+=() et EventObservable::operator-=().
83 */
84class ARCANE_UTILS_EXPORT EventObserverBase
85{
86 friend class EventObservableBase;
87
88 public:
89
90 EventObserverBase() = default;
91 virtual ~EventObserverBase() ARCANE_NOEXCEPT_FALSE;
92
93 protected:
94
95 void _notifyDetach();
96 void _notifyAttach(EventObservableBase* obs);
97
98 private:
99
100 EventObservableBase* m_observable = nullptr;
101};
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105/*!
106 * \ingroup Utils
107 * \brief Observateur d'évènements.
108 */
109template <typename... Args>
110class EventObserver
111: public EventObserverBase
112{
113 public:
114
115 typedef EventObservable<Args...> ObservableType;
116
117 public:
118
119 EventObserver() {}
120 EventObserver(const std::function<void(Args...)>& func)
121 : m_functor(func)
122 {}
123 EventObserver(std::function<void(Args...)>&& func)
124 : m_functor(func)
125 {}
126 void observerUpdate(Args... args)
127 {
128 if (m_functor)
129 m_functor(args...);
130 }
131
132 private:
133
134 std::function<void(Args...)> m_functor;
135};
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139/*!
140 * \brief Conserve des références d'observateurs.
141 */
142class ARCANE_UTILS_EXPORT EventObserverPool
143{
144 public:
145
147
148 public:
149
150 //! Ajoute l'observateur \a x
151 void add(EventObserverBase* x);
152 //! Supprime tous les observateurs associés à cette instance.
153 void clear();
154
155 private:
156
158};
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162/*!
163 * \ingroup Utils
164 * \brief Classe de base d'un handler d'évènement.
165 *
166 * Les instances de cette classe ne peuvent pas être copiées.
167 *
168 * Cette classe permet d'enregistrer une liste d'observateurs qui peuvent
169 * être notifiés lors de l'appel à notify(). \a Args contient
170 * la liste des paramètres de notification.
171 *
172 * Il est possible d'ajouter un observateur via la méthode attach(). Si
173 * l'observateur est une fonction lambda, il est nécessaire de
174 * spécifier une instance de EventObserverPool pour gérer la durée
175 * de vie de la lambda, qui sera alors la même que celle de
176 * l'EventObserverPool associé.
177 *
178 \code
179 * //! Evènement appelant une méthode void f(int,double):
180 * EventObservable<int,double> observable;
181 * EventObserverPool pool;
182 * observable.attach(pool,[](int a,double b) { ... });
183 * std::function<int,double> f2(...);
184 * auto o = new EventObserver<int,double>(f2);
185 * observable.attach(o);
186 * observable.notify(1,3.2);
187 \endcode
188 *
189 */
190template <typename... Args>
191class EventObservable
192: public EventObservableBase
193{
194 public:
195
196 typedef EventObserver<Args...> ObserverType;
197
198 public:
199
200 EventObservable() = default;
201
202 public:
203
204 /*!
205 * \brief Attache l'observateur \a o à cet observable.
206 *
207 * Une exception est levée si l'observateur est déjà attaché à un observable.
208 */
209 void attach(ObserverType* o) { _attachObserver(o, false); }
210 /*!
211 * \brief Détache l'observateur \a o de cet observable.
212 *
213 * Une exception est levée si l'observateur n'est pas attaché à cet observable.
214 */
215 void detach(ObserverType* o) { _detachObserver(o); }
216
217 /*!
218 * \brief Ajoute un observateur utilisant la lambda \a lambda
219 * et conserve une référence dans \a pool.
220 */
221 template <typename Lambda>
222 void attach(EventObserverPool& pool, const Lambda& lambda)
223 {
224 auto x = new ObserverType(lambda);
225 _attachObserver(x, false);
226 pool.add(x);
227 }
228
229 //! Appelle les observeurs associés à cet observable.
230 void notify(Args... args)
231 {
232 if (!hasObservers())
233 return;
234 for (auto o : _observers())
235 ((ObserverType*)o)->observerUpdate(args...);
236 }
237};
238
239/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
241/*!
242 * \ingroup Utils
243 * \brief Classe gérant les observateurs associés à un évènement.
244 * \sa EventObservable
245 */
246template <typename... Args>
247class EventObservableView
248{
249 public:
250
251 typedef EventObserver<Args...> ObserverType;
252
253 public:
254
255 explicit EventObservableView(EventObservable<Args...>& v)
256 : m_observable_ref(v)
257 {}
258
259 public:
260
261 /*!
262 * \brief Attache l'observateur \a o à cet observable.
263 *
264 * Une exception est levée si l'observateur est déjà attaché à un observable.
265 */
266 void attach(ObserverType* o) { m_observable_ref.attach(o); }
267 /*!
268 * \brief Détache l'observateur \a o de cet observable.
269 *
270 * Une exception est levée si l'observateur n'est pas attaché à cet observable.
271 */
272 void detach(ObserverType* o) { m_observable_ref.detach(o); }
273
274 /*!
275 * \brief Ajoute un observateur utilisant la lambda \a lambda
276 * et conserve une référence dans \a pool.
277 */
278 template <typename Lambda>
279 void attach(EventObserverPool& pool, const Lambda& lambda)
280 {
281 m_observable_ref.attach(pool, lambda);
282 }
283
284 private:
285
286 EventObservable<Args...>& m_observable_ref;
287};
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
292} // namespace Arcane
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297#endif
Déclarations des types utilisés dans Arcane.
Vue constante d'un tableau de type T.
void attach(ObserverType *o)
Attache l'observateur o à cet observable.
Definition Event.h:266
void detach(ObserverType *o)
Détache l'observateur o de cet observable.
Definition Event.h:272
void attach(EventObserverPool &pool, const Lambda &lambda)
Ajoute un observateur utilisant la lambda lambda et conserve une référence dans pool.
Definition Event.h:279
Classe de base d'un handler d'évènement.
Definition Event.h:193
void detach(ObserverType *o)
Détache l'observateur o de cet observable.
Definition Event.h:215
void attach(EventObserverPool &pool, const Lambda &lambda)
Ajoute un observateur utilisant la lambda lambda et conserve une référence dans pool.
Definition Event.h:222
void attach(ObserverType *o)
Attache l'observateur o à cet observable.
Definition Event.h:209
void notify(Args... args)
Appelle les observeurs associés à cet observable.
Definition Event.h:230
Conserve des références d'observateurs.
Definition Event.h:143
void clear()
Supprime tous les observateurs associés à cette instance.
Definition Event.cc:189
void add(EventObserverBase *x)
Ajoute l'observateur x.
Definition Event.cc:200
Observateur d'évènements.
Definition Event.h:112
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-