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_
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>
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>::iterator iterator_type;
48 typedef std::list<slot_base>::const_iterator const_iterator_type;
52 // only MSVC needs this to guarantee that all new/delete are executed from the DLL module
53 #ifdef SIGC_NEW_DELETE_IN_LIBRARY_ONLY
54 void* operator new(size_t size_);
55 void operator delete(void* p);
58 /// Increments the reference counter.
59 inline void reference()
62 /// Increments the reference and execution counter.
63 inline void reference_exec()
64 { ++ref_count_; ++exec_count_; }
66 /** Decrements the reference counter.
67 * The object is deleted when the reference counter reaches zero.
69 inline void unreference()
70 { if (!(--ref_count_)) delete this; }
72 /** Decrements the reference and execution counter.
73 * Invokes sweep() if the execution counter reaches zero and the
74 * removal of one or more slots has been deferred.
76 inline void unreference_exec()
78 if (!(--ref_count_)) delete this;
79 else if (!(--exec_count_) && deferred_) sweep();
82 /** Returns whether the list of slots is empty.
83 * @return @p true if the list of slots is empty.
85 inline bool empty() const
86 { return slots_.empty(); }
88 /// Empties the list of slots.
91 /** Returns the number of slots in the list.
92 * @return The number of slots in the list.
94 size_type size() const;
96 /** Adds a slot at the bottom of the list of slots.
97 * @param slot_ The slot to add to the list of slots.
98 * @return An iterator pointing to the new slot in the list.
100 iterator_type connect(const slot_base& slot_);
102 /** Adds a slot at the given position into the list of slots.
103 * @param i An iterator indicating the position where @p slot_ should be inserted.
104 * @param slot_ The slot to add to the list of slots.
105 * @return An iterator pointing to the new slot in the list.
107 iterator_type insert(iterator_type i, const slot_base& slot_);
109 /** Removes the slot at the given position from the list of slots.
110 * @param i An iterator pointing to the slot to be removed.
111 * @return An iterator pointing to the slot in the list after the one removed.
113 iterator_type erase(iterator_type i);
115 /// Removes invalid slots from the list of slots.
118 /** Callback that is executed when some slot becomes invalid.
119 * This callback is registered in every slot when inserted into
120 * the list of slots. It is executed when a slot becomes invalid
121 * because of some referred object being destroyed.
122 * It either calls sweep() directly or defers the execution of
123 * sweep() when the signal is being emitted.
124 * @param d The signal object (@p this).
126 static void* notify(void* d);
128 /** Reference counter.
129 * The object is destroyed when @em ref_count_ reaches zero.
133 /** Execution counter.
134 * Indicates whether the signal is being emitted.
138 /// Indicates whether the execution of sweep() is being deferred.
141 /// The list of slots.
142 std::list<slot_base> slots_;
145 /// Exception safe sweeper for cleaning up invalid slots on the slot list.
146 struct SIGC_API signal_exec
148 /// The parent sigc::signal_impl object.
151 /** Increments the reference and execution counter of the parent sigc::signal_impl object.
152 * @param sig The parent sigc::signal_impl object.
154 inline signal_exec(const signal_impl* sig)
155 : sig_(const_cast<signal_impl*>(sig) )
156 { sig_->reference_exec(); }
158 /// Decrements the reference and execution counter of the parent sigc::signal_impl object.
159 inline ~signal_exec()
160 { sig_->unreference_exec(); }
163 } /* namespace internal */
166 /** @defgroup signal Signals
167 * Use sigc::signal::connect() with sigc::mem_fun() and sigc::ptr_fun() to connect a method or function with a signal.
170 * signal_clicked.connect( sigc::mem_fun(*this, &MyWindow::on_clicked) );
173 * When the signal is emitted your method will be called.
175 * signal::connect() returns a connection, which you can later use to disconnect your method.
176 * If the type of your object inherits from sigc::trackable the method is disconnected
177 * automatically when your object is destroyed.
179 * When signals are copied they share the underlying information,
180 * so you can have a protected/private sigc::signal member and a public accessor method.
182 * signal and slot objects provide the core functionality of this
183 * library. A slot is a container for an arbitrary functor.
184 * A signal is a list of slots that are executed on emission.
185 * For compile time type safety a list of template arguments
186 * must be provided for the signal template that determines the
187 * parameter list for emission. Functors and closures are converted
188 * into slots implicitely on connection, triggering compiler errors
189 * if the given functor or closure cannot be invoked with the
190 * parameter list of the signal to connect to.
193 /** Base class for the sigc::signal# templates.
194 * signal_base integrates most of the interface of the derived sigc::signal#
195 * templates. The implementation, however, resides in sigc::internal::signal_impl.
196 * A sigc::internal::signal_impl object is dynamically allocated from signal_base
197 * when first connecting a slot to the signal. This ensures that empty signals
198 * don't waste memory.
202 struct SIGC_API signal_base : public trackable
204 typedef size_t size_type;
208 signal_base(const signal_base& src);
212 signal_base& operator = (const signal_base& src);
214 /** Returns whether the list of slots is empty.
215 * @return @p true if the list of slots is empty.
217 inline bool empty() const
218 { return (!impl_ || impl_->empty()); }
220 /// Empties the list of slots.
223 /** Returns the number of slots in the list.
224 * @return The number of slots in the list.
226 size_type size() const;
229 typedef internal::signal_impl::iterator_type iterator_type;
231 /** Adds a slot at the bottom of the list of slots.
232 * @param slot_ The slot to add to the list of slots.
233 * @return An iterator pointing to the new slot in the list.
235 iterator_type connect(const slot_base& slot_);
237 /** Adds a slot at the given position into the list of slots.
238 * @param i An iterator indicating the position where @e slot_ should be inserted.
239 * @param slot_ The slot to add to the list of slots.
240 * @return An iterator pointing to the new slot in the list.
242 iterator_type insert(iterator_type i, const slot_base& slot_);
244 /** Removes the slot at the given position from the list of slots.
245 * @param i An iterator pointing to the slot to be removed.
246 * @return An iterator pointing to the slot in the list after the one removed.
248 iterator_type erase(iterator_type i);
250 /** Returns the signal_impl object encapsulating the list of slots.
251 * @return The signal_impl object encapsulating the list of slots.
253 internal::signal_impl* impl() const;
255 /// The signal_impl object encapsulating the slot list.
256 mutable internal::signal_impl* impl_;
261 #endif /* _SIGC_SIGNAL_BASE_H_ */