Itasca C++ Interface
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
signal2.h
Go to the documentation of this file.
1 #pragma once
2 
6 #include "isignalbase.h"
7 
8 namespace itasca {
33  template <class Param1,class Param2> class Signal2 : public ISignalBase {
34  public:
35 
38 
40  Signal2() { }
41  Signal2(const Signal2 &) = delete;
42  Signal2(Signal2 &&) = delete;
43  void operator=(const Signal2 &) = delete;
44  void operator=(Signal2 &&) = delete;
45 
46 
49  virtual ~Signal2();
50 
55  virtual void execute(Param1,Param2);
56 
62  virtual void attach(SlotType *,const QString &);
63 
70  bool remove(ISlotBase *slot,const QString &name=QString());
71 
74  virtual void attachNotice(ISignalBase *signal);
77  virtual void removeNotice(ISignalBase *signal);
78 
79  // Creates a SlotType implementation that calls the method MFP on instance t of class T, using two arguments.
80  // T must be derived from ISlotBase.
85  template <class T,void (T::*MFP)(Param1,Param2)>
86  void attachMethod2(T *t) {
87  AutoSlot2<T,MFP> *s = NEW("AutoSlot") AutoSlot2<T,MFP>(t);
88  attach(s,typeid(*s).name());
89  }
90 
91  // Creates a SlotType implementation that calls the method MFP on instance t of class T, using one argument.
92  // T must be derived from ISlotBase.
97  template <class T,void (T::*MFP)(Param1)>
98  void attachMethod1(T *t) {
99  AutoSlot1<T,MFP> *s = NEW("AutoSlot") AutoSlot1<T,MFP>(t);
100  attach(s,typeid(*s).name());
101  }
102 
103  // Creates a SlotType implementation that calls the method MFP on instance t of class T, using no arguments.
104  // T must be derived from ISlotBase.
109  template <class T,void (T::*MFP)()>
110  void attachMethod0(T *t) {
111  AutoSlot0<T,MFP> *s = NEW("AutoSlot") AutoSlot0<T,MFP>(t);
112  attach(s,typeid(*s).name());
113  }
114 
115  // Removes a slot connection created to method MFP on instance to of class T, using two arguments.
119  template <class T,void (T::*MFP)(Param1,Param2)>
120  void removeMethod2(T *t) {
121  AutoSlot2<T,MFP> s = AutoSlot2<T,MFP>(t);
122  remove(t,typeid(s).name());
123  }
124 
125  // Removes a slot connection created to method MFP on instance to of class T, using one argument.
129  template <class T,void (T::*MFP)(Param1)>
130  void removeMethod1(T *t) {
131  AutoSlot1<T,MFP> s = AutoSlot1<T,MFP>(t);
132  remove(t,typeid(s).name());
133  }
134 
135  // Removes a slot connection created to method MFP on instance to of class T, using no arguments.
139  template <class T,void (T::*MFP)()>
140  void removeMethod0(T *t) {
141  AutoSlot0<T,MFP> s = AutoSlot0<T,MFP>(t);
142  remove(t,typeid(s).name());
143  }
144 
145  // Attaches a signal (same two arguments) to this signal, as a slot, causing the signals to chain.
151  attachMethod2<Signal2<Param1,Param2>,&Signal2<Param1,Param2>::execute>(sig);
152  }
153 
154  // Removes a signal previously attached
158  removeMethod2<Signal2<Param1,Param2>,&Signal2<Param1,Param2>::execute>(sig);
159  }
160 
161  private:
162  typedef QMultiMap<QString,SlotType *> SlotMap;
163  QList<ISignalBase *> signals_;
164  SlotMap map_;
165 
166  // Derived from SlotType - used when a method is attached via attachMethod2().
167  template <class T,void (T::*MFP)(Param1,Param2)> class AutoSlot2 : public SlotType {
168  public:
169  AutoSlot2(T *t) : t_(t) { assert(t_); }
170  virtual void execute(Param1 v1,Param2 v2) {
171  assert(t_);
172  (t_->*MFP)(v1,v2);
173  }
174  virtual ISlotBase *getBase() { return t_; }
175  private:
176  T *t_;
177  };
178 
179  // Derived from SlotType - used when a method is attached via attachMethod1().
180  template <class T,void (T::*MFP)(Param1)> class AutoSlot1 : public SlotType {
181  public:
182  AutoSlot1(T *t) : t_(t) { assert(t_); }
183  virtual void execute(Param1 v1,Param2) {
184  assert(t_);
185  (t_->*MFP)(v1);
186  }
187  virtual ISlotBase *getBase() { return t_; }
188  private:
189  T *t_;
190  };
191 
192  // Derived from SlotType - used when a method is attached via attachMethod0().
193  template <class T,void (T::*MFP)()> class AutoSlot0 : public SlotType {
194  public:
195  AutoSlot0(T *t) : t_(t) { assert(t_); }
196  virtual void execute(Param1,Param2) {
197  assert(t_);
198  (t_->*MFP)();
199  }
200  virtual ISlotBase *getBase() { return t_; }
201  private:
202  T *t_;
203  };
204  };
205 
206  template <class Param1,class Param2>
208  while (signals_.size()) {
209  ISignalBase *base = signals_.last();
210  base->remove(this);
211  }
212  while (map_.size()) {
213  typename SlotMap::iterator it = map_.begin();
214  SlotType *slot = it.value();
215  map_.erase(it);
216  slot->getBase()->removeNotice(this);
217  delete slot;
218  }
219  }
220 
221  template <class Param1,class Param2>
222  void Signal2<Param1,Param2>::execute(Param1 v1,Param2 v2) {
223  for (typename SlotMap::iterator it=map_.begin();it!=map_.end();++it)
224  it.value()->execute(v1,v2);
225  }
226 
227  template <class Param1,class Param2>
228  void Signal2<Param1,Param2>::attach(SlotType *slot,const QString &name) {
229  assert(slot);
230  map_.insert(name,slot);
231  slot->getBase()->attachNotice(this);
232  }
233 
234  template <class Param1,class Param2>
235  bool Signal2<Param1,Param2>::remove(ISlotBase *slot,const QString &name) {
236  if (slot && name.length()) { // First first entry
237  for (typename SlotMap::iterator it=map_.find(name);it!=map_.end() && it.key()==name;++it) {
238  SlotType *st = it.value();
239  if (st->getBase()==slot) {
240  map_.erase(it);
241  st->getBase()->removeNotice(this);
242  delete st;
243  return true;
244  }
245  }
246  return false;
247  }
248  if (slot) { // Remove all entries matching that slot base
249  QList<QPair<QString,SlotType *> > toRemove;
250  for (typename SlotMap::iterator it=map_.begin();it!=map_.end();++it) {
251  if (it.value()->getBase()==slot)
252  toRemove.push_back(QPair<QString,SlotType *>(it.key(),it.value()));
253  }
254  for (int i=0;i<toRemove.size();++i) {
255  QPair<QString,SlotType *> &p = toRemove[i];
256  map_.remove(p.first,p.second);
257  p.second->getBase()->removeNotice(this);
258  delete p.second;
259  }
260  return toRemove.size() ? true : false;
261  }
262  if (name.length()) { // Remove all slots with matching name
263  QList<QPair<QString,SlotType *> > toRemove;
264  for (typename SlotMap::iterator it=map_.find(name);it!=map_.end() && it.key()==name;++it)
265  toRemove.push_back(QPair<QString,SlotType *>(it.key(),it.value()));
266  for (int i=0;i<toRemove.size();++i) {
267  QPair<QString,SlotType *> &p = toRemove[i];
268  map_.remove(p.first,p.second);
269  p.second->getBase()->removeNotice(this);
270  delete p.second;
271  }
272  return toRemove.size() ? true : false;
273  }
274  // Remove all slots
275  while (map_.size()) {
276  typename SlotMap::iterator it = map_.begin();
277  SlotType *slotType = it.value();
278  map_.erase(it);
279  slotType->getBase()->removeNotice(this);
280  delete slotType;
281  }
282  return true;
283  }
284 
285  template <class Param1,class Param2>
287  signals_.push_back(signal);
288  }
289 
290  template <class Param1,class Param2>
292  int i = signals_.indexOf(signal);
293  if (i<0) return;
294  signals_.removeAt(i);
295  }
296 } // namespace Itasca
297 // Eof
virtual void execute(Param1, Param2)
Definition: signal2.h:222
namespace Itasca
Definition: basememory.cpp:9
Definition of a Signal2 object, holding a list of ISlot2 objects.
Definition: isignalbase.h:76
Signal base class.
Definition: isignalbase.h:44
virtual ~Signal2()
Definition: signal2.h:207
void attachMethod0(T *t)
Definition: signal2.h:110
void removeSignal(Signal2< Param1, Param2 > *sig)
Definition: signal2.h:157
virtual void attachNotice(ISignalBase *signal)=0
virtual void removeNotice(ISignalBase *signal)=0
Interface for the small-granularity callback utility.
Slot base class.
Definition: isignalbase.h:23
void attachSignal(Signal2< Param1, Param2 > *sig)
Definition: signal2.h:150
void removeMethod2(T *t)
Definition: signal2.h:120
virtual void attachNotice(ISignalBase *signal)
Definition: signal2.h:286
void removeMethod1(T *t)
Definition: signal2.h:130
ISlot2 interface - a two-argument class.
Definition: isignalbase.h:66
void attachMethod2(T *t)
Definition: signal2.h:86
virtual bool remove(ISlotBase *slot, const QString &name=QString())=0
ISlot2< Param1, Param2 > SlotType
Define SlotType as an ISlot2 object with template arguments Param1 and Param2.
Definition: signal2.h:37
void attachMethod1(T *t)
Definition: signal2.h:98
void removeMethod0(T *t)
Definition: signal2.h:140
Signal2()
Default constructor - no values are set.
Definition: signal2.h:40
virtual void removeNotice(ISignalBase *signal)
Definition: signal2.h:291
virtual void attach(SlotType *, const QString &)
Definition: signal2.h:228
virtual ISlotBase * getBase()=0
Returns the ISlotBase pointer to the base class from which this ISlot2 is derived.
bool remove(ISlotBase *slot, const QString &name=QString())
Definition: signal2.h:235