-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
608 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
// Boost.Signals library | ||
|
||
// Copyright Douglas Gregor 2001-2004. Use, modification and | ||
// 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) | ||
|
||
// For more information, see http://www.boost.org | ||
|
||
#define BOOST_SIGNALS_SOURCE | ||
|
||
#include <boost/signals/connection.hpp> | ||
#include <cassert> | ||
|
||
namespace boost { | ||
namespace BOOST_SIGNALS_NAMESPACE { | ||
|
||
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; | ||
} | ||
|
||
void | ||
connection::add_bound_object(const BOOST_SIGNALS_NAMESPACE::detail::bound_object& b) | ||
{ | ||
assert(con.get() != 0); | ||
con->bound_objects.push_back(b); | ||
} | ||
|
||
|
||
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); | ||
|
||
// Disconnect all bound objects | ||
typedef std::list<BOOST_SIGNALS_NAMESPACE::detail::bound_object>::iterator iterator; | ||
for (iterator i = local_con->bound_objects.begin(); | ||
i != local_con->bound_objects.end(); ++i) { | ||
assert(i->disconnect != 0); | ||
i->disconnect(i->obj, i->data); | ||
} | ||
} | ||
} | ||
} // end namespace boost | ||
} // end namespace boost | ||
|
||
#ifndef BOOST_MSVC | ||
// Explicit instantiations to keep everything in the library | ||
template class std::list<boost::BOOST_SIGNALS_NAMESPACE::detail::bound_object>; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// Boost.Signals library | ||
|
||
// Copyright Douglas Gregor 2001-2004. Use, modification and | ||
// 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) | ||
|
||
// For more information, see http://www.boost.org | ||
|
||
#define BOOST_SIGNALS_SOURCE | ||
|
||
#include <boost/signals/detail/named_slot_map.hpp> | ||
#include <cassert> | ||
#include <map> | ||
#include <list> | ||
#include <typeinfo> | ||
|
||
namespace boost { namespace BOOST_SIGNALS_NAMESPACE { namespace detail { | ||
|
||
typedef std::list<connection_slot_pair> group_list; | ||
typedef group_list::iterator slot_pair_iterator; | ||
typedef std::map<stored_group, group_list, compare_type> slot_container_type; | ||
typedef slot_container_type::iterator group_iterator; | ||
typedef slot_container_type::const_iterator const_group_iterator; | ||
|
||
|
||
#if BOOST_WORKAROUND(_MSC_VER, <= 1600) | ||
void named_slot_map_iterator::decrement() { assert(false); } | ||
void named_slot_map_iterator::advance(difference_type) { assert(false); } | ||
#endif | ||
|
||
named_slot_map::named_slot_map(const compare_type& compare) : groups(compare) | ||
{ | ||
clear(); | ||
} | ||
|
||
void named_slot_map::clear() | ||
{ | ||
groups.clear(); | ||
groups[stored_group(stored_group::sk_front)]; | ||
groups[stored_group(stored_group::sk_back)]; | ||
back = groups.end(); | ||
--back; | ||
} | ||
|
||
named_slot_map::iterator named_slot_map::begin() | ||
{ | ||
return named_slot_map::iterator(groups.begin(), groups.end()); | ||
} | ||
|
||
named_slot_map::iterator named_slot_map::end() | ||
{ | ||
return named_slot_map::iterator(groups.end(), groups.end()); | ||
} | ||
|
||
named_slot_map::iterator | ||
named_slot_map::insert(const stored_group& name, const connection& con, | ||
const any& slot, connect_position at) | ||
{ | ||
group_iterator group; | ||
if (name.empty()) { | ||
switch (at) { | ||
case at_front: group = groups.begin(); break; | ||
case at_back: group = back; break; | ||
} | ||
} else { | ||
group = groups.find(name); | ||
if (group == groups.end()) { | ||
slot_container_type::value_type v(name, group_list()); | ||
group = groups.insert(v).first; | ||
} | ||
} | ||
iterator it; | ||
it.group = group; | ||
it.last_group = groups.end(); | ||
|
||
switch (at) { | ||
case at_back: | ||
group->second.push_back(connection_slot_pair(con, slot)); | ||
it.slot_ = group->second.end(); | ||
it.slot_assigned = true; | ||
--(it.slot_); | ||
break; | ||
|
||
case at_front: | ||
group->second.push_front(connection_slot_pair(con, slot)); | ||
it.slot_ = group->second.begin(); | ||
it.slot_assigned = true; | ||
break; | ||
} | ||
return it; | ||
} | ||
|
||
void named_slot_map::disconnect(const stored_group& name) | ||
{ | ||
group_iterator group = groups.find(name); | ||
if (group != groups.end()) { | ||
slot_pair_iterator i = group->second.begin(); | ||
while (i != group->second.end()) { | ||
slot_pair_iterator next = i; | ||
++next; | ||
i->first.disconnect(); | ||
i = next; | ||
} | ||
groups.erase(group); | ||
} | ||
} | ||
|
||
void named_slot_map::erase(iterator pos) | ||
{ | ||
// Erase the slot | ||
pos.slot_->first.disconnect(); | ||
pos.group->second.erase(pos.slot_); | ||
} | ||
|
||
void named_slot_map::remove_disconnected_slots() | ||
{ | ||
// Remove any disconnected slots | ||
group_iterator g = groups.begin(); | ||
while (g != groups.end()) { | ||
slot_pair_iterator s = g->second.begin(); | ||
while (s != g->second.end()) { | ||
if (s->first.connected()) ++s; | ||
else g->second.erase(s++); | ||
} | ||
|
||
// Clear out empty groups | ||
if (empty(g)) groups.erase(g++); | ||
else ++g; | ||
} | ||
} | ||
|
||
|
||
} } } |
Oops, something went wrong.