2002-05-26 13:02:17 +00:00
|
|
|
// Boost.Signals library
|
2004-02-05 09:14:22 +00:00
|
|
|
|
2004-11-20 09:08:45 +00:00
|
|
|
// Copyright Douglas Gregor 2001-2004. Use, modification and
|
2004-02-05 09:14:22 +00:00
|
|
|
// 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)
|
|
|
|
|
2002-05-26 13:02:17 +00:00
|
|
|
// For more information, see http://www.boost.org
|
|
|
|
|
2004-02-05 09:14:22 +00:00
|
|
|
#define BOOST_SIGNALS_SOURCE
|
2002-08-20 21:50:08 +00:00
|
|
|
|
2002-05-26 13:02:17 +00:00
|
|
|
#include <boost/signals/connection.hpp>
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
namespace boost {
|
2002-06-18 15:39:27 +00:00
|
|
|
namespace BOOST_SIGNALS_NAMESPACE {
|
2004-02-05 09:14:22 +00:00
|
|
|
|
2004-11-20 09:08:45 +00:00
|
|
|
connection::connection(const connection& other) :
|
|
|
|
con(other.con), controlling_connection(other.controlling_connection)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
connection::~connection()
|
|
|
|
{
|
|
|
|
if (controlling_connection) {
|
|
|
|
disconnect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
connection::reset(BOOST_SIGNALS_NAMESPACE::detail::basic_connection* new_con)
|
|
|
|
{
|
|
|
|
con.reset(new_con);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool connection::operator==(const connection& other) const
|
|
|
|
{
|
|
|
|
return con.get() == other.con.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool connection::operator<(const connection& other) const
|
|
|
|
{
|
|
|
|
return con.get() < other.con.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
connection& connection::operator=(const connection& other)
|
|
|
|
{
|
|
|
|
connection(other).swap(*this);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void connection::swap(connection& other)
|
|
|
|
{
|
|
|
|
this->con.swap(other.con);
|
|
|
|
std::swap(this->controlling_connection, other.controlling_connection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(connection& c1, connection& c2)
|
|
|
|
{
|
|
|
|
c1.swap(c2);
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_connection::scoped_connection(const connection& other) :
|
|
|
|
connection(other),
|
|
|
|
released(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_connection::scoped_connection(const scoped_connection& other) :
|
|
|
|
connection(other),
|
|
|
|
released(other.released)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_connection::~scoped_connection()
|
|
|
|
{
|
|
|
|
if (!released) {
|
|
|
|
this->disconnect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
connection scoped_connection::release()
|
|
|
|
{
|
|
|
|
released = true;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void scoped_connection::swap(scoped_connection& other)
|
|
|
|
{
|
|
|
|
this->connection::swap(other);
|
|
|
|
bool other_released = other.released;
|
|
|
|
other.released = this->released;
|
|
|
|
this->released = other_released;
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(scoped_connection& c1, scoped_connection& c2)
|
|
|
|
{
|
|
|
|
c1.swap(c2);
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_connection&
|
|
|
|
scoped_connection::operator=(const connection& other)
|
|
|
|
{
|
|
|
|
scoped_connection(other).swap(*this);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_connection&
|
|
|
|
scoped_connection::operator=(const scoped_connection& other)
|
|
|
|
{
|
|
|
|
scoped_connection(other).swap(*this);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2004-02-05 09:14:22 +00:00
|
|
|
void
|
|
|
|
connection::add_bound_object(const BOOST_SIGNALS_NAMESPACE::detail::bound_object& b)
|
|
|
|
{
|
|
|
|
assert(con.get() != 0);
|
|
|
|
con->bound_objects.push_back(b);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-26 13:02:17 +00:00
|
|
|
void connection::disconnect() const
|
|
|
|
{
|
|
|
|
if (this->connected()) {
|
|
|
|
// Make sure we have a reference to the basic_connection object,
|
|
|
|
// because 'this' may disappear
|
|
|
|
shared_ptr<detail::basic_connection> local_con = con;
|
|
|
|
|
|
|
|
void (*signal_disconnect)(void*, void*) = local_con->signal_disconnect;
|
|
|
|
|
|
|
|
// Note that this connection no longer exists
|
|
|
|
// Order is important here: we could get into an infinite loop if this
|
|
|
|
// isn't cleared before we try the disconnect.
|
|
|
|
local_con->signal_disconnect = 0;
|
|
|
|
|
|
|
|
// Disconnect signal
|
|
|
|
signal_disconnect(local_con->signal, local_con->signal_data);
|
2004-02-05 09:14:22 +00:00
|
|
|
|
2002-05-26 13:02:17 +00:00
|
|
|
// Disconnect all bound objects
|
2002-06-18 15:39:27 +00:00
|
|
|
typedef std::list<BOOST_SIGNALS_NAMESPACE::detail::bound_object>::iterator iterator;
|
2004-02-05 09:14:22 +00:00
|
|
|
for (iterator i = local_con->bound_objects.begin();
|
2002-05-26 13:02:17 +00:00
|
|
|
i != local_con->bound_objects.end(); ++i) {
|
2002-08-09 08:51:51 +00:00
|
|
|
assert(i->disconnect != 0);
|
2002-05-26 13:02:17 +00:00
|
|
|
i->disconnect(i->obj, i->data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-02-05 09:14:22 +00:00
|
|
|
} // end namespace boost
|
2002-05-26 13:02:17 +00:00
|
|
|
} // end namespace boost
|
|
|
|
|
|
|
|
#ifndef BOOST_MSVC
|
|
|
|
// Explicit instantiations to keep everything in the library
|
2002-06-18 15:39:27 +00:00
|
|
|
template class std::list<boost::BOOST_SIGNALS_NAMESPACE::detail::bound_object>;
|
2002-05-26 13:02:17 +00:00
|
|
|
#endif
|