aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-08-08 11:14:20 (GMT)
committerPavel Labath <pavelo@centrum.sk>2011-09-14 17:39:11 (GMT)
commitaa84c952535a86e797226a2fe3bc5f41248c93c1 (patch)
treea68a3758b8b5db9369e8c1456cf7fee70768f227
parent0a42e6ca3d3c3badf189afda7051676e344d208d (diff)
downloadfluxbox_paul-aa84c952535a86e797226a2fe3bc5f41248c93c1.zip
fluxbox_paul-aa84c952535a86e797226a2fe3bc5f41248c93c1.tar.bz2
Enable connecting to const Signals
The idea is that connecting to a signal doesn't change it's state or the state of the object owning the signal (even though it needs to add the functor to the list for later reference). Emitting, on the other hand, is usually done as a result of a state change and therefore remains non-const. Additional benefit of this arrangement is that objects can export const references to signals to allow connecting, while keeping the ability to emit to themselves.
-rw-r--r--src/FbTk/Signal.hh36
1 files changed, 19 insertions, 17 deletions
diff --git a/src/FbTk/Signal.hh b/src/FbTk/Signal.hh
index 6480690..6bf94bc 100644
--- a/src/FbTk/Signal.hh
+++ b/src/FbTk/Signal.hh
@@ -69,7 +69,7 @@ public:
69 } 69 }
70 70
71 /// Remove a specific slot \c id from this signal 71 /// Remove a specific slot \c id from this signal
72 void disconnect(SlotID slotIt) { 72 void disconnect(SlotID slotIt) const {
73 if(m_emitting) { 73 if(m_emitting) {
74 // if we are emitting, we must not erase the actual element, as that would 74 // if we are emitting, we must not erase the actual element, as that would
75 // invalidate iterators in the emit() function 75 // invalidate iterators in the emit() function
@@ -87,11 +87,11 @@ public:
87 m_slots.clear(); 87 m_slots.clear();
88 } 88 }
89 89
90 void connectTracker(SignalHolder::Tracker& tracker) { 90 void connectTracker(SignalHolder::Tracker& tracker) const {
91 m_trackers.insert(&tracker); 91 m_trackers.insert(&tracker);
92 } 92 }
93 93
94 void disconnectTracker(SignalHolder::Tracker& tracker) { 94 void disconnectTracker(SignalHolder::Tracker& tracker) const {
95 m_trackers.erase(&tracker); 95 m_trackers.erase(&tracker);
96 } 96 }
97 97
@@ -103,7 +103,7 @@ protected:
103 Iterator end() { return m_slots.end(); } 103 Iterator end() { return m_slots.end(); }
104 104
105 /// Connect a slot to this signal. Must only be called by child classes. 105 /// Connect a slot to this signal. Must only be called by child classes.
106 SlotID connect(const SlotPtr& slot) { 106 SlotID connect(const SlotPtr& slot) const {
107 return m_slots.insert(m_slots.end(), slot); 107 return m_slots.insert(m_slots.end(), slot);
108 } 108 }
109 109
@@ -116,8 +116,8 @@ protected:
116 } 116 }
117private: 117private:
118 typedef std::set<Tracker*> Trackers; 118 typedef std::set<Tracker*> Trackers;
119 SlotList m_slots; ///< all slots connected to a signal 119 mutable SlotList m_slots; ///< all slots connected to a signal
120 Trackers m_trackers; ///< all instances that tracks this signal. 120 mutable Trackers m_trackers; ///< all instances that tracks this signal.
121 unsigned m_emitting; 121 unsigned m_emitting;
122}; 122};
123 123
@@ -138,13 +138,13 @@ public:
138 } 138 }
139 139
140 template<typename Functor> 140 template<typename Functor>
141 SlotID connect(const Functor& functor) { 141 SlotID connect(const Functor& functor) const {
142 return SignalHolder::connect(SlotPtr( 142 return SignalHolder::connect(SlotPtr(
143 new SlotImpl<Functor, void, Arg1, Arg2, Arg3>(functor) 143 new SlotImpl<Functor, void, Arg1, Arg2, Arg3>(functor)
144 )); 144 ));
145 } 145 }
146 146
147 SlotID connectSlot(const RefCount<FbTk::Slot<void, Arg1, Arg2, Arg3> > &slot) { 147 SlotID connectSlot(const RefCount<FbTk::Slot<void, Arg1, Arg2, Arg3> > &slot) const {
148 return SignalHolder::connect(slot); 148 return SignalHolder::connect(slot);
149 } 149 }
150}; 150};
@@ -163,13 +163,13 @@ public:
163 } 163 }
164 164
165 template<typename Functor> 165 template<typename Functor>
166 SlotID connect(const Functor& functor) { 166 SlotID connect(const Functor& functor) const {
167 return SignalHolder::connect(SlotPtr( 167 return SignalHolder::connect(SlotPtr(
168 new SlotImpl<Functor, void, Arg1, Arg2>(functor) 168 new SlotImpl<Functor, void, Arg1, Arg2>(functor)
169 )); 169 ));
170 } 170 }
171 171
172 SlotID connectSlot(const RefCount<FbTk::Slot<void, Arg1, Arg2> > &slot) { 172 SlotID connectSlot(const RefCount<FbTk::Slot<void, Arg1, Arg2> > &slot) const {
173 return SignalHolder::connect(slot); 173 return SignalHolder::connect(slot);
174 } 174 }
175}; 175};
@@ -188,13 +188,13 @@ public:
188 } 188 }
189 189
190 template<typename Functor> 190 template<typename Functor>
191 SlotID connect(const Functor& functor) { 191 SlotID connect(const Functor& functor) const {
192 return SignalHolder::connect(SlotPtr( 192 return SignalHolder::connect(SlotPtr(
193 new SlotImpl<Functor, void, Arg1>(functor) 193 new SlotImpl<Functor, void, Arg1>(functor)
194 )); 194 ));
195 } 195 }
196 196
197 SlotID connectSlot(const RefCount<FbTk::Slot<void, Arg1> > &slot) { 197 SlotID connectSlot(const RefCount<FbTk::Slot<void, Arg1> > &slot) const {
198 return SignalHolder::connect(slot); 198 return SignalHolder::connect(slot);
199 } 199 }
200}; 200};
@@ -213,13 +213,13 @@ public:
213 } 213 }
214 214
215 template<typename Functor> 215 template<typename Functor>
216 SlotID connect(const Functor& functor) { 216 SlotID connect(const Functor& functor) const {
217 return SignalHolder::connect(SlotPtr( 217 return SignalHolder::connect(SlotPtr(
218 new SlotImpl<Functor, void>(functor) 218 new SlotImpl<Functor, void>(functor)
219 )); 219 ));
220 } 220 }
221 221
222 SlotID connectSlot(const RefCount<FbTk::Slot<void> > &slot) { 222 SlotID connectSlot(const RefCount<FbTk::Slot<void> > &slot) const {
223 return SignalHolder::connect(slot); 223 return SignalHolder::connect(slot);
224 } 224 }
225}; 225};
@@ -231,7 +231,7 @@ public:
231class SignalTracker: public SigImpl::SignalHolder::Tracker { 231class SignalTracker: public SigImpl::SignalHolder::Tracker {
232public: 232public:
233 /// Internal type, do not use. 233 /// Internal type, do not use.
234 typedef std::map<SigImpl::SignalHolder*, 234 typedef std::map<const SigImpl::SignalHolder*,
235 SigImpl::SignalHolder::SlotID> Connections; 235 SigImpl::SignalHolder::SlotID> Connections;
236 typedef Connections::iterator TrackID; ///< \c ID type for join/leave. 236 typedef Connections::iterator TrackID; ///< \c ID type for join/leave.
237 237
@@ -242,7 +242,7 @@ public:
242 /// Starts tracking a signal. 242 /// Starts tracking a signal.
243 /// @return A tracking ID 243 /// @return A tracking ID
244 template<typename Arg1, typename Arg2, typename Arg3, typename Functor> 244 template<typename Arg1, typename Arg2, typename Arg3, typename Functor>
245 TrackID join(Signal<Arg1, Arg2, Arg3> &sig, const Functor &functor) { 245 TrackID join(const Signal<Arg1, Arg2, Arg3> &sig, const Functor &functor) {
246 return joinSlot(sig, RefCount<Slot<void, Arg1, Arg2, Arg3> >( 246 return joinSlot(sig, RefCount<Slot<void, Arg1, Arg2, Arg3> >(
247 new SlotImpl<Functor, void, Arg1, Arg2, Arg3>(functor) 247 new SlotImpl<Functor, void, Arg1, Arg2, Arg3>(functor)
248 )); 248 ));
@@ -250,7 +250,9 @@ public:
250 250
251 template<typename Arg1, typename Arg2, typename Arg3> 251 template<typename Arg1, typename Arg2, typename Arg3>
252 TrackID 252 TrackID
253 joinSlot(Signal<Arg1, Arg2, Arg3> &sig, const RefCount<Slot<void, Arg1, Arg2, Arg3> > &slot) { 253 joinSlot(const Signal<Arg1, Arg2, Arg3> &sig,
254 const RefCount<Slot<void, Arg1, Arg2, Arg3> > &slot) {
255
254 ValueType value = ValueType(&sig, sig.connectSlot(slot)); 256 ValueType value = ValueType(&sig, sig.connectSlot(slot));
255 std::pair<TrackID, bool> ret = m_connections.insert(value); 257 std::pair<TrackID, bool> ret = m_connections.insert(value);
256 if ( !ret.second ) { 258 if ( !ret.second ) {