QuteCom手记:使用Event类实现观察者模式
2011-07-05 23:02
465 查看
Event类的定义在qutecom\libs\owutil\util\event.h
Event继承了 boost::signal,重载了-=和+=运算符。分别对应boost::signal的disconncet和connect。
Event在PhoneCall类中的使用:
qutecom\qutecom\src\model\phonecall\phonecall.h
stateChangedEvent事件的“事件处理函数”设置:
stateChangedEvent事件的触发:
注意他们在同一上下文中执行。
Event用这种方法实现了观察者模式,CPhoneCall是观察者,PhoneCall是被观察模型。
还有CPhoneLine和PhoneLine也是如此。
关于boost::bind的文章请见:
http://blog.csdn.net/Solstice/article/details/3066268
http://www.cppblog.com/shanoa/archive/2009/06/15/87746.aspx
/** * Connects a slot to this signal (=event). * * Provides unicity when connecting a slot to a signal. * Two identical slots cannot be connected, only one will be: * this method checks first if the same slot was not connected already. * * @param slot callback function * @return connection object */ template<typename Slot> boost::signals::connection operator+=(const Slot & slot) { boost::signals::connection c; if (!alreadyConnected(slot)) { //The slot is not connected to the signal c = this->connect(slot); SlotConnection sc; sc.connection = c; sc.slot = slot; _slotList.push_back(sc); } //The slot is already connected to the signal return c; } /** * Connects a signal to another signal (=event). * * Does not check if the signal is already connected, does not * provide unicity connection. * * @param event signal to connect * @return connection object */ boost::signals::connection operator+=(const Event & event) { return this->connect(event); } /** * Disconnects a slot from a signal (=event). * * Slot comparison does not always work properly, * check http://boost.org/doc/html/function/faq.html#id2699084 * * @param slot callback function to disconnect from the signal */ template<typename Slot> void operator-=(const Slot & slot) { typename SlotList::iterator it; for (it = _slotList.begin(); it != _slotList.end(); it++) { if ((*it).slot == slot) break; } if (it != _slotList.end()) { (*it).connection.disconnect(); _slotList.erase(it); } }
Event继承了 boost::signal,重载了-=和+=运算符。分别对应boost::signal的disconncet和connect。
Event在PhoneCall类中的使用:
qutecom\qutecom\src\model\phonecall\phonecall.h
/** * The state of the PhoneCall has changed. * * @param sender this class * @param status new status */ Event<void (PhoneCall & sender, EnumPhoneCallState::PhoneCallState status)> stateChangedEvent; /** * A video frame has been received from the network. * * @param sender this class * @param remoteVideoFrame remote video frame * @param localVideoFrame local video frame from the webcam */ Event<void (PhoneCall & sender, piximage * remoteVideoFrame, piximage * localVideoFrame)> videoFrameReceivedEvent;stateChangedEvent的声明说明函数对象的原型为void (PhoneCall & sender, EnumPhoneCallState::PhoneCallState status),无返回值,第一个参数为PhoneCall对象的引用,第二个参数为一个状态码。
stateChangedEvent事件的“事件处理函数”设置:
void CPhoneCall::initPresentationThreadSafe() { _pPhoneCall = PFactory::getFactory().createPresentationPhoneCall(*this); _phoneCall.stateChangedEvent += boost::bind(&CPhoneCall::stateChangedEventHandler, this, _1, _2); _phoneCall.videoFrameReceivedEvent += boost::bind(&CPhoneCall::videoFrameReceivedEventHandler, this, _1, _2, _3); }注意boost::bind的第二参数为this指针而不能为对象,这是因为CPhoneCall的实例是不可复制对象。见CPhoneCall的声明。
stateChangedEvent事件的触发:
void PhoneCall::setState(EnumPhoneCallState::PhoneCallState state) { LOG_DEBUG("PhoneCallState=" + String::fromNumber(state)); for (unsigned i = 0; i < _phoneCallStateList.size(); i++) { PhoneCallState * callState = _phoneCallStateList[i]; if (callState->getCode() == state) { if (_state->getCode() != callState->getCode()) { _state = callState; //省略...... LOG_DEBUG("call state changed callId=" + String::fromNumber(_callId) + " state=" + EnumPhoneCallState::toString(_state->getCode())); applyState(state); stateChangedEvent(*this, state); return; } } } //LOG_FATAL("unknown PhoneCallState=" + String::fromNumber(state)); }当模型PhoneCall的实例发生状态改变时,将触发stateChangedEvent。第一参数为PhoneCall实例引用,第二参数为状态代码。由此将调用对应CPhoneCall对应实例的stateChangedEventHandler函数,并将两个参数传递给它。
注意他们在同一上下文中执行。
Event用这种方法实现了观察者模式,CPhoneCall是观察者,PhoneCall是被观察模型。
还有CPhoneLine和PhoneLine也是如此。
关于boost::bind的文章请见:
http://blog.csdn.net/Solstice/article/details/3066268
http://www.cppblog.com/shanoa/archive/2009/06/15/87746.aspx
相关文章推荐
- [置顶] 【设计模式】使用unity实现观察者模式(delegate,event)
- 使用 javascript 来实现 观察者模式
- 观察者模式学习--使用jdk的工具类简单实现
- 如何使用 Java 8 实现观察者模式
- Java使用观察者模式实现气象局高温预警功能示例
- 如何使用 Java8 实现观察者模式?(上)
- 如何使用 Java8 实现观察者模式?(上)
- PHP使用标准库spl实现的观察者模式示例
- java注解使用及使用注解实现观察者模式
- 如何使用 Java8 实现观察者模式?(上)
- RCTDeviceEventEmitter 实现简单的观察者模式
- 使用观察者模式实现Java应用程序设计MVC模式
- 如何使用委托与事件来实现观察者模式
- C#中使用委托和事件实现观察者模式(observer pattern)
- 使用 Java8 实现观察者模式的方法(下)
- Rx_java(2) 使用java中的类(Observable与Observer)实现观察者模式
- ZooKeeper学习笔记:使用zookeeper的API实现增删查改以及客户端的观察者模式
- 设计模式(二):自己动手使用“观察者模式”实现通知机制
- 使用委托和事件实现观察者模式(Observer Pattern)
- 翻译:观察者模式—使用JavaScript实现(转)