Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Event.cc
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.cc (C) 2000-2025 */
9/* */
10/* Gestionnaires d'évènements. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Event.h"
15#include "arcane/utils/UniqueArray.h"
16#include "arcane/utils/FatalErrorException.h"
17
18#include <set>
19#include <iostream>
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23/*!
24 * \file utils/Event.h
25 *
26 * \brief Fichier contenant les mécanismes de gestion des évènements.
27 */
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace Arcane
32{
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
38{
39 public:
40
41 Impl() {}
42
43 public:
44
45 std::set<EventObserverBase*> m_auto_destroy_observers;
46 std::set<EventObserverBase*> m_observers;
47};
48
49/*---------------------------------------------------------------------------*/
50/*---------------------------------------------------------------------------*/
51
52EventObservableBase::
53EventObservableBase()
54: m_p(new Impl())
55{
56}
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
60
61EventObservableBase::
62~EventObservableBase()
63{
64 try{
65 detachAllObservers();
66 }
67 catch(...){
68 std::cerr << "ERROR: Exception launched during call to ~EventObservableBase().\n";
69 }
70 delete m_p;
71}
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76void EventObservableBase::
77_rebuildObserversArray()
78{
79 m_observers_array.clear();
80 m_observers_array.reserve(m_p->m_observers.size());
81 for (auto o : m_p->m_observers)
82 m_observers_array.add(o);
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88void EventObservableBase::
89_attachObserver(EventObserverBase* obs, bool is_auto_destroy)
90{
91 // Vérifie que l'observeur n'est pas dans la liste.
92 if (m_p->m_observers.find(obs) != m_p->m_observers.end())
93 ARCANE_FATAL("Observer is already attached to this observable");
94 obs->_notifyAttach(this);
95 m_p->m_observers.insert(obs);
96 _rebuildObserversArray();
97 if (is_auto_destroy)
98 m_p->m_auto_destroy_observers.insert(obs);
99}
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
104void EventObservableBase::
105_detachObserver(EventObserverBase* obs)
106{
107 // NOTE: il est impossible de détacher un observeur qui a été alloué
108 // dynamiquement. Il n'y a donc pas besoin de mettre à jour
109 // m_p->m_auto_destroy_observers.
110 bool is_ok = false;
111 for (auto o : m_p->m_observers)
112 if (o == obs) {
113 m_p->m_observers.erase(o);
114 is_ok = true;
115 break;
116 }
117
118 // Lance une exception si pas trouvé
119 if (!is_ok)
120 ARCANE_FATAL("observer is not registered to this observable");
121 obs->_notifyDetach();
122 _rebuildObserversArray();
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
128void EventObservableBase::
129detachAllObservers()
130{
131 for( auto o : m_p->m_observers )
132 o->_notifyDetach();
133 m_p->m_observers.clear();
134 for( auto o : m_p->m_auto_destroy_observers )
135 delete o;
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
144EventObserverBase::
145~EventObserverBase() ARCANE_NOEXCEPT_FALSE
146{
147 if (m_observable)
148 m_observable->_detachObserver(this);
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154void EventObserverBase::
155_notifyDetach()
156{
157 if (!m_observable)
158 ARCANE_FATAL("EventObserver is not attached to an EventObservable");
159 m_observable = nullptr;
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
165void EventObserverBase::
166_notifyAttach(EventObservableBase* obs)
167{
168 if (m_observable)
169 ARCANE_FATAL("EventObserver is already attached to an EventObservable");
170 m_observable = obs;
171}
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
179EventObserverPool::
180~EventObserverPool()
181{
182 clear();
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
189clear()
190{
191 for( auto o : m_observers )
192 delete o;
193 m_observers.clear();
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
201{
202 m_observers.add(obs);
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208} // End namespace Arcane
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les mécanismes de gestion des évènements.
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
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-