when setting a redirect box to display a given route's redirects, always unset the...
[ardour2.git] / libs / sigc++2 / sigc++ / signal_base.h
blob582a8f4943bd82b9f8d77a560bfe48503f0cfeba
1 // -*- c++ -*-
2 /*
3 * Copyright 2002, The libsigc++ Development Team
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef _SIGC_SIGNAL_BASE_H_
22 #define _SIGC_SIGNAL_BASE_H_
24 #include <list>
25 #include <sigc++config.h>
26 #include <sigc++/type_traits.h>
27 #include <sigc++/trackable.h>
28 #include <sigc++/functors/slot.h>
29 #include <sigc++/functors/mem_fun.h>
31 namespace sigc
34 namespace internal
37 /** Implementation of the signal interface.
38 * signal_impl manages a list of slots. When a slot becomes
39 * invalid (because some referred object dies), notify() is executed.
40 * notify() either calls sweep() directly or defers the execution of
41 * sweep() when the signal is being emitted. sweep() removes all
42 * invalid slot from the list.
44 struct SIGC_API signal_impl
46 typedef size_t size_type;
47 typedef std::list<slot_base> slot_list;
48 typedef slot_list::iterator iterator_type;
49 typedef slot_list::const_iterator const_iterator_type;
51 signal_impl();
53 // only MSVC needs this to guarantee that all new/delete are executed from the DLL module
54 #ifdef SIGC_NEW_DELETE_IN_LIBRARY_ONLY
55 void* operator new(size_t size_);
56 void operator delete(void* p);
57 #endif
59 /// Increments the reference counter.
60 inline void reference()
61 { ++ref_count_; }
63 /// Increments the reference and execution counter.
64 inline void reference_exec()
65 { ++ref_count_; ++exec_count_; }
67 /** Decrements the reference counter.
68 * The object is deleted when the reference counter reaches zero.
70 inline void unreference()
71 { if (!(--ref_count_)) delete this; }
73 /** Decrements the reference and execution counter.
74 * Invokes sweep() if the execution counter reaches zero and the
75 * removal of one or more slots has been deferred.
77 inline void unreference_exec()
79 if (!(--ref_count_)) delete this;
80 else if (!(--exec_count_) && deferred_) sweep();
83 /** Returns whether the list of slots is empty.
84 * @return @p true if the list of slots is empty.
86 inline bool empty() const
87 { return slots_.empty(); }
89 /// Empties the list of slots.
90 void clear();
92 /** Returns the number of slots in the list.
93 * @return The number of slots in the list.
95 size_type size() const;
97 /** Adds a slot at the bottom of the list of slots.
98 * @param slot_ The slot to add to the list of slots.
99 * @return An iterator pointing to the new slot in the list.
101 iterator_type connect(const slot_base& slot_);
103 /** Adds a slot at the given position into the list of slots.
104 * @param i An iterator indicating the position where @p slot_ should be inserted.
105 * @param slot_ The slot to add to the list of slots.
106 * @return An iterator pointing to the new slot in the list.
108 iterator_type insert(iterator_type i, const slot_base& slot_);
110 /** Removes the slot at the given position from the list of slots.
111 * @param i An iterator pointing to the slot to be removed.
112 * @return An iterator pointing to the slot in the list after the one removed.
114 iterator_type erase(iterator_type i);
116 /// Removes invalid slots from the list of slots.
117 void sweep();
119 /** Callback that is executed when some slot becomes invalid.
120 * This callback is registered in every slot when inserted into
121 * the list of slots. It is executed when a slot becomes invalid
122 * because of some referred object being destroyed.
123 * It either calls sweep() directly or defers the execution of
124 * sweep() when the signal is being emitted.
125 * @param d The signal object (@p this).
127 static void* notify(void* d);
129 /** Reference counter.
130 * The object is destroyed when @em ref_count_ reaches zero.
132 short ref_count_;
134 /** Execution counter.
135 * Indicates whether the signal is being emitted.
137 short exec_count_;
139 /// Indicates whether the execution of sweep() is being deferred.
140 bool deferred_;
142 /// The list of slots.
143 std::list<slot_base> slots_;
146 /// Exception safe sweeper for cleaning up invalid slots on the slot list.
147 struct SIGC_API signal_exec
149 /// The parent sigc::signal_impl object.
150 signal_impl* sig_;
152 /** Increments the reference and execution counter of the parent sigc::signal_impl object.
153 * @param sig The parent sigc::signal_impl object.
155 inline signal_exec(const signal_impl* sig)
156 : sig_(const_cast<signal_impl*>(sig) )
157 { sig_->reference_exec(); }
159 /// Decrements the reference and execution counter of the parent sigc::signal_impl object.
160 inline ~signal_exec()
161 { sig_->unreference_exec(); }
164 /** Temporary slot list used during signal emission.
165 * Through evolution this class is slightly misnamed. It is now
166 * an index into the slot_list passed into it. It simply keeps track
167 * of where the end of this list was at construction, and pretends that's
168 * the end of your list. This way you may connect during emittion without
169 * inadvertently entering an infinite loop, as well as make other
170 * modifications to the slot_list at your own risk.
172 struct temp_slot_list
174 typedef signal_impl::slot_list slot_list;
175 typedef signal_impl::iterator_type iterator;
176 typedef signal_impl::const_iterator_type const_iterator;
178 temp_slot_list(slot_list &slots) : slots_(slots)
180 placeholder = slots_.insert(slots_.end(), slot_base());
183 ~temp_slot_list()
185 slots_.erase(placeholder);
188 iterator begin() { return slots_.begin(); }
189 iterator end() { return placeholder; }
190 const_iterator begin() const { return slots_.begin(); }
191 const_iterator end() const { return placeholder; }
193 private:
194 slot_list &slots_;
195 slot_list::iterator placeholder;
198 } /* namespace internal */
201 /** @defgroup signal Signals
202 * Use sigc::signal::connect() with sigc::mem_fun() and sigc::ptr_fun() to connect a method or function with a signal.
204 * @code
205 * signal_clicked.connect( sigc::mem_fun(*this, &MyWindow::on_clicked) );
206 * @endcode
208 * When the signal is emitted your method will be called.
210 * signal::connect() returns a connection, which you can later use to disconnect your method.
211 * If the type of your object inherits from sigc::trackable the method is disconnected
212 * automatically when your object is destroyed.
214 * When signals are copied they share the underlying information,
215 * so you can have a protected/private sigc::signal member and a public accessor method.
217 * signal and slot objects provide the core functionality of this
218 * library. A slot is a container for an arbitrary functor.
219 * A signal is a list of slots that are executed on emission.
220 * For compile time type safety a list of template arguments
221 * must be provided for the signal template that determines the
222 * parameter list for emission. Functors and closures are converted
223 * into slots implicitely on connection, triggering compiler errors
224 * if the given functor or closure cannot be invoked with the
225 * parameter list of the signal to connect to.
228 /** Base class for the sigc::signal# templates.
229 * signal_base integrates most of the interface of the derived sigc::signal#
230 * templates. The implementation, however, resides in sigc::internal::signal_impl.
231 * A sigc::internal::signal_impl object is dynamically allocated from signal_base
232 * when first connecting a slot to the signal. This ensures that empty signals
233 * don't waste memory.
235 * @ingroup signal
237 struct SIGC_API signal_base : public trackable
239 typedef size_t size_type;
241 signal_base();
243 signal_base(const signal_base& src);
245 ~signal_base();
247 signal_base& operator = (const signal_base& src);
249 /** Returns whether the list of slots is empty.
250 * @return @p true if the list of slots is empty.
252 inline bool empty() const
253 { return (!impl_ || impl_->empty()); }
255 /// Empties the list of slots.
256 void clear();
258 /** Returns the number of slots in the list.
259 * @return The number of slots in the list.
261 size_type size() const;
263 protected:
264 typedef internal::signal_impl::iterator_type iterator_type;
266 /** Adds a slot at the end of the list of slots.
267 * With connect(), slots can also be added during signal emission.
268 * In this case, they won't be executed until the next emission occurs.
269 * @param slot_ The slot to add to the list of slots.
270 * @return An iterator pointing to the new slot in the list.
272 iterator_type connect(const slot_base& slot_);
274 /** Adds a slot at the given position into the list of slots.
275 * Note that this function does not work during signal emission!
276 * @param i An iterator indicating the position where @e slot_ should be inserted.
277 * @param slot_ The slot to add to the list of slots.
278 * @return An iterator pointing to the new slot in the list.
280 iterator_type insert(iterator_type i, const slot_base& slot_);
282 /** Removes the slot at the given position from the list of slots.
283 * Note that this function does not work during signal emission!
284 * @param i An iterator pointing to the slot to be removed.
285 * @return An iterator pointing to the slot in the list after the one removed.
287 iterator_type erase(iterator_type i);
289 /** Returns the signal_impl object encapsulating the list of slots.
290 * @return The signal_impl object encapsulating the list of slots.
292 internal::signal_impl* impl() const;
294 /// The signal_impl object encapsulating the slot list.
295 mutable internal::signal_impl* impl_;
298 } //namespace sigc
300 #endif /* _SIGC_SIGNAL_BASE_H_ */