source: NonGTP/Boost/boost/signals/detail/signal_base.hpp @ 857

Revision 857, 4.9 KB checked in by igarcia, 18 years ago (diff)
Line 
1// Boost.Signals library
2
3// Copyright Douglas Gregor 2001-2004. Use, modification and
4// distribution is subject to the Boost Software License, Version
5// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7
8// For more information, see http://www.boost.org
9
10#ifndef BOOST_SIGNALS_SIGNAL_BASE_HEADER
11#define BOOST_SIGNALS_SIGNAL_BASE_HEADER
12
13#include <boost/signals/detail/config.hpp>
14#include <boost/signals/detail/signals_common.hpp>
15#include <boost/signals/detail/named_slot_map.hpp>
16#include <boost/signals/connection.hpp>
17#include <boost/signals/trackable.hpp>
18#include <boost/signals/slot.hpp>
19#include <boost/smart_ptr.hpp>
20#include <boost/utility.hpp>
21#include <boost/function/function2.hpp>
22#include <utility>
23#include <vector>
24
25#ifdef BOOST_HAS_ABI_HEADERS
26#  include BOOST_ABI_PREFIX
27#endif
28
29namespace boost {
30  namespace BOOST_SIGNALS_NAMESPACE {
31    namespace detail {
32      // Must be constructed before calling the slots, because it safely
33      // manages call depth
34      class BOOST_SIGNALS_DECL call_notification {
35      public:
36        call_notification(const shared_ptr<signal_base_impl>&);
37        ~call_notification();
38
39        shared_ptr<signal_base_impl> impl;
40      };
41
42      // Implementation of base class for all signals. It handles the
43      // management of the underlying slot lists.
44      class BOOST_SIGNALS_DECL signal_base_impl {
45      public:
46        friend class call_notification;
47
48        typedef function2<bool, stored_group, stored_group> compare_type;
49
50        // Make sure that an exception does not cause the "clearing" flag to
51        // remain set
52        class temporarily_set_clearing {
53        public:
54          temporarily_set_clearing(signal_base_impl* b) : base(b)
55          {
56            base->flags.clearing = true;
57          }
58
59          ~temporarily_set_clearing()
60          {
61            base->flags.clearing = false;
62          }
63
64        private:
65          signal_base_impl* base;
66        };
67
68        friend class temporarily_set_clearing;
69
70        signal_base_impl(const compare_type&, const any&);
71        ~signal_base_impl();
72
73        // Disconnect all slots connected to this signal
74        void disconnect_all_slots();
75
76        // Are there any connected slots?
77        bool empty() const;
78
79        // The number of connected slots
80        std::size_t num_slots() const;
81
82        // Disconnect all slots in the given group
83        void disconnect(const stored_group&);
84
85        // We're being notified that a slot has disconnected
86        static void slot_disconnected(void* obj, void* data);
87
88        connection connect_slot(const any& slot,
89                                const stored_group& name,
90                                shared_ptr<slot_base::data_t> data,
91                                connect_position at);
92
93      private:
94        // Remove all of the slots that have been marked "disconnected"
95        void remove_disconnected_slots() const;
96
97      public:
98        // Our call depth when invoking slots (> 1 when we have a loop)
99        mutable int call_depth;
100
101        struct {
102          // True if some slots have disconnected, but we were not able to
103          // remove them from the list of slots because there are valid
104          // iterators into the slot list
105          mutable bool delayed_disconnect:1;
106
107          // True if we are disconnecting all disconnected slots
108          bool clearing:1;
109        } flags;
110
111        // Slots
112        mutable named_slot_map slots_;
113        any combiner_;
114
115        // Types
116        typedef named_slot_map::iterator iterator;
117      };
118
119      class BOOST_SIGNALS_DECL signal_base : public noncopyable {
120      public:
121        typedef signal_base_impl::compare_type compare_type;
122
123        friend class call_notification;
124
125        signal_base(const compare_type& comp, const any& combiner);
126        ~signal_base();
127
128      public:
129        // Disconnect all slots connected to this signal
130        void disconnect_all_slots() { impl->disconnect_all_slots(); }
131
132        // Are there any connected slots?
133        bool empty() const { return impl->empty(); }
134
135        // How many slots are connected?
136        std::size_t num_slots() const { return impl->num_slots(); }
137
138      protected:
139        connection connect_slot(const any& slot,
140                                const stored_group& name,
141                                shared_ptr<slot_base::data_t> data,
142                                connect_position at)
143        {
144          return impl->connect_slot(slot, name, data, at);
145        }
146
147        typedef named_slot_map::iterator iterator;
148
149        shared_ptr<signal_base_impl> impl;
150      };
151    } // end namespace detail
152  } // end namespace BOOST_SIGNALS_NAMESPACE
153} // end namespace boost
154
155#ifdef BOOST_HAS_ABI_HEADERS
156#  include BOOST_ABI_SUFFIX
157#endif
158
159#endif // BOOST_SIGNALS_SIGNAL_BASE_HEADER
Note: See TracBrowser for help on using the repository browser.