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]

_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]

_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)
   
{
    connections_list::iterator itNext 
= it;
    
++itNext;
    
if((*it)->getdest() == pslot)
    
{
     m_connected_slots.erase(it);
     
//   delete *it;
    }

    it 
= itNext;
   }

  }

  
void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
  
{
   lock_block
<mt_policy> lock(this);
   connections_list::iterator it 
= m_connected_slots.begin();
   connections_list::iterator itEnd 
= m_connected_slots.end();
            
            
//遍历conncet列表
   while(it != itEnd)
   
{
       
//如果某个connect->getdest()为oldtarget,则替换为newtarget
    if((*it)->getdest() == oldtarget)
    
{
     m_connected_slots.push_back((
*it)->duplicate(newtarget));//生成一个新的connect
    }

    
++it;
   }

  }

protected:
  connections_list m_connected_slots;   
//connect列表
}
;[ / code]

signal0模板类

[code] /*signal0/signal1 真正的信号类*/
template
< class  mt_policy  =  SIGSLOT_DEFAULT_MT_POLICY >
class  signal0 :  public  _signal_base0 < mt_policy >
{
public:
  signal0()
  
{
   ;
  }

  signal0(
const signal0<mt_policy>& s)
   : _signal_base0
<mt_policy>(s)
  
{
   ;
  }

        
        
//不需要模板函数,应该更强的校验:desttype-->has_slots<mt_policy>
  template<class desttype>
   
void connect(desttype* pclass, void (desttype::*pmemfun)())
  
{
   lock_block
<mt_policy> lock(this);
   _connection0
<desttype, mt_policy>* conn = 
    
new _connection0<desttype, mt_policy>(pclass, pmemfun); //创建一个connect对象
   m_connected_slots.push_back(conn);                          //放入connect列表
   
//调用对象的signal_connect函数,而该对象必须继承自has_slots
   
//has_slots函数
   pclass->signal_connect(this);     //将this-signal插入到对象的sender集合中
  }

        
//发送消息,同operator()()
  void emit()
  
{
   lock_block
<mt_policy> lock(this);
   connections_list::const_iterator itNext, it 
= m_connected_slots.begin();
   connections_list::const_iterator itEnd 
= m_connected_slots.end();
   
while(it != itEnd)
   
{
    itNext 
= it;
    
++itNext;
    (
*it)->emit();
    it 
= itNext;
   }

  }

        
        
//发送消息,对connect_list中记录的每个connect调用目标对象的回调函数
  void operator()()
  
{
   lock_block
<mt_policy> lock(this);
   connections_list::const_iterator itNext, it 
= m_connected_slots.begin();
   connections_list::const_iterator itEnd 
= m_connected_slots.end();
   
while(it != itEnd)
   
{
    itNext 
= it;
    
++itNext;
    (
*it)->emit();
    it 
= itNext;
   }

  }

}
;[ / code]

 

作者:vt.buxiu@www.vtzone.org

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值