2004-11-20 09:08:45 +00:00
|
|
|
// 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;
|
2006-03-05 18:22:35 +00:00
|
|
|
typedef std::map<stored_group, group_list, compare_type> slot_container_type;
|
2004-11-20 09:08:45 +00:00
|
|
|
typedef slot_container_type::iterator group_iterator;
|
|
|
|
typedef slot_container_type::const_iterator const_group_iterator;
|
|
|
|
|
|
|
|
|
2008-09-30 18:01:03 +00:00
|
|
|
#if BOOST_WORKAROUND(_MSC_VER, <= 1500)
|
2004-11-20 09:08:45 +00:00
|
|
|
void named_slot_map_iterator::decrement() { assert(false); }
|
|
|
|
void named_slot_map_iterator::advance(difference_type) { assert(false); }
|
|
|
|
#endif
|
|
|
|
|
2006-03-05 18:22:35 +00:00
|
|
|
named_slot_map::named_slot_map(const compare_type& compare) : groups(compare)
|
2004-11-20 09:08:45 +00:00
|
|
|
{
|
2006-03-05 18:22:35 +00:00
|
|
|
clear();
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
|
2006-03-05 18:22:35 +00:00
|
|
|
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;
|
|
|
|
}
|
2004-11-20 09:08:45 +00:00
|
|
|
|
|
|
|
named_slot_map::iterator named_slot_map::begin()
|
|
|
|
{
|
2006-03-05 18:22:35 +00:00
|
|
|
return named_slot_map::iterator(groups.begin(), groups.end());
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
named_slot_map::iterator named_slot_map::end()
|
|
|
|
{
|
2006-03-05 18:22:35 +00:00
|
|
|
return named_slot_map::iterator(groups.end(), groups.end());
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
named_slot_map::iterator
|
2006-03-05 18:22:35 +00:00
|
|
|
named_slot_map::insert(const stored_group& name, const connection& con,
|
|
|
|
const any& slot, connect_position at)
|
2004-11-20 09:08:45 +00:00
|
|
|
{
|
|
|
|
group_iterator group;
|
|
|
|
if (name.empty()) {
|
|
|
|
switch (at) {
|
2006-03-05 18:22:35 +00:00
|
|
|
case at_front: group = groups.begin(); break;
|
|
|
|
case at_back: group = back; break;
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
} else {
|
2006-03-05 18:22:35 +00:00
|
|
|
group = groups.find(name);
|
|
|
|
if (group == groups.end()) {
|
2004-11-20 09:08:45 +00:00
|
|
|
slot_container_type::value_type v(name, group_list());
|
2006-03-05 18:22:35 +00:00
|
|
|
group = groups.insert(v).first;
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
}
|
2006-03-05 18:22:35 +00:00
|
|
|
iterator it;
|
|
|
|
it.group = group;
|
|
|
|
it.last_group = groups.end();
|
2004-11-20 09:08:45 +00:00
|
|
|
|
|
|
|
switch (at) {
|
|
|
|
case at_back:
|
|
|
|
group->second.push_back(connection_slot_pair(con, slot));
|
2006-03-05 18:22:35 +00:00
|
|
|
it.slot_ = group->second.end();
|
|
|
|
it.slot_assigned = true;
|
|
|
|
--(it.slot_);
|
2004-11-20 09:08:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case at_front:
|
|
|
|
group->second.push_front(connection_slot_pair(con, slot));
|
2006-03-05 18:22:35 +00:00
|
|
|
it.slot_ = group->second.begin();
|
|
|
|
it.slot_assigned = true;
|
2004-11-20 09:08:45 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-03-05 18:22:35 +00:00
|
|
|
return it;
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
|
2006-03-05 18:22:35 +00:00
|
|
|
void named_slot_map::disconnect(const stored_group& name)
|
2004-11-20 09:08:45 +00:00
|
|
|
{
|
2006-03-05 18:22:35 +00:00
|
|
|
group_iterator group = groups.find(name);
|
|
|
|
if (group != groups.end()) {
|
2004-11-20 09:08:45 +00:00
|
|
|
slot_pair_iterator i = group->second.begin();
|
|
|
|
while (i != group->second.end()) {
|
|
|
|
slot_pair_iterator next = i;
|
|
|
|
++next;
|
|
|
|
i->first.disconnect();
|
|
|
|
i = next;
|
|
|
|
}
|
2006-03-05 18:22:35 +00:00
|
|
|
groups.erase(group);
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void named_slot_map::erase(iterator pos)
|
|
|
|
{
|
|
|
|
// Erase the slot
|
2006-03-05 18:22:35 +00:00
|
|
|
pos.slot_->first.disconnect();
|
|
|
|
pos.group->second.erase(pos.slot_);
|
2004-11-20 09:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void named_slot_map::remove_disconnected_slots()
|
|
|
|
{
|
|
|
|
// Remove any disconnected slots
|
2006-03-05 18:22:35 +00:00
|
|
|
group_iterator g = groups.begin();
|
|
|
|
while (g != groups.end()) {
|
2004-11-20 09:08:45 +00:00
|
|
|
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
|
2006-03-05 18:22:35 +00:00
|
|
|
if (empty(g)) groups.erase(g++);
|
2004-11-20 09:08:45 +00:00
|
|
|
else ++g;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} } }
|