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