aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
signaler_with_args.pattern.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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  = 0;
52  };
53 
54  template < LIST_DECL_CLASSES >
55  class MAKE_NAME(BasicSignaler) : public ISignaler {
56  protected:
60 
62 
64  (const MAKE_NAME(BasicSignaler) & s) : ISignaler(s) {
66 
67  for (const auto& connector: connectors_) {
70  }
71  }
72 
73  public:
74  virtual ~MAKE_NAME(BasicSignaler)() {
76 
77  for (const auto& connector: connectors_) {
79  delete connector;
80  }
81 
83  }
84 
85  bool hasListener() { return (!(connectors_.empty())); }
86 
87  void detach(Listener* target) {
89  = 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
115  = connectors_.rbeginSafe(); // safe iterator needed here
116  it != connectors_.rendSafe();) {
117  itprev = it;
118  --it;
119 
120  if ((*itprev)->target() == target) {
121  delete *itprev;
123  }
124  }
125  }
126 
128  };
129 
130  template < class TargetClass, LIST_DECL_CLASSES >
131  class MAKE_NAME(Connector) : public MAKE_NAME(IConnector)< LIST_CLASSES > {
132  public:
133  MAKE_NAME(Connector)() {
135  target__ = NULL;
136  action__ = NULL;
137  }
138 
141  void (TargetClass::*action)(const void*, LIST_CLASSES)) {
143  target__ = target;
144  action__ = action;
145  }
146 
151  }
152 
154 
155  INLINE virtual MAKE_NAME(IConnector)< LIST_CLASSES >* clone() {
156  return new MAKE_NAME(Connector)< TargetClass, LIST_CLASSES >(*this);
157  }
158 
160  Listener* target) {
161  return new MAKE_NAME(
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) :
181  typedef typename __sig__::MAKE_NAME(
183 
184  public:
186 
188 
190  (const MAKE_NAME(Signaler) & s) :
193  }
194 
196 
197  template < class TargetClass >
198  void attach(TargetClass* target,
199  void (TargetClass::*action)(const void*, LIST_CLASSES)) {
202  action);
203  this->connectors_.pushBack(conn);
204  target->attachSignal__(this);
205  }
206 
207  INLINE void operator()(const void* src, LIST_DECL_ARGS) {
208  for (const auto& connector: this->connectors_) {
210  }
211  }
212  };
213 
214 } // namespace gum
215 
216 #endif // DOXYGEN_SHOULD_SKIP_THIS
217 
218 #undef MAKE_NAME
219 #undef LIST_DECL_CLASSES
220 #undef LIST_CLASSES
221 #undef LIST_DECL_ARGS
222 #undef LIST_ARGS
223 #undef SIGNALER_PATRON_ACCEPTED
Internal namespace for aGrUM signaler/listener components.
Definition: agrum.h:28
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669