牵着老婆满街逛

严以律己,宽以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

libjingle翻译之《Important Concepts(重要概念)之Signals (信号)》

转载自:http://blog.csdn.net/night_cat/article/details/3495530

Important Concepts(重要概念)

你应该理解libjingle中以下的重要概念:

 Signals                                          (信号)

 Threads and Messages                     (线程、消息)

 Naming Conventions                        (命名约定)

 SSL Support                                    SSL 支持)

 Connections                                    (链接)

 Transports, Channels, and Connections (传输、通道、链接)

 Candidates                                     (协商)

 Data Packets                                   (数据包)

 

 

Signals   (信号)

libjingle 使用sigslot 促进对象间的通信。sigslot是一种framework,它可以把呼叫方(calling member)和任意类实现的接收函数很容易地关联起来,工作方式就像这样:

1、  发出呼叫的类声明一个数据成员(被称作信号),声明方式使用一种很像模板的语法。这个信号数据成员定义了和接收函数一致的参数。(注:这个接收函数当然是属于某个类了)

2、  类中的接收函数在实现时,它的参数必须与它关联的信号的参数相同,这里的参数相同是指数量相同,类型相同和次序相同。这个接收函数有时被称作receiverslot(注意:接收函数可以与信号数据成员同属一个类)。接收函数不能有返回值(可以是void)。它必须继承自sigslot::has_slots<>

3、  通过呼叫信号数据成员的connect函数,使信号数据成员与接收函数关联起来,呼叫时传递两个参数:一个是接收函数所在类的对象指针,另一个是类中的接收函数的地址。

4、  呼叫方使用信号成员就像是调用它自己的函数一样,传递给与信号成员声明时一致的参数就可以了。如果调用信号成员成功,则所有与此信号成员关联的任意类中的接收函数都会被调用。

我们可以把任意数量的信号成员与一个接收函数关系起来。libjingle有时就是把多个信号成员与一个接收函数关联起来,达到统一处理消息之目的。相反,一些类对象声明一个信号对象,是为了从一个“信号点”广播消息(“信号点”语意上讲就是一个信号成员对象,此对象关联了众多的接收函数,当此信号成员被调用时,这些接收函数都能接收到消息,即这些接收函数都被调用)。当对象(包括信号成员所在对象和传递给connect函数的接收函数所属类对象)被销毁时,sigslot库会小心处理取消关联和引用关系。

下面的代码示范了sigslot库的使用方法:

 

// Class that sends the notification.

class Sender {

// The signal declaration.

// The &apos;2&apos; in the name indicates the number of parameters. Parameter //types

// are declared in the template parameter list.

sigslot::signal2<string message, std::time_t time> SignalDanger;

// When anyone calls Panic(), we will send the SignalDanger signal.

void Panic(){

SignalDanger("Help!", std::time(0));

}

// Listening class. It must inherit sigslot.

class Receiver : public sigslot::has_slots<>{

// Receiver registers to get SignalDanger signals.

// When SignalDanger is sent, it is caught by OnDanger().

// Second parameter gives address of the listener function class definition.

// First parameter points to instance of this class to receive notifications.

Receiver(Sender sender){

sender->SignalDanger.connect(this, &Receiver.OnDanger);

}

// When anyone calls Panic(), Receiver::OnDanger gets the message.

// Notice that the number and type of parameters match

// those in Sender::SignalDanger, and that it doesn&apos;t return a value.

void Receiver::OnDanger(string message, std::time_t time){

if(message == "Help!")

{

// Call the police

...

}

}

...

}

 

Sender 类声明了一个信号数据成员:

sigslot::signal2<string message, std::time_t time> SignalDanger;

       语句中的“<string message, std::time_t time>”声明了可以与此信号成员关联的接收函数的参数形式,必须是 void functionName( string,std::time_t )形式。

       Sender类的成员数void Panic()实现中可以看到,使用信号成员的形式就像是在调用一个与信号成员同名的函数SignalDanger("Help!", std::time(0));,参数类型就是声明信号成员时指定的参数。

 

Receiver类继承自sigslot::has_slots<>,它的成员函数就具有了成为“接收函数”的“潜质”。

       Receiver的构造函数可以看出,当Receiver对象创建时,必须向它指定一个信号类(即声明了信号成员的类)对象作为构建造函数的参数,当然此信号类必须有Receiver定义的操作用到的信号成员的样式。

       一旦Receiver类对象被创建,Sender类中的信号成员就与Receiver类中的OnDanger()函数关联起来了,只要Sender对象的Panic()被调用,Receiver类对象的OnDanger()就被调用,即接收到来自Sender对象的消息,从而进行处理。

:

 

Sender sender;

Receiver  receiver(sender);

如果 运行:

sender.Panic();

receiver.OnDanger();

被自动调用,在此函数的内部就可以处理来自sender的消息。

实现了信号类与接收类之间的松偶合性。

 

libjingle库中的一些类,发送信号给接收函数(即listeners 监听者,可理解为某个类的接收函数),用来传递一些重要事件。比如:当你发出或收到一个链接尝试时,Call::SignalSessionState就会发出通知信号。在应用程序中应该有接收函数与这些信号关联起来,并且做出适当的行为。

 

按照libjingle中的约定,在声明信号数据成员时,名字被冠以“Signal”字符,比如:SignalStateChange,SignalSessionState,SignalSessionCreate

与这些信号关联的函数名被冠以“On,比如:OnPortDestropyed(),OnOutgoingMessage(),OnSendPacket();

 

关于 sigslot库的更多内容,请查看sigslot文档。

 

若有错误,请您指正,thanks!




posted on 2013-09-01 16:30 杨粼波 阅读(438) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理