Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
Event.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* Event managers. */
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/*---------------------------------------------------------------------------*/
25
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
42{
43 public:
44
45 Impl() {}
46
47 public:
48
49 std::set<EventObserverBase*> m_auto_destroy_observers;
50 std::set<EventObserverBase*> m_observers;
51};
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56EventObservableBase::
57EventObservableBase()
58: m_p(new Impl())
59{
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65EventObservableBase::
66~EventObservableBase()
67{
68 try {
69 detachAllObservers();
70 }
71 catch (...) {
72 std::cerr << "ERROR: Exception launched during call to ~EventObservableBase().\n";
73 }
74 delete m_p;
75}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80void EventObservableBase::
81_rebuildObserversArray()
82{
83 m_observers_array.clear();
84 m_observers_array.reserve(m_p->m_observers.size());
85 for (auto o : m_p->m_observers)
86 m_observers_array.add(o);
87}
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
91
92void EventObservableBase::
93_attachObserver(EventObserverBase* obs, bool is_auto_destroy)
94{
95 // Checks that the observer is not in the list.
96 if (m_p->m_observers.find(obs) != m_p->m_observers.end())
97 ARCCORE_FATAL("Observer is already attached to this observable");
98 obs->_notifyAttach(this);
99 m_p->m_observers.insert(obs);
100 _rebuildObserversArray();
101 if (is_auto_destroy)
102 m_p->m_auto_destroy_observers.insert(obs);
103}
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108void EventObservableBase::
109_detachObserver(EventObserverBase* obs)
110{
111 // NOTE: it is impossible to detach an observer that was
112 // dynamically allocated. There is therefore no need to update
113 // m_p->m_auto_destroy_observers.
114 bool is_ok = false;
115 for (auto o : m_p->m_observers)
116 if (o == obs) {
117 m_p->m_observers.erase(o);
118 is_ok = true;
119 break;
120 }
121
122 // Throws an exception if not found
123 if (!is_ok)
124 ARCCORE_FATAL("observer is not registered to this observable");
125 obs->_notifyDetach();
126 _rebuildObserversArray();
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
132void EventObservableBase::
133detachAllObservers()
134{
135 for (auto o : m_p->m_observers)
136 o->_notifyDetach();
137 m_p->m_observers.clear();
138 for (auto o : m_p->m_auto_destroy_observers)
139 delete o;
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148EventObserverBase::
149~EventObserverBase() ARCCORE_NOEXCEPT_FALSE
150{
151 if (m_observable)
152 m_observable->_detachObserver(this);
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158void EventObserverBase::
159_notifyDetach()
160{
161 if (!m_observable)
162 ARCCORE_FATAL("EventObserver is not attached to an EventObservable");
163 m_observable = nullptr;
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168
169void EventObserverBase::
170_notifyAttach(EventObservableBase* obs)
171{
172 if (m_observable)
173 ARCCORE_FATAL("EventObserver is already attached to an EventObservable");
174 m_observable = obs;
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
180/*---------------------------------------------------------------------------*/
181/*---------------------------------------------------------------------------*/
182
183EventObserverPool::
184~EventObserverPool()
185{
186 clear();
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
193clear()
194{
195 for (auto o : m_observers)
196 delete o;
197 m_observers.clear();
198}
199
200/*---------------------------------------------------------------------------*/
201/*---------------------------------------------------------------------------*/
202
205{
206 m_observers.add(obs);
207}
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
211
212} // End namespace Arcane
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
void clear()
Clears all observers associated with this instance.
Definition Event.cc:193
void add(EventObserverBase *x)
Adds the observer x.
Definition Event.cc:204
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --