class RAILCORESHARED_EXPORT CAbstractEvent : public QEvent{ QString fsenderTag; //кто отправляет (записывает отправитель свой tag) QStringList fdestinationTag; //кто должен получить (tag приемника, можеть быть больше одного) QVariantHash fvarData; //где хранятся параметрыpublic: static const int customType = 1003; CAbstractEvent(QEvent::Type InitType); const QString & senderTag() const; const QStringList & destiantionTag()const; const QVariantHash & varData() const; void setSenderTag(const QString & Value); void setDestinationTag(const QStringList & Value); void setVarData(const QVariantHash & Value);};
bool CMVCEventProxy::event(QEvent *e){ qDebug("type %d",e->type()); if(e->type() == static_cast<QEvent::Type>(CAbstractEvent::customType)) { CAbstractEvent * abstractEvent = static_cast<CAbstractEvent*>(e); { CAbstractSceneAction * targetSceneAction; CGenericRailController * targetRailController; foreach(const QString & currentDestinationTag, abstractEvent->destiantionTag()) { //сначала смотрим по action в качестве адресата if((targetSceneAction = factionsHash.value(currentDestinationTag,NULL))) { QApplication::postEvent(targetSceneAction,abstractEvent); //отправляем событие дальше на сцену continue; } if((targetRailController = fcontrollersHash.value(currentDestinationTag,NULL))) { QApplication::postEvent(targetRailController,abstractEvent); //отправляем контроллеру continue; } } } return false; } else return QObject::event(e);}
...if(manevrWasChanged && !lightObject->manevrDestination().isEmpty()) { CAbstractEvent * setupManevrRouteEvent = new CAbstractEvent(static_cast<QEvent::Type>(CAbstractEvent::customType)); setupManevrRouteEvent->setSenderTag(tag()); destinations<<"com.action.dsp.manevr_route"; //это кто должен словить это соыбтие destinations<<"com.action.dsp.manevr_route_auto"; QVariantHash params; params["begin_light"] = lightObject->objectId(); params["end_light"] = lightObject->manevrDestination(); setupManevrRouteEvent->setVarData(params); setupManevrRouteEvent->setDestinationTag(destinations); qDebug("postEvent"); QApplication::postEvent(eventProxy(),setupManevrRouteEvent); } else ...
#include <QString>class CAbstractEvent;class CMVCEventProxy;class CAbstractEventInterface{ CMVCEventProxy * feventProxy;protected: virtual void attachEventProxy(); //обработчик привяки диспетчера событий virtual void detachEventProxy(); //обработчик отвязки virtual void receiveMVCEvent(CAbstractEvent * event); //обработчки приёма события void sendEvent(CAbstractEvent * event); //отправка события virtual void acceptEvent(CAbstractEvent * event); //принять событие friend class CMVCEventProxy;public: CAbstractEventInterface(); virtual const QString & tag() const = 0; //тег объекта (может выступать адресом применика, и адресом отправителя) void setEventProxy(CMVCEventProxy * EventProxyObject); //установка проки const CMVCEventProxy * eventProxyObject() const; //получение прокси};
#include "cabstracteventinterface.h"#include "cabstractevent.h"#include "cmvceventproxy.h"CAbstractEventInterface::CAbstractEventInterface(){ feventProxy = NULL;}void CAbstractEventInterface::setEventProxy(CMVCEventProxy *EventProxyObject){ if(feventProxy!=EventProxyObject) { if(feventProxy) detachEventProxy(); feventProxy = EventProxyObject; if(feventProxy) attachEventProxy(); }}const CMVCEventProxy *CAbstractEventInterface::eventProxyObject() const{ return feventProxy;}void CAbstractEventInterface::sendEvent(CAbstractEvent *event){ if(feventProxy) { feventProxy->sendEvent(event); }}void CAbstractEventInterface::acceptEvent(CAbstractEvent *event){ Q_UNUSED(event)}void CAbstractEventInterface::attachEventProxy(){}void CAbstractEventInterface::detachEventProxy(){}void CAbstractEventInterface::receiveMVCEvent(CAbstractEvent *event){ Q_UNUSED(event)}
#include <QObject>#include <QHash>#include "cabstracteventinterface.h"class CAbstractEvent;class CAbstractArmLogic;class CMVCEventProxy : public QObject{Q_OBJECT QHash<QString, CAbstractEventInterface*> fsubscribedObjects; //подписчики на событияprotected:public: explicit CMVCEventProxy(QObject *parent = 0); ~CMVCEventProxy(); bool sendEvent(CAbstractEvent * event); //отправка события void subscribeObjectForEventReceiving(const QString & address, CAbstractEventInterface * InterfaceObject); //подписывает объект на приём событий void unsubscribeObjectFromEventReceiving(const QString & address); //отписывает объект по адерсу void unsubscribeObjectFromEventReceiving(CAbstractEventInterface * InterfaceObject); //отписывает объект по интерфейсу};
#include "cmvceventproxy.h"#include "cabstractevent.h"CMVCEventProxy::CMVCEventProxy(QObject *parent) : QObject(parent){}CMVCEventProxy::~CMVCEventProxy(){}bool CMVCEventProxy::sendEvent(CAbstractEvent *event){ if(!event || event->destiantionTag().isEmpty()) return false; qDebug("CMVCEventProxy::sendEvent"); CAbstractEventInterface * interface; foreach(const QString & destination, event->destiantionTag()) { if((interface = fsubscribedObjects.value(destination,NULL))) { interface->acceptEvent(event); } } delete event; return true;}void CMVCEventProxy::subscribeObjectForEventReceiving(const QString &address, CAbstractEventInterface *InterfaceObject){ if(address.isEmpty() || !InterfaceObject) return; qDebug("subscribeObjectForEventReceiving %s",qPrintable(address)); CAbstractEventInterface * oldInterface = fsubscribedObjects.value(address,NULL); if(oldInterface) oldInterface->setEventProxy(NULL); InterfaceObject->setEventProxy(this); fsubscribedObjects[address] = InterfaceObject;}void CMVCEventProxy::unsubscribeObjectFromEventReceiving(const QString &address){ qDebug("unsubscribeObjectFromEventReceiving %s",qPrintable(address)); CAbstractEventInterface * oldInterface = fsubscribedObjects.value(address,NULL); if(oldInterface) oldInterface->setEventProxy(NULL); fsubscribedObjects.remove(address);}void CMVCEventProxy::unsubscribeObjectFromEventReceiving(CAbstractEventInterface *InterfaceObject){ for(QHash<QString, CAbstractEventInterface*>::iterator it = fsubscribedObjects.begin(); it!= fsubscribedObjects.end(); it++) { if(it.value() == InterfaceObject) { unsubscribeObjectFromEventReceiving(it.key()); break; } }}
if(manevrWasChanged && !lightObject->manevrDestination().isEmpty()) { CAbstractEvent * setupManevrRouteEvent = new CAbstractEvent("com.event.route.setup.manevr"); setupManevrRouteEvent->setSenderTag(tag()); destinations<<"com.action.dsp.manevr_route"; destinations<<"com.action.dsp.manevr_route_auto"; QVariantHash params; params["begin_light"] = lightObject->objectId(); params["end_light"] = lightObject->manevrDestination(); setupManevrRouteEvent->setVarData(params); setupManevrRouteEvent->setDestinationTag(destinations); sendEvent(setupManevrRouteEvent); }
void CSetupRouteAction::acceptEvent(CAbstractEvent *event){//на самом деле тут данные из соыбтия обрабатываются, но для простоты просто подвтерждаем что сделано doneAction();}