/////////////////////////////////////////////////////////////////////
//slot_base
class BOOST_SIGNALS_DECL slot_base
{
public:
struct data_t
{
std::vector<const trackable*> bound_objects;
connection watch_bound_objects;
};
shared_ptr<data_t> get_data() const { return data; }
std::vector<const trackable*>& get_bound_objects() const
{
return data->bound_objects;
}
bool is_active() const
{
return data->watch_bound_objects.connected();
}
protected:
void create_connection();
shared_ptr<data_t> data;
private:
static void bound_object_destructed(void*, void*) {}
};
//////////////////////////////////////////////////////////////////////////////////
//slot
template<typename SlotFunction>
class slot : public BOOST_SIGNALS_NAMESPACE::detail::slot_base
{
typedef BOOST_SIGNALS_NAMESPACE::detail::slot_base inherited;
typedef typename inherited::data_t data_t;
public:
template<typename F>
slot(const F& f) : slot_function(BOOST_SIGNALS_NAMESPACE::get_invocable_slot(f, BOOST_SIGNALS_NAMESPACE::tag_type(f)))
{
this->data.reset(new data_t);
BOOST_SIGNALS_NAMESPACE::detail::bound_objects_visitor do_bind(this->data->bound_objects);
visit_each(do_bind,
BOOST_SIGNALS_NAMESPACE::get_inspectable_slot
(f, BOOST_SIGNALS_NAMESPACE::tag_type(f)));
create_connection();
}
public:
const SlotFunction& get_slot_function() const { return slot_function; }
void release() const { data->watch_bound_objects.set_controlling(false); }
private:
slot();
slot& operator=(const slot&);
SlotFunction slot_function;
};
//////////////////////////////////////////////////////////////////////////
//slot_base::create_connection
void slot_base::create_connection()
{
basic_connection* con = new basic_connection();
{
con->signal = static_cast<void*>(this);
con->signal_data = 0;
con->blocked_ = false ;
con->signal_disconnect = &bound_object_destructed;
}
data->watch_bound_objects.reset(con);
scoped_connection safe_connection(data->watch_bound_objects);
for(std::vector<const trackable*>::iterator i = data->bound_objects.begin();
i != data->bound_objects.end(); ++i)
{
BOOST_SIGNALS_NAMESPACE::detail::bound_object binding;
(*i)->signal_connected(data->watch_bound_objects, binding);
BOOST_SIGNALS_NAMESPACE::detail::auto_disconnect_bound_object disconnector(binding);
con->bound_objects.push_back(binding);
disconnector.release();
}
safe_connection.release();
data->watch_bound_objects.set_controlling(true);
}
posted on 2007-04-24 15:15
walkspeed 阅读(521)
评论(0) 编辑 收藏 引用 所属分类:
boost学习