aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
signaler0.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 Class of gum::Signaler0.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  *
28  */
29 
30 #ifndef GUM_SIGNALER0_H
31 #define GUM_SIGNALER0_H
32 #include <functional>
33 
34 #include <agrum/agrum.h>
35 #include <agrum/tools/core/list.h>
36 #include <agrum/tools/core/signal/signaler.h>
37 
38 namespace gum {
39 
40 #ifndef DOXYGEN_SHOULD_SKIP_THIS
41 
42  namespace __sig__ {
43 
44  class IConnector0 {
45  public:
46  virtual ~IConnector0(){};
47 
48  virtual Listener* target() const = 0;
49  virtual void notify(const void*) = 0;
50  virtual IConnector0* clone() = 0;
51  virtual IConnector0* duplicate(Listener* target) = 0;
52  };
53 
54  class BasicSignaler0: public ISignaler {
55  protected:
56  typedef std::vector< IConnector0* > ConnectorList;
57 
58  BasicSignaler0();
59 
60  BasicSignaler0(const BasicSignaler0& s);
61 
62  public:
63  virtual ~BasicSignaler0();
64 
65  bool hasListener();
66 
67  void detach(Listener* target);
68 
69  protected:
70  friend class Listener;
71 
72  void detachFromTarget_(Listener* target);
73 
74  void duplicateTarget_(const Listener* oldtarget, Listener* newtarget);
75 
76  ConnectorList connectors_;
77 
78  private:
79  std::function< bool(IConnector0* el) > _find_target_(const gum::Listener* l);
80  };
81 
82  template < class TargetClass >
83  class Connector0: public IConnector0 {
84  public:
85  Connector0();
86 
87  Connector0(TargetClass* target, void (TargetClass::*action)(const void*));
88 
89  Connector0(const Connector0< TargetClass >* src);
90 
91  virtual ~Connector0();
92 
93  virtual IConnector0* clone();
94 
95  virtual IConnector0* duplicate(Listener* target);
96 
97  virtual void notify(const void* src);
98 
99  virtual Listener* target() const;
100 
101  private:
102  TargetClass* _target_;
103  void (TargetClass::*_action_)(const void*);
104  };
105 
106  } // namespace __sig__
107 
108 #endif // DOXYGEN_SHOULD_SKIP_THIS
109 
110  /**
111  * @class Signaler0
112  * @ingroup signal_group
113  * @brief class for signal with 0 args
114  * @warning Due to the too-smart-way-for-DOXYGEN of building classes
115  * Signaler1,...,Signaler_n, these classes are not documented.
116  */
117  class Signaler0: public __sig__::BasicSignaler0 {
118  public:
120  GUM_CONSTRUCTOR(Signaler0);
121  ;
122  }
123 
124  Signaler0(const Signaler0& s) : __sig__::BasicSignaler0(s) { GUM_CONS_CPY(Signaler0); }
125 
126  virtual ~Signaler0() {
127  GUM_DESTRUCTOR(Signaler0);
128  ;
129  }
130 
131  template < class TargetClass >
132  void attach(TargetClass* target, void (TargetClass::*action)(const void*)) {
133  __sig__::Connector0< TargetClass >* conn
134  = new __sig__::Connector0< TargetClass >(target, action);
135  this->connectors_.push_back(conn);
136  target->_attachSignal_(this);
137  }
138 
139  INLINE void operator()(const void* src) {
140  for (const auto el: connectors_) {
141  el->notify(src);
142  }
143  }
144  };
145 
146 } // namespace gum
147 
148 /// this macro is the good way of emitting a signal.
149 #define GUM_EMIT0(signal) this->signal(this)
150 
151 // Template implementation should always be in headers
152 #include <agrum/tools/core/signal/signaler0_tpl.h>
153 
154 #ifndef GUM_NO_INLINE
155 # include <agrum/tools/core/signal/signaler0_inl.h>
156 #endif // GUM_NO_INLINE
157 
158 #endif // GUM_SIGNALER0_H
Internal namespace for aGrUM signaler/listener components.
Definition: agrum.h:28
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
virtual ~Signaler0()
Definition: signaler0.h:126
void attach(TargetClass *target, void(TargetClass::*action)(const void *))
Definition: signaler0.h:132
Signaler0(const Signaler0 &s)
Definition: signaler0.h:124
INLINE void operator()(const void *src)
Definition: signaler0.h:139