Gtalk源码剖析之:sigslot源代码
Posted ouyangbuxiu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gtalk源码剖析之:sigslot源代码相关的知识,希望对你有一定的参考价值。
版权声明: 本文章由vt.buxiu发布在www.vtzone.org,版权归vtzone研究小组所有,转载请保持此声明!!!
@@内容摘要:
sigslot源代码包含:single_threaded,multi_threaded_global,multi_threaded_local ,lock_block等用于控制线程安全的辅助类,以及has_slots,_connection相关类,_signal相关类;本文仅以参数个数为0的代码作为事例,其他大于0个参数的情况相同。 @@
/*single_threaded/multi_threaed...作为父类被has_slot继承*/
class single_threaded ;//单线程,空,所以相当于has_slot没有父类
// The multi threading policies only get compiled in if they are enabled.
class multi_threaded_global ;//全局多线程共享临界区,has_slot从这个类继承了锁
class multi_threaded_local ; //每个对象多线程共享临界区
template<class mt_policy> //封装锁资源,用于{}
class lock_block;
has_slots模板类:[code]
template
<
class
mt_policy
>
class has_slots;
template < class mt_policy = SIGSLOT_DEFAULT_MT_POLICY >
class has_slots : public mt_policy
... {
private:
typedef std::set<_signal_base<mt_policy> *> sender_set; //发送者集合:signal集合
typedef sender_set::const_iterator const_iterator;
public:
has_slots()
...{
;
}
has_slots(const has_slots& hs) //拷贝构造函数
: mt_policy(hs)
...{
lock_block<mt_policy> lock(this);
const_iterator it = hs.m_senders.begin();
const_iterator itEnd = hs.m_senders.end();
while(it != itEnd)
...{
//signal->slot_duplicate(old,new);
(*it)->slot_duplicate(&hs, this);
m_senders.insert(*it);
++it;
}
}
//将signal放入到sender集合中
void signal_connect(_signal_base<mt_policy>* sender)
...{
lock_block<mt_policy> lock(this);
m_senders.insert(sender);
}
//从sender集合中删除指定的signal
void signal_disconnect(_signal_base<mt_policy>* sender)
...{
lock_block<mt_policy> lock(this);
m_senders.erase(sender);
}
virtual ~has_slots()
...{
disconnect_all();
}
void disconnect_all()
...{
lock_block<mt_policy> lock(this);
const_iterator it = m_senders.begin();
const_iterator itEnd = m_senders.end();
while(it != itEnd)
...{
(*it)->slot_disconnect(this);
++it;
}
m_senders.erase(m_senders.begin(), m_senders.end());
}
private:
sender_set m_senders;
} ;[ / code]
class has_slots;
template < class mt_policy = SIGSLOT_DEFAULT_MT_POLICY >
class has_slots : public mt_policy
... {
private:
typedef std::set<_signal_base<mt_policy> *> sender_set; //发送者集合:signal集合
typedef sender_set::const_iterator const_iterator;
public:
has_slots()
...{
;
}
has_slots(const has_slots& hs) //拷贝构造函数
: mt_policy(hs)
...{
lock_block<mt_policy> lock(this);
const_iterator it = hs.m_senders.begin();
const_iterator itEnd = hs.m_senders.end();
while(it != itEnd)
...{
//signal->slot_duplicate(old,new);
(*it)->slot_duplicate(&hs, this);
m_senders.insert(*it);
++it;
}
}
//将signal放入到sender集合中
void signal_connect(_signal_base<mt_policy>* sender)
...{
lock_block<mt_policy> lock(this);
m_senders.insert(sender);
}
//从sender集合中删除指定的signal
void signal_disconnect(_signal_base<mt_policy>* sender)
...{
lock_block<mt_policy> lock(this);
m_senders.erase(sender);
}
virtual ~has_slots()
...{
disconnect_all();
}
void disconnect_all()
...{
lock_block<mt_policy> lock(this);
const_iterator it = m_senders.begin();
const_iterator itEnd = m_senders.end();
while(it != itEnd)
...{
(*it)->slot_disconnect(this);
++it;
}
m_senders.erase(m_senders.begin(), m_senders.end());
}
private:
sender_set m_senders;
} ;[ / code]
_connection_base0模板类
[code]template
<
class
mt_policy
>
//
conncetion_base定义抽象接口,要求connect必须实现该接口
class _connection_base0
... {
public:
virtual has_slots<mt_policy>* getdest() const = 0;
virtual void emit() = 0;
virtual _connection_base0* clone() = 0;
virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;
} ;[ / code]_connection0模板类[code]
template < class dest_type, class mt_policy >
class _connection0 : public _connection_base0 < mt_policy >
... {
public:
_connection0()
...{
pobject = NULL;
pmemfun = NULL;
}
//connect构造函数,每个connect对象记录了(接受/发送)消息对象的地址和回调函数,
//而connect对象本身保存在signal中
_connection0(dest_type* pobject, void (dest_type::*pmemfun)())
...{
m_pobject = pobject;
m_pmemfun = pmemfun;
}
//克隆一个connect对象,即基于*this生成一个新的connect对象
virtual _connection_base0<mt_policy>* clone()
...{
return new _connection0<dest_type, mt_policy>(*this);
}
//生成一个新的connect对象,但内容为:新的(接受/发送)消息对象地址+老的回调函数
virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
...{
return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
}
//发送消息,即调用connect中注册的回调函数(对象的成员函数)
virtual void emit()
...{
(m_pobject->*m_pmemfun)();
}
//返回目标对象地址
virtual has_slots<mt_policy>* getdest() const
...{
return m_pobject;
}
private:
dest_type* m_pobject;
void (dest_type::* m_pmemfun)();
} ;[ / code]
class _connection_base0
... {
public:
virtual has_slots<mt_policy>* getdest() const = 0;
virtual void emit() = 0;
virtual _connection_base0* clone() = 0;
virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;
} ;[ / code]_connection0模板类[code]
template < class dest_type, class mt_policy >
class _connection0 : public _connection_base0 < mt_policy >
... {
public:
_connection0()
...{
pobject = NULL;
pmemfun = NULL;
}
//connect构造函数,每个connect对象记录了(接受/发送)消息对象的地址和回调函数,
//而connect对象本身保存在signal中
_connection0(dest_type* pobject, void (dest_type::*pmemfun)())
...{
m_pobject = pobject;
m_pmemfun = pmemfun;
}
//克隆一个connect对象,即基于*this生成一个新的connect对象
virtual _connection_base0<mt_policy>* clone()
...{
return new _connection0<dest_type, mt_policy>(*this);
}
//生成一个新的connect对象,但内容为:新的(接受/发送)消息对象地址+老的回调函数
virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
...{
return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
}
//发送消息,即调用connect中注册的回调函数(对象的成员函数)
virtual void emit()
...{
(m_pobject->*m_pmemfun)();
}
//返回目标对象地址
virtual has_slots<mt_policy>* getdest() const
...{
return m_pobject;
}
private:
dest_type* m_pobject;
void (dest_type::* m_pmemfun)();
} ;[ / code]
_signal_base模板类
[code]template
<
class
mt_policy
>
class _signal_base : public mt_policy // signal基类,定义抽象接口
... {
public:
virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
} ;[ / code]_signal_base0 模板类[code]
template < class mt_policy >
class _signal_base0 : public _signal_base < mt_policy > // 带有0个参数的signal
... {
public:
typedef std::list<_connection_base0<mt_policy> *> connections_list;
_signal_base0()
...{
;
}
_signal_base0(const _signal_base0& s) //拷贝构造函数
: _signal_base<mt_policy>(s)
...{
lock_block<mt_policy> lock(this);
connections_list::const_iterator it = s.m_connected_slots.begin();
connections_list::const_iterator itEnd = s.m_connected_slots.end();
while(it != itEnd)
...{
(*it)->getdest()->signal_connect(this);
m_connected_slots.push_back((*it)->clone());
++it;
}
}
~_signal_base0()
...{
disconnect_all();
}
void disconnect_all()
...{
lock_block<mt_policy> lock(this);
connections_list::const_iterator it = m_connected_slots.begin();
connections_list::const_iterator itEnd = m_connected_slots.end();
while(it != itEnd)
...{
(*it)->getdest()->signal_disconnect(this);
delete *it;
++it;
}
m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
}
//disconnect为什么不放到子类?connect放在子类
//根据传入的目标对象地址,在connect_list中查找到对应的connect,
//将该connect删除,并删除list中的该地址入口,
void disconnect(has_slots<mt_policy>* pclass)
...{
lock_block<mt_policy> lock(this);
connections_list::iterator it = m_connected_slots.begin();
connections_list::iterator itEnd = m_connected_slots.end();
while(it != itEnd)
...{
if((*it)->getdest() == pclass)
...{
delete *it;
m_connected_slots.erase(it);
pclass->signal_disconnect(this); //has_slots函数
return;
}
++it;
}
}
void slot_disconnect(has_slots<mt_policy>* pslot)
...{
lock_block<mt_policy> lock(this);
connections_list::iterator it = m_connected_slots.begin();
connections_list::iterator itEnd = m_connected_slots.end();
while(it != itEnd)
Gtalk源码剖析之:sigslot介绍
class _signal_base : public mt_policy // signal基类,定义抽象接口
... {
public:
virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
} ;[ / code]_signal_base0 模板类[code]
template < class mt_policy >
class _signal_base0 : public _signal_base < mt_policy > // 带有0个参数的signal
... {
public:
typedef std::list<_connection_base0<mt_policy> *> connections_list;
_signal_base0()
...{
;
}
_signal_base0(const _signal_base0& s) //拷贝构造函数
: _signal_base<mt_policy>(s)
...{
lock_block<mt_policy> lock(this);
connections_list::const_iterator it = s.m_connected_slots.begin();
connections_list::const_iterator itEnd = s.m_connected_slots.end();
while(it != itEnd)
...{
(*it)->getdest()->signal_connect(this);
m_connected_slots.push_back((*it)->clone());
++it;
}
}
~_signal_base0()
...{
disconnect_all();
}
void disconnect_all()
...{
lock_block<mt_policy> lock(this);
connections_list::const_iterator it = m_connected_slots.begin();
connections_list::const_iterator itEnd = m_connected_slots.end();
while(it != itEnd)
...{
(*it)->getdest()->signal_disconnect(this);
delete *it;
++it;
}
m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
}
//disconnect为什么不放到子类?connect放在子类
//根据传入的目标对象地址,在connect_list中查找到对应的connect,
//将该connect删除,并删除list中的该地址入口,
void disconnect(has_slots<mt_policy>* pclass)
...{
lock_block<mt_policy> lock(this);
connections_list::iterator it = m_connected_slots.begin();
connections_list::iterator itEnd = m_connected_slots.end();
while(it != itEnd)
...{
if((*it)->getdest() == pclass)
...{
delete *it;
m_connected_slots.erase(it);
pclass->signal_disconnect(this); //has_slots函数
return;
}
++it;
}
}
void slot_disconnect(has_slots<mt_policy>* pslot)
...{
lock_block<mt_policy> lock(this);
connections_list::iterator it = m_connected_slots.begin();
connections_list::iterator itEnd = m_connected_slots.end();
while(it != itEnd)
Gtalk源码剖析之:sigslot介绍