aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
signaler.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
68
69#ifndef GUM_SIGNALER_H
70#define GUM_SIGNALER_H
71
72#include <algorithm>
73#include <functional>
74#include <vector>
75
76#include <agrum/agrum.h>
77
79
80namespace gum {
81
82 namespace __sig__ {
83
84 // =========================================================================
85 // IConnector<Args...> : Abstract interface for connectors with any args
86 // =========================================================================
92 template < typename... Args >
93 class IConnector {
94 public:
95 virtual ~IConnector() = default;
96
98 virtual Listener* target() const = 0;
99
101 virtual void notify(const void* src, Args... args) = 0;
102
104 virtual IConnector< Args... >* clone() const = 0;
105
107 [[nodiscard]] virtual IConnector< Args... >* duplicate(Listener* newTarget) const = 0;
108 };
109
110 // =========================================================================
111 // Connector<TargetClass, Args...> : Concrete connector implementation
112 // =========================================================================
119 template < class TargetClass, typename... Args >
120 class Connector: public IConnector< Args... > {
121 public:
123 using ActionType = void (TargetClass::*)(const void*, Args...);
124
126 Connector() : _target_(nullptr), _action_(nullptr) { GUM_CONSTRUCTOR(Connector); }
127
129 Connector(TargetClass* target, ActionType action);
130
132 Connector(const Connector& src);
133
135 ~Connector() override { GUM_DESTRUCTOR(Connector); }
136
138 Listener* target() const override;
139
141 void notify(const void* src, Args... args) override;
142
144 IConnector< Args... >* clone() const override;
145
147 [[nodiscard]] IConnector< Args... >* duplicate(Listener* newTarget) const override;
148
149 private:
150 TargetClass* _target_;
152 };
153
154 // =========================================================================
155 // BasicSignaler<Args...> : Base signaler with connector management
156 // =========================================================================
162 template < typename... Args >
163 class BasicSignaler: public ISignaler {
164 protected:
165 using ConnectorList = std::vector< IConnector< Args... >* >;
166
168 BasicSignaler() { GUM_CONSTRUCTOR(BasicSignaler); }
169
171 BasicSignaler(const BasicSignaler& other);
172
173 public:
175 ~BasicSignaler() override;
176
178 bool hasListener() override;
179
181 void detach(Listener* target);
182
183 protected:
184 friend class gum::Listener;
185
187 void detachFromTarget(Listener* target) override;
188
190 void duplicateTarget(const Listener* oldTarget, Listener* newTarget) override;
191
193 };
194
195 } // namespace __sig__
196
197 // ===========================================================================
198 // Signaler<Args...> : The main variadic signaler class
199 // ===========================================================================
235 template < typename... Args >
236 class Signaler: public __sig__::BasicSignaler< Args... > {
237 public:
239 Signaler() { GUM_CONSTRUCTOR(Signaler); }
240
242 Signaler(const Signaler& other);
243
245 ~Signaler() override { GUM_DESTRUCTOR(Signaler); }
246
253 template < class TargetClass >
254 void attach(TargetClass* target, void (TargetClass::*action)(const void*, Args...));
255
261 void operator()(const void* src, Args... args);
262 };
263
264 // ===========================================================================
265 // Signaler0 : Alias for Signaler<> (signal with no arguments)
266 // ===========================================================================
274
275} // namespace gum
276
277// ===========================================================================
278// Emit macros
279// ===========================================================================
280
282#define GUM_EMIT0(signal) (signal)(this)
283
286#define GUM_EMIT_ARGS(signal, ...) (signal)(this, __VA_ARGS__)
287
288// Legacy macros for backward compatibility (all map to GUM_EMIT_ARGS)
289#define GUM_EMIT1(signal, arg1) GUM_EMIT_ARGS(signal, arg1)
290#define GUM_EMIT2(signal, arg1, arg2) GUM_EMIT_ARGS(signal, arg1, arg2)
291#define GUM_EMIT3(signal, arg1, arg2, arg3) GUM_EMIT_ARGS(signal, arg1, arg2, arg3)
292#define GUM_EMIT4(signal, arg1, arg2, arg3, arg4) GUM_EMIT_ARGS(signal, arg1, arg2, arg3, arg4)
293#define GUM_EMIT5(signal, arg1, arg2, arg3, arg4, arg5) \
294 GUM_EMIT_ARGS(signal, arg1, arg2, arg3, arg4, arg5)
295#define GUM_EMIT6(signal, arg1, arg2, arg3, arg4, arg5, arg6) \
296 GUM_EMIT_ARGS(signal, arg1, arg2, arg3, arg4, arg5, arg6)
297#define GUM_EMIT7(signal, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
298 GUM_EMIT_ARGS(signal, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
299
301#define GUM_CONNECT(sender, signal, receiver, target) (sender).signal.attach(&(receiver), &target)
302
304
305#endif // GUM_SIGNALER_H
Every class who would catch signal from signaler should derive from Listener.
Definition listener.h:93
Signaler(const Signaler &other)
Copy constructor.
Signaler()
Default constructor.
Definition signaler.h:239
void attach(TargetClass *target, void(TargetClass::*action)(const void *, Args...))
Attach a listener with a member function callback.
void operator()(const void *src, Args... args)
Emit the signal, notifying all attached listeners.
~Signaler() override
Destructor.
Definition signaler.h:245
Base class for signalers, managing connector lifecycle.
Definition signaler.h:163
std::vector< IConnector< Args... > * > ConnectorList
Definition signaler.h:165
void duplicateTarget(const Listener *oldTarget, Listener *newTarget) override
Called by Listener copy constructor to duplicate connections.
BasicSignaler()
Default constructor.
Definition signaler.h:168
friend class gum::Listener
Definition signaler.h:184
~BasicSignaler() override
Destructor: detaches from all targets and deletes connectors.
void detachFromTarget(Listener *target) override
Called by Listener to detach when the listener is destroyed.
ConnectorList _connectors_
Definition signaler.h:192
void detach(Listener *target)
Detach a specific listener from this signaler.
Concrete connector binding a target object and its member function.
Definition signaler.h:120
void(TargetClass::*)(const void *, Args...) ActionType
Type alias for the member function pointer.
Definition signaler.h:123
Listener * target() const override
IConnector< Args... > * duplicate(Listener *newTarget) const override
Create a duplicate connector pointing to a new target.
void notify(const void *src, Args... args) override
Notify the target with the given source and arguments.
~Connector() override
Destructor.
Definition signaler.h:135
Connector()
Default constructor.
Definition signaler.h:126
TargetClass * _target_
Definition signaler.h:150
IConnector< Args... > * clone() const override
Create a deep copy of this connector.
Abstract interface for signal connectors with variadic arguments.
Definition signaler.h:93
virtual void notify(const void *src, Args... args)=0
Notify the target with the given source and arguments.
virtual IConnector< Args... > * duplicate(Listener *newTarget) const =0
Create a duplicate connector pointing to a new target.
virtual ~IConnector()=default
virtual Listener * target() const =0
virtual IConnector< Args... > * clone() const =0
Create a deep copy of this connector.
Class of listener.
Internal namespace for aGrUM signaler/listener components.
Definition agrum.h:49
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Signaler<> Signaler0
Signaler with no arguments.
Definition signaler.h:273