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