diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-08-08 11:14:20 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2011-09-14 17:39:11 (GMT) |
commit | aa84c952535a86e797226a2fe3bc5f41248c93c1 (patch) | |
tree | a68a3758b8b5db9369e8c1456cf7fee70768f227 | |
parent | 0a42e6ca3d3c3badf189afda7051676e344d208d (diff) | |
download | fluxbox_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.hh | 36 |
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 | } |
117 | private: | 117 | private: |
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: | |||
231 | class SignalTracker: public SigImpl::SignalHolder::Tracker { | 231 | class SignalTracker: public SigImpl::SignalHolder::Tracker { |
232 | public: | 232 | public: |
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 ) { |