| 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_CONNECTION_HPP | 
|---|
| 11 | #define BOOST_SIGNALS_CONNECTION_HPP | 
|---|
| 12 |  | 
|---|
| 13 | #include <boost/signals/detail/signals_common.hpp> | 
|---|
| 14 | #include <boost/smart_ptr.hpp> | 
|---|
| 15 | #include <boost/operators.hpp> | 
|---|
| 16 | #include <boost/any.hpp> | 
|---|
| 17 | #include <list> | 
|---|
| 18 | #include <cassert> | 
|---|
| 19 | #include <utility> | 
|---|
| 20 |  | 
|---|
| 21 | #ifdef BOOST_HAS_ABI_HEADERS | 
|---|
| 22 | #  include BOOST_ABI_PREFIX | 
|---|
| 23 | #endif | 
|---|
| 24 |  | 
|---|
| 25 | namespace boost { | 
|---|
| 26 |   namespace BOOST_SIGNALS_NAMESPACE { | 
|---|
| 27 |     class trackable; | 
|---|
| 28 |  | 
|---|
| 29 |     namespace detail { | 
|---|
| 30 |       // Represents an object that has been bound as part of a slot, and how | 
|---|
| 31 |       // to notify that object of a disconnect | 
|---|
| 32 |       struct bound_object { | 
|---|
| 33 |         void* obj; | 
|---|
| 34 |         void* data; | 
|---|
| 35 |         void (*disconnect)(void*, void*); | 
|---|
| 36 |  | 
|---|
| 37 |         bool operator==(const bound_object& other) const | 
|---|
| 38 |           { return obj == other.obj && data == other.data; } | 
|---|
| 39 |         bool operator<(const bound_object& other) const | 
|---|
| 40 |           { return obj < other.obj; } | 
|---|
| 41 |  | 
|---|
| 42 |         // To support intel 80 compiler, 2004/03/18 (Mark Rodgers) | 
|---|
| 43 |         bool operator!=(const bound_object& other) const | 
|---|
| 44 |         { return !(*this==other); } | 
|---|
| 45 |         bool operator>(const bound_object& other) const | 
|---|
| 46 |         { return !(*this < other); } | 
|---|
| 47 |       }; | 
|---|
| 48 |  | 
|---|
| 49 |       // Describes the connection between a signal and the objects that are | 
|---|
| 50 |       // bound for a specific slot. Enables notification of the signal and the | 
|---|
| 51 |       // slots when a disconnect is requested. | 
|---|
| 52 |       struct basic_connection { | 
|---|
| 53 |         void* signal; | 
|---|
| 54 |         void* signal_data; | 
|---|
| 55 |         void (*signal_disconnect)(void*, void*); | 
|---|
| 56 |         bool blocked_; | 
|---|
| 57 |  | 
|---|
| 58 |         std::list<bound_object> bound_objects; | 
|---|
| 59 |       }; | 
|---|
| 60 |     } // end namespace detail | 
|---|
| 61 |  | 
|---|
| 62 |     // The user may freely pass around the "connection" object and terminate | 
|---|
| 63 |     // the connection at any time using disconnect(). | 
|---|
| 64 |     class BOOST_SIGNALS_DECL connection : | 
|---|
| 65 |       private less_than_comparable1<connection>, | 
|---|
| 66 |       private equality_comparable1<connection> | 
|---|
| 67 |     { | 
|---|
| 68 |     public: | 
|---|
| 69 |       connection() : con(), controlling_connection(false) {} | 
|---|
| 70 |       connection(const connection&); | 
|---|
| 71 |       ~connection(); | 
|---|
| 72 |  | 
|---|
| 73 |       // Block he connection: if the connection is still active, there | 
|---|
| 74 |       // will be no notification | 
|---|
| 75 |       void block(bool should_block = true) { con->blocked_ = should_block; } | 
|---|
| 76 |       void unblock() { con->blocked_ = false; } | 
|---|
| 77 |       bool blocked() const { return !connected() || con->blocked_; } | 
|---|
| 78 |  | 
|---|
| 79 |       // Disconnect the signal and slot, if they are connected | 
|---|
| 80 |       void disconnect() const; | 
|---|
| 81 |  | 
|---|
| 82 |       // Returns true if the signal and slot are connected | 
|---|
| 83 |       bool connected() const { return con.get() && con->signal_disconnect; } | 
|---|
| 84 |  | 
|---|
| 85 |       // Comparison of connections | 
|---|
| 86 |       bool operator==(const connection& other) const; | 
|---|
| 87 |       bool operator<(const connection& other) const; | 
|---|
| 88 |  | 
|---|
| 89 |       // Connection assignment | 
|---|
| 90 |       connection& operator=(const connection& other) ; | 
|---|
| 91 |  | 
|---|
| 92 |       // Swap connections | 
|---|
| 93 |       void swap(connection& other); | 
|---|
| 94 |  | 
|---|
| 95 |     public: // TBD: CHANGE THIS | 
|---|
| 96 |       // Set whether this connection object is controlling or not | 
|---|
| 97 |       void set_controlling(bool control = true) | 
|---|
| 98 |       { controlling_connection = control; } | 
|---|
| 99 |  | 
|---|
| 100 |       shared_ptr<BOOST_SIGNALS_NAMESPACE::detail::basic_connection> | 
|---|
| 101 |       get_connection() const | 
|---|
| 102 |       { return con; } | 
|---|
| 103 |  | 
|---|
| 104 |     private: | 
|---|
| 105 |       friend class detail::signal_base_impl; | 
|---|
| 106 |       friend class detail::slot_base; | 
|---|
| 107 |       friend class trackable; | 
|---|
| 108 |  | 
|---|
| 109 |       // Reset this connection to refer to a different actual connection | 
|---|
| 110 |       void reset(BOOST_SIGNALS_NAMESPACE::detail::basic_connection*); | 
|---|
| 111 |  | 
|---|
| 112 |       // Add a bound object to this connection (not for users) | 
|---|
| 113 |       void add_bound_object(const BOOST_SIGNALS_NAMESPACE::detail::bound_object& b); | 
|---|
| 114 |  | 
|---|
| 115 |       friend class BOOST_SIGNALS_NAMESPACE::detail::bound_objects_visitor; | 
|---|
| 116 |  | 
|---|
| 117 |       // Pointer to the actual contents of the connection | 
|---|
| 118 |       shared_ptr<BOOST_SIGNALS_NAMESPACE::detail::basic_connection> con; | 
|---|
| 119 |  | 
|---|
| 120 |       // True if the destruction of this connection object should disconnect | 
|---|
| 121 |       bool controlling_connection; | 
|---|
| 122 |     }; | 
|---|
| 123 |  | 
|---|
| 124 |     // Similar to connection, but will disconnect the connection when it is | 
|---|
| 125 |     // destroyed unless release() has been called. | 
|---|
| 126 |     class BOOST_SIGNALS_DECL scoped_connection : public connection { | 
|---|
| 127 |     public: | 
|---|
| 128 |       scoped_connection() : connection(), released(false) {} | 
|---|
| 129 |       scoped_connection(const connection&); | 
|---|
| 130 |       scoped_connection(const scoped_connection&); | 
|---|
| 131 |       ~scoped_connection(); | 
|---|
| 132 |  | 
|---|
| 133 |       connection release(); | 
|---|
| 134 |  | 
|---|
| 135 |       inline void swap(scoped_connection&); | 
|---|
| 136 |  | 
|---|
| 137 |       scoped_connection& operator=(const connection&); | 
|---|
| 138 |       scoped_connection& operator=(const scoped_connection&); | 
|---|
| 139 |  | 
|---|
| 140 |     private: | 
|---|
| 141 |       bool released; | 
|---|
| 142 |     }; | 
|---|
| 143 |  | 
|---|
| 144 |     namespace detail { | 
|---|
| 145 |       struct connection_slot_pair { | 
|---|
| 146 |         connection first; | 
|---|
| 147 |         any second; | 
|---|
| 148 |  | 
|---|
| 149 |         connection_slot_pair() {} | 
|---|
| 150 |  | 
|---|
| 151 |         connection_slot_pair(const connection& c, const any& a) | 
|---|
| 152 |           : first(c), second(a) | 
|---|
| 153 |         { | 
|---|
| 154 |         } | 
|---|
| 155 |  | 
|---|
| 156 |         // Dummys to allow explicit instantiation to work | 
|---|
| 157 |         bool operator==(const connection_slot_pair&) const { return false; } | 
|---|
| 158 |         bool operator<(const connection_slot_pair&) const { return false;} | 
|---|
| 159 |       }; | 
|---|
| 160 |  | 
|---|
| 161 |       // Determines if the underlying connection is disconnected | 
|---|
| 162 |       struct is_disconnected { | 
|---|
| 163 |         typedef connection_slot_pair argument_type; | 
|---|
| 164 |         typedef bool result_type; | 
|---|
| 165 |  | 
|---|
| 166 |         inline bool operator()(const argument_type& c) const | 
|---|
| 167 |         { | 
|---|
| 168 |           return !c.first.connected(); | 
|---|
| 169 |         } | 
|---|
| 170 |       }; | 
|---|
| 171 |  | 
|---|
| 172 |       // Determines if the underlying connection is callable, ie if | 
|---|
| 173 |       // it is connected and not blocked | 
|---|
| 174 |       struct is_callable { | 
|---|
| 175 |         typedef connection_slot_pair argument_type; | 
|---|
| 176 |         typedef bool result_type; | 
|---|
| 177 |  | 
|---|
| 178 |         inline bool operator()(const argument_type& c) const | 
|---|
| 179 |         { | 
|---|
| 180 |           return c.first.connected() && !c.first.blocked() ; | 
|---|
| 181 |         } | 
|---|
| 182 |       }; | 
|---|
| 183 |  | 
|---|
| 184 |       // Autodisconnects the bound object when it is destroyed unless the | 
|---|
| 185 |       // release method is invoked. | 
|---|
| 186 |       class auto_disconnect_bound_object { | 
|---|
| 187 |       public: | 
|---|
| 188 |         auto_disconnect_bound_object(const bound_object& b) : | 
|---|
| 189 |           binding(b), auto_disconnect(true) | 
|---|
| 190 |         { | 
|---|
| 191 |         } | 
|---|
| 192 |  | 
|---|
| 193 |         ~auto_disconnect_bound_object() | 
|---|
| 194 |         { | 
|---|
| 195 |           if (auto_disconnect) | 
|---|
| 196 |             binding.disconnect(binding.obj, binding.data); | 
|---|
| 197 |         } | 
|---|
| 198 |  | 
|---|
| 199 |         void release() { auto_disconnect = false; } | 
|---|
| 200 |  | 
|---|
| 201 |       private: | 
|---|
| 202 |         bound_object binding; | 
|---|
| 203 |         bool auto_disconnect; | 
|---|
| 204 |       }; | 
|---|
| 205 |     } // end namespace detail | 
|---|
| 206 |   } // end namespace BOOST_SIGNALS_NAMESPACE | 
|---|
| 207 | } // end namespace boost | 
|---|
| 208 |  | 
|---|
| 209 | #ifdef BOOST_HAS_ABI_HEADERS | 
|---|
| 210 | #  include BOOST_ABI_SUFFIX | 
|---|
| 211 | #endif | 
|---|
| 212 |  | 
|---|
| 213 | #endif // BOOST_SIGNALS_CONNECTION_HPP | 
|---|