00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef CNTM_USE_QT_SS
00015
00016 #include <iostream>
00017 #include <Cntm/Synchro/QTMainSynchroSpace.h>
00018 #include <Cntm/Synchro/LoopInNoMainThreadException.h>
00019 #include <Cntm/Synchro/NoReentrantModeException.h>
00020
00021
00022
00023 bool Cntm::QTMainSynchroSpace::EventLoop::created = false;
00024
00025 int Cntm::QTMainSynchroSpace::EventLoop::enterLoop()
00026 {
00027
00028 implement->ReentrantEnter(loopLevel());
00029 int res = QEventLoop::enterLoop();
00030 implement->ReentrantLeave(loopLevel());
00031
00032 return res;
00033 }
00034
00035
00036
00037
00038 Cntm::QTMainSynchroSpace::Implement::Implement(): instance(NULL)
00039 {
00040 if (!SynchroSpace::SetMainSynchroSpaceFactory(this))
00041 throw IllegalStateException("Cntm::QTMainSynchroSpace::Prepare", "Попытка повторного создания главного синхропространства");
00042 holdInstance = SynchroSpace::Main();
00043 }
00044
00045 bool Cntm::QTMainSynchroSpace::Implement::event(QEvent* e)
00046 {
00047 switch (e->type())
00048 {
00049 case QEvent::User + 0:
00050 taskQueue.Exec();
00051 return true;
00052
00053 case QEvent::User + 1:
00054 QApplication::exit(0);
00055 return true;
00056
00057 default:
00058 return false;
00059 }
00060 }
00061
00062 Cntm::SynchroSpace::Ptr Cntm::QTMainSynchroSpace::Implement::QueryMainInstance()
00063 {
00064
00065 SynchroSpace::Ptr res = holdInstance;
00066 if (res) return res;
00067
00068
00069
00070 boost::recursive_mutex::scoped_lock lock(instanceMutex);
00071 res.SetPointer(instance);
00072 if (!res)
00073 {
00074 res = new QTMainSynchroSpace();
00075 instance = res.Pointer();
00076 }
00077 return res;
00078 }
00079
00080 void Cntm::QTMainSynchroSpace::Implement::ReentrantEnter(int Level)
00081 {
00082
00083 if (!QTMainSynchroSpace::IsMainThread())
00084 {
00085 std::cerr << "Критическая ошибка: Библиотека QT не позволяет запускать цикл обработки событий не из главного потока." << std::endl;
00086 throw LoopInNoMainThreadException("Cntm::QTMainSynchroSpace::Implement::ReentrantEnter", "Библиотека QT не позволяет запускать цикл обработки событий не из главного потока");
00087 }
00088
00089
00090 SynchroSpace::Ptr space = SynchroSpace::Main();
00091 if (space && !space->IsReentrantMode())
00092 {
00093 std::cerr << "Критическая ошибка: Запуск цикла обработки событий QT когда вход в главное синхропространство произведен не в REENTRANT режиме." << std::endl;
00094 throw NoReentrantModeException("Cntm::QTMainSynchroSpace::Implement::ReentrantEnter", "Запуск цикла обработки событий QT когда вход в главное синхропространство произведен не в REENTRANT режиме");
00095 }
00096
00097
00098 QApplication::postEvent(this, new QEvent(QEvent::Type(QEvent::User + 0)));
00099
00100
00101 qApp->unlock();
00102 }
00103
00104 void Cntm::QTMainSynchroSpace::Implement::ReentrantLeave(int Level)
00105 {
00106
00107 qApp->lock();
00108 }
00109
00110 void Cntm::QTMainSynchroSpace::Implement::Start()
00111 {
00112
00113
00114 qApp->lock();
00115 }
00116
00117 void Cntm::QTMainSynchroSpace::Implement::Finish()
00118 {
00119 holdInstance.SetNull();
00120 while (instance) qApp->exec();
00121 qApp->unlock();
00122 }
00123
00124 void Cntm::QTMainSynchroSpace::Implement::MainInstanceDeleted(QTMainSynchroSpace* Inst)
00125 {
00126
00127
00128
00129 boost::recursive_mutex::scoped_lock lock(instanceMutex);
00130 if (instance == Inst)
00131 {
00132 instance = NULL;
00133 QApplication::postEvent(this, new QEvent(QEvent::Type(QEvent::User + 1)));
00134 }
00135 }
00136
00137
00138
00139
00140 Cntm::QTMainSynchroSpace::Implement* Cntm::QTMainSynchroSpace::implement;
00141
00142 void Cntm::QTMainSynchroSpace::Prepare()
00143 {
00144 EventLoop::CreateEventLoop();
00145 implement = new Implement;
00146 }
00147
00148 #endif //CNTM_USE_QT_SS