| [29] | 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 | 
|---|