aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
signaler_with_args.pattern.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Meta classes for signalers.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  *
28  */
29 
30 #ifndef SIGNALER_PATRON_ACCEPTED
31 # error "This file should not be included directly. Please use signaler{x}.h"
32 #endif // SIGNALER_PATRON_ACCEPTED
33 
34 #include <agrum/tools/core/list.h>
35 
36 #ifndef DOXYGEN_SHOULD_SKIP_THIS
37 
38 namespace gum {
39 
40  namespace __sig__ {
41 
42  template < LIST_DECL_CLASSES >
43  class MAKE_NAME(IConnector) {
44  public:
45  virtual ~MAKE_NAME(IConnector)() {}
46 
47  virtual Listener* target() const = 0;
48  virtual void notify(const void*, LIST_DECL_ARGS) = 0;
49  virtual MAKE_NAME(IConnector)< LIST_CLASSES >* clone() = 0;
51  };
52 
53  template < LIST_DECL_CLASSES >
54  class MAKE_NAME(BasicSignaler) : public ISignaler {
55  protected:
58 
61  ;
62  }
63 
65  (const MAKE_NAME(BasicSignaler) & s) : ISignaler(s) {
67 
68  for (const auto& connector: connectors_) {
71  }
72  }
73 
74  public:
75  virtual ~MAKE_NAME(BasicSignaler)() {
77 
78  for (const auto& connector: connectors_) {
80  delete connector;
81  }
82 
84  }
85 
86  bool hasListener() { return (!(connectors_.empty())); }
87 
88  void detach(Listener* target) {
89  for (ConnectorIterator it = connectors_.reginSafe(); // safe iterator needed here
90  it != connectors_.rendSafe();
91  --it) {
92  if ((*it)->target() == target) {
93  delete *it;
95  target->_detachSignal_(this);
96  return;
97  }
98  }
99  }
100 
101  protected:
102  friend class Listener;
103 
105  for (const auto& connector: connectors_)
106  if (connector->target() == oldtarget) {
108  }
109  }
110 
113 
114  for (ConnectorIterator it = connectors_.rbeginSafe(); // safe iterator needed here
115  it != connectors_.rendSafe();) {
116  itprev = it;
117  --it;
118 
119  if ((*itprev)->target() == target) {
120  delete *itprev;
122  }
123  }
124  }
125 
127  };
128 
129  template < class TargetClass, LIST_DECL_CLASSES >
130  class MAKE_NAME(Connector) : public MAKE_NAME(IConnector)< LIST_CLASSES > {
131  public:
132  MAKE_NAME(Connector)() {
134  _target_ = NULL;
135  _action_ = NULL;
136  }
137 
139  (TargetClass* target, void (TargetClass::*action)(const void*, LIST_CLASSES)) {
141  _target_ = target;
142  _action_ = action;
143  }
144 
149  }
150 
151  virtual ~MAKE_NAME(Connector)() {
153  ;
154  }
155 
156  INLINE virtual MAKE_NAME(IConnector)< LIST_CLASSES >* clone() {
157  return new MAKE_NAME(Connector)< TargetClass, LIST_CLASSES >(*this);
158  }
159 
162  _action_);
163  }
164 
165  INLINE virtual void notify(const void* src, LIST_DECL_ARGS) {
167  }
168 
169  INLINE virtual Listener* target() const { return _target_; }
170 
171  private:
173  void (TargetClass::*_action_)(const void*, LIST_CLASSES);
174  };
175 
176  } // namespace __sig__
177 
178  template < LIST_DECL_CLASSES >
179  class MAKE_NAME(Signaler) : public __sig__::MAKE_NAME(BasicSignaler)< LIST_CLASSES > {
182 
183  public:
185 
186  MAKE_NAME(Signaler)() {
188  ;
189  }
190 
194  }
195 
196  virtual ~MAKE_NAME(Signaler)() {
198  ;
199  }
200 
201  template < class TargetClass >
202  void attach(TargetClass* target, void (TargetClass::*action)(const void*, LIST_CLASSES)) {
205  this->connectors_.pushBack(conn);
206  target->_attachSignal_(this);
207  }
208 
209  INLINE void operator()(const void* src, LIST_DECL_ARGS) {
210  for (const auto& connector: this->connectors_) {
212  }
213  }
214  };
215 
216 } // namespace gum
217 
218 #endif // DOXYGEN_SHOULD_SKIP_THIS
219 
220 #undef MAKE_NAME
221 #undef LIST_DECL_CLASSES
222 #undef LIST_CLASSES
223 #undef LIST_DECL_ARGS
224 #undef LIST_ARGS
225 #undef SIGNALER_PATRON_ACCEPTED
Internal namespace for aGrUM signaler/listener components.
Definition: agrum.h:28
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643