// Boost.Signals library | |
// Copyright Douglas Gregor 2001-2004. Use, modification and | |
// distribution is subject to the Boost Software License, Version | |
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
// For more information, see http://www.boost.org | |
#ifndef BOOST_SIGNALS_SIGNAL_BASE_HEADER | |
#define BOOST_SIGNALS_SIGNAL_BASE_HEADER | |
#include <boost/signals/detail/config.hpp> | |
#include <boost/signals/detail/signals_common.hpp> | |
#include <boost/signals/detail/named_slot_map.hpp> | |
#include <boost/signals/connection.hpp> | |
#include <boost/signals/trackable.hpp> | |
#include <boost/signals/slot.hpp> | |
#include <boost/smart_ptr.hpp> | |
#include <boost/utility.hpp> | |
#include <boost/function/function2.hpp> | |
#include <utility> | |
#include <vector> | |
#ifdef BOOST_HAS_ABI_HEADERS | |
# include BOOST_ABI_PREFIX | |
#endif | |
namespace boost { | |
namespace BOOST_SIGNALS_NAMESPACE { | |
namespace detail { | |
// Must be constructed before calling the slots, because it safely | |
// manages call depth | |
class BOOST_SIGNALS_DECL call_notification { | |
public: | |
call_notification(const shared_ptr<signal_base_impl>&); | |
~call_notification(); | |
shared_ptr<signal_base_impl> impl; | |
}; | |
// Implementation of base class for all signals. It handles the | |
// management of the underlying slot lists. | |
class BOOST_SIGNALS_DECL signal_base_impl { | |
public: | |
friend class call_notification; | |
typedef function2<bool, stored_group, stored_group> compare_type; | |
// Make sure that an exception does not cause the "clearing" flag to | |
// remain set | |
class temporarily_set_clearing { | |
public: | |
temporarily_set_clearing(signal_base_impl* b) : base(b) | |
{ | |
base->flags.clearing = true; | |
} | |
~temporarily_set_clearing() | |
{ | |
base->flags.clearing = false; | |
} | |
private: | |
signal_base_impl* base; | |
}; | |
friend class temporarily_set_clearing; | |
signal_base_impl(const compare_type&, const any&); | |
~signal_base_impl(); | |
// Disconnect all slots connected to this signal | |
void disconnect_all_slots(); | |
// Are there any connected slots? | |
bool empty() const; | |
// The number of connected slots | |
std::size_t num_slots() const; | |
// Disconnect all slots in the given group | |
void disconnect(const stored_group&); | |
// We're being notified that a slot has disconnected | |
static void slot_disconnected(void* obj, void* data); | |
connection connect_slot(const any& slot, | |
const stored_group& name, | |
shared_ptr<slot_base::data_t> data, | |
connect_position at); | |
private: | |
// Remove all of the slots that have been marked "disconnected" | |
void remove_disconnected_slots() const; | |
public: | |
// Our call depth when invoking slots (> 1 when we have a loop) | |
mutable int call_depth; | |
struct { | |
// True if some slots have disconnected, but we were not able to | |
// remove them from the list of slots because there are valid | |
// iterators into the slot list | |
mutable bool delayed_disconnect:1; | |
// True if we are disconnecting all disconnected slots | |
bool clearing:1; | |
} flags; | |
// Slots | |
mutable named_slot_map slots_; | |
any combiner_; | |
// Types | |
typedef named_slot_map::iterator iterator; | |
}; | |
class BOOST_SIGNALS_DECL signal_base : public noncopyable { | |
public: | |
typedef signal_base_impl::compare_type compare_type; | |
friend class call_notification; | |
signal_base(const compare_type& comp, const any& combiner); | |
~signal_base(); | |
public: | |
// Disconnect all slots connected to this signal | |
void disconnect_all_slots() { impl->disconnect_all_slots(); } | |
// Are there any connected slots? | |
bool empty() const { return impl->empty(); } | |
// How many slots are connected? | |
std::size_t num_slots() const { return impl->num_slots(); } | |
protected: | |
connection connect_slot(const any& slot, | |
const stored_group& name, | |
shared_ptr<slot_base::data_t> data, | |
connect_position at) | |
{ | |
return impl->connect_slot(slot, name, data, at); | |
} | |
typedef named_slot_map::iterator iterator; | |
shared_ptr<signal_base_impl> impl; | |
}; | |
} // end namespace detail | |
} // end namespace BOOST_SIGNALS_NAMESPACE | |
} // end namespace boost | |
#ifdef BOOST_HAS_ABI_HEADERS | |
# include BOOST_ABI_SUFFIX | |
#endif | |
#endif // BOOST_SIGNALS_SIGNAL_BASE_HEADER |