Slot.h
1 /*
2  * Copyright (C) 2008 Marc Boris Duerner
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #ifndef Pt_Slot_h
30 #define Pt_Slot_h
31 
32 #include <Pt/Api.h>
33 #include <Pt/Void.h>
34 #include <Pt/Callable.h>
35 
36 namespace Pt {
37 
38 class Connection;
39 
40 class Slot
41 {
42  public:
43  virtual ~Slot() {}
44 
45  virtual Slot* clone() const = 0;
46 
47  virtual const void* callable() const = 0;
48 
49  virtual void onConnect(const Connection& c) = 0;
50 
51  virtual void onDisconnect(const Connection& c) = 0;
52 
53  virtual bool equals(const Slot& slot) const = 0;
54 };
55 
56 template < typename R, typename A1 = Void, typename A2 = Void,
57  typename A3 = Void, typename A4 = Void,
58  typename A5 = Void, typename A6 = Void,
59  typename A7 = Void, typename A8 = Void,
60  typename A9 = Void, typename A10 = Void >
61 class BasicSlot : public Slot
62 {
63  public:
64  virtual Slot* clone() const = 0;
65 };
66 
67 
68 template <typename T>
69 class BindAdaptorBase
70 {
71  public:
72  BindAdaptorBase(const Slot& s, const T& a)
73  : _slot( s.clone() )
74  , _a(a)
75  { }
76 
77  BindAdaptorBase(const BindAdaptorBase& c)
78  : _slot( c._slot->clone() )
79  , _a(c._a)
80  { }
81 
82  ~BindAdaptorBase()
83  { delete _slot; }
84 
85  BindAdaptorBase& operator=(const BindAdaptorBase& b)
86  {
87  if(this == &b)
88  return *this;
89 
90  Slot* s = b.slot().clone();
91  delete _slot;
92  _slot = s;
93 
94  _a = b.a;
95  return *this;
96  }
97 
98  Slot& slot()
99  { return *_slot; }
100 
101  const Slot& slot() const
102  { return *_slot; }
103 
104  const T& arg() const
105  { return _a; }
106 
107  private:
108  Slot* _slot;
109  T _a;
110 };
111 
112 
113 template <typename R, typename A1,
114  typename A2 = Void, typename A3 = Void,
115  typename A4 = Void>
116 class BindAdaptor : public Callable<R, A1, A2, A3>
117  , public BindAdaptorBase<A4>
118 {
119  public:
120  typedef BasicSlot<R, A1, A2, A3> SlotBase;
121 
122  public:
123  BindAdaptor(const BasicSlot<R, A1, A2, A3, A4>& slot, const A4& a)
124  : BindAdaptorBase<A4>(slot, a)
125  { }
126 
127  virtual Callable<R, A1, A2, A3>* clone() const
128  { return new BindAdaptor(*this); }
129 
130  virtual R operator()(A1 a1, A2 a2, A3 a3) const
131  {
132  const Callable<R, A1, A2, A3, A4>* cb =
133  static_cast< const Callable<R, A1, A2, A3, A4>* >( this->slot().callable() );
134 
135  return cb->call( a1, a2, a3, this->arg() );
136  }
137 };
138 
139 
140 template <typename R, typename A1,
141  typename A2, typename A3>
142 class BindAdaptor<R, A1, A2, A3, Void> : public Callable<R, A1, A2>
143  , public BindAdaptorBase<A3>
144 {
145  public:
146  typedef BasicSlot<R, A1, A2> SlotBase;
147 
148  public:
149  BindAdaptor(const BasicSlot<R, A1, A2, A3>& slot, const A3& a)
150  : BindAdaptorBase<A3>(slot, a)
151  { }
152 
153  virtual Callable<R, A1, A2>* clone() const
154  { return new BindAdaptor(*this); }
155 
156  virtual R operator()(A1 a1, A2 a2) const
157  {
158  const Callable<R, A1, A2, A3>* cb =
159  static_cast< const Callable<R, A1, A2, A3>* >( this->slot().callable() );
160 
161  return cb->call( a1, a2, this->arg() );
162  }
163 };
164 
165 
166 
167 template <typename R, typename A1, typename A2>
168 class BindAdaptor<R, A1, A2, Void, Void> : public Callable<R, A1>
169  , public BindAdaptorBase<A2>
170 {
171  public:
172  typedef BasicSlot<R, A1> SlotBase;
173 
174  public:
175  BindAdaptor(const BasicSlot<R, A1, A2>& slot, const A2& a)
176  : BindAdaptorBase<A2>(slot, a)
177  { }
178 
179  virtual Callable<R, A1>* clone() const
180  { return new BindAdaptor(*this); }
181 
182  virtual R operator()(A1 a1) const
183  {
184  const Callable<R, A1, A2>* cb =
185  static_cast< const Callable<R, A1, A2>* >( this->slot().callable() );
186 
187  return cb->call( a1, this->arg() );
188  }
189 };
190 
191 
192 template <typename R, typename A1>
193 class BindAdaptor<R, A1, Void, Void, Void> : public Callable<R>
194  , public BindAdaptorBase<A1>
195 {
196  public:
197  typedef BasicSlot<R> SlotBase;
198 
199  public:
200  BindAdaptor(const BasicSlot<R, A1>& slot, const A1& a)
201  : BindAdaptorBase<A1>(slot, a)
202  { }
203 
204  virtual Callable<R>* clone() const
205  { return new BindAdaptor(*this); }
206 
207  virtual R operator()() const
208  {
209  const Callable<R, A1>* cb =
210  static_cast< const Callable<R, A1>* >( this->slot().callable() );
211 
212  return cb->call( this->arg() );
213  }
214 };
215 
216 
217 template <typename R, typename A1, typename A2, typename A3, typename A4>
218 class BoundSlot : public BindAdaptor<R, A1, A2, A3, A4>::SlotBase
219 {
220  public:
221  template <typename T>
222  BoundSlot(const BasicSlot<R, A1, A2, A3, A4>& slot, const T& a)
223  : _adaptor(slot, a)
224  { }
225 
226  Slot* clone() const
227  {
228  return new BoundSlot(*this);
229  }
230 
231  virtual const void* callable() const
232  {
233  return &_adaptor;
234  }
235 
236  virtual void onConnect(const Connection& c)
237  {
238  _adaptor.slot().onConnect(c);
239  }
240 
241  virtual void onDisconnect(const Connection& c)
242  {
243  _adaptor.slot().onDisconnect(c);
244  }
245 
246  virtual bool equals(const Slot& slot) const
247  {
248  return _adaptor.slot().equals(slot);
249  }
250 
251  private:
252  BindAdaptor<R, A1, A2, A3, A4> _adaptor;
253 };
254 
255 
256 template < typename R, typename A1, typename A2, typename A3, typename A4, typename T>
257 BoundSlot<R, A1, A2, A3, A4> slot(const BasicSlot<R, A1, A2, A3, A4>& slot, const T& a)
258 {
259  return BoundSlot<R, A1, A2, A3, A4>(slot, a);
260 }
261 
262 } // namespace Pt
263 
264 #endif
virtual Slot * clone() const =0
Clone this object with new.
Endpoint of a signal/slot connection.
Definition: Slot.h:21
Represents a connection between a Signal/Delegate and a slot.
Definition: Connection.h:90
virtual Slot * clone() const =0
Clone this object with new.
virtual ~Slot()
Destructor.
Definition: Slot.h:25
virtual bool equals(const Slot &slot) const =0
Returns true if two slots are equal in value.
virtual R operator()(A1) const =0
Call the callable entity.
virtual void onConnect(const Connection &c)=0
Notifies of connects.
Base type for various "slot" types.
Definition: Slot.h:47
Void type.
Definition: Void.h:43
virtual const void * callable() const =0
Returns a pointer to the contained callable.
ConstMethodSlot< R, C, ARGS > slot(C &obj, R(BaseT::*memFunc)(ARGS) const )
Returns a slot object for the given object/member pair.
virtual void onDisconnect(const Connection &c)=0
Notifies of disconnects.