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