#include "PrtCnvApplication.hpp" #include "PrtCnvThreadStarter.hpp" #include "PrtCnvThread.hpp" #include "PrtCnvCentralThread.hpp" #include "PrtCnvTelegramLogThread.hpp" #include #include #include #include #include #include #include namespace PrtCnv { static std::string threadIdToString(PrtCnvApplication::E_ThreadId id) { switch (id) { case PrtCnvApplication::e_Central: return "Central"; case PrtCnvApplication::e_Radio: return "Radio"; case PrtCnvApplication::e_Db: return "Db"; case PrtCnvApplication::e_Log: return "Log"; case PrtCnvApplication::e_Injection: return "Injection"; case PrtCnvApplication::e_RadioTraffic: return "RadioTraffic"; case PrtCnvApplication::e_ThreadIdMax: break; } return std::to_string(id); } PrtCnvApplication::PrtCnvApplication() : m_Config(nullptr) , m_exerciseId(0) , m_accessMutex(QMutex::Recursive) , m_logger(getLogger("PrtCnvApplication")) {} PrtCnvApplication::~PrtCnvApplication() { delete m_Config; for (const auto &ti : m_threadInfo) delete ti.thread; } void PrtCnvApplication::waitForCreate(const E_ThreadId a_threadId) { INFO_LOG(m_logger) << "Wait for others until we can create " << threadIdToString(a_threadId); setConstructed(a_threadId); switch (a_threadId) { case e_Central: while (!(isConstructed(e_Db) && isConstructed(e_Radio) && isConstructed(e_Log) && isConstructed(e_Injection))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_Radio: while (!(isConstructed(e_Db) && isConstructed(e_Central) && isConstructed(e_Log) && isConstructed(e_Injection))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_Db: while (!(isConstructed(e_Radio) && isConstructed(e_Central))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; default: break; } INFO_LOG(m_logger) << "Now we can create " << threadIdToString(a_threadId); } void PrtCnvApplication::waitForInit(E_ThreadId a_threadId) { INFO_LOG(m_logger) << "Wait for others until we can initialize " << threadIdToString(a_threadId); setCreated(a_threadId); switch (a_threadId) { case e_Central: while (!(isCreated(e_Db) && isCreated(e_Radio))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_Radio: while (!(isCreated(e_Db) && isCreated(e_Central))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_Db: while (!(isCreated(e_Radio) && isCreated(e_Central))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; default: break; } INFO_LOG(m_logger) << "Now we can initialize " << threadIdToString(a_threadId); } void PrtCnvApplication::waitForStart(E_ThreadId a_threadId) { INFO_LOG(m_logger) << "Wait for others until we can start " << threadIdToString(a_threadId); setInitialized(a_threadId); switch (a_threadId) { case e_Central: while (!(isStarted(e_Db) && isInitialized(e_Radio) && isStarted(e_Log) && isStarted(e_Injection))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_Radio: while (!(isStarted(e_Db) && isInitialized(e_Central) && isStarted(e_Log) && isStarted(e_Injection) && isInitialized(e_RadioTraffic))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_Db: while (!(isInitialized(e_Radio) && isInitialized(e_Central) && isStarted(e_Log))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; case e_RadioTraffic: while (!(isInitialized(e_Radio) && isStarted(e_Log))) { DEBUG_LOG(m_logger) << "wait..."; QThread::sleep(1); } break; default: break; } INFO_LOG(m_logger) << "Now we can start " << threadIdToString(a_threadId); } void PrtCnvApplication::waitForExec(E_ThreadId a_threadId) { setStarted(a_threadId); } void PrtCnvApplication::startApp() { createApplication(); init(); start(); } void PrtCnvApplication::shutdownApp() { stop(); deinit(); destroy(); for (const auto &ti : m_threadInfo) ti.thread->quit(); for (const auto &ti : m_threadInfo) ti.thread->wait(); for (auto &ti : m_threadInfo) { delete ti.thread; ti.thread = nullptr; } } void PrtCnvApplication::setCleanDb(bool bCleanDb) { PrtCnvThread::m_DoCleanDb = bCleanDb; } void PrtCnvApplication::setExerciseId(int exerciseId) { m_exerciseId = exerciseId; } void PrtCnvApplication::setConfigFile(const QString &configFile) { m_ConfigFileName = configFile; } int32_t PrtCnvApplication::createApplication() { setName(QStringLiteral("Common")); if (m_ConfigFileName.isEmpty()) { m_ConfigFileName = QCoreApplication::applicationDirPath(); if (m_exerciseId > 0) m_ConfigFileName += QStringLiteral("/PrtCnv_ex_") + QString::number(m_exerciseId) + QStringLiteral(".dat"); else m_ConfigFileName += QStringLiteral("/PrtCnv.dat"); } m_Config = new NGL::Settings(m_ConfigFileName); std::cout << "Use config-file: " << qPrintable(m_ConfigFileName) << std::endl; for (int i = 0; i < e_ThreadIdMax; i++) m_threadInfo[i].thread = new PrtCnvThreadStarter((E_ThreadId)i, m_ConfigFileName, this); N_AppComponent::AppComponent::create(m_Config); return 0; } int32_t PrtCnvApplication::start() { for (const auto &ti : m_threadInfo) ti.thread->start(); N_AppComponent::AppComponent::start(); return 0; } PrtCnv::PrtCnvThreadStarter *PrtCnvApplication::getThreadStarter(const E_ThreadId a_threadId) { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return nullptr; QMutexLocker l(&m_accessMutex); return m_threadInfo[a_threadId].thread; } void PrtCnvApplication::setDatabaseConnectionParams(const QString &driver, const QString &hostName, const QString &database, const QString &schemaName, const QString &userName, const QString &password) { m_dbDriver = driver; m_dbHostName = hostName; m_dbDatabaseName = database; m_dbSchemaName = schemaName; m_dbUserName = userName; m_dbPassword = password; } void PrtCnvApplication::logWlsTelegram(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *tele, bool bIsSend) { const auto threadHandler = m_threadInfo[e_Log].thread; PrtCnvTelegramLogThread *t = static_cast(threadHandler ? threadHandler->getThread() : nullptr); if (t) t->writeWlsTelegramLog(tele, bIsSend, 0); } bool PrtCnvApplication::isConstructed(const E_ThreadId a_threadId) const { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return false; QMutexLocker l(&m_accessMutex); return m_threadInfo[a_threadId].isConstructed; } void PrtCnvApplication::setConstructed(const E_ThreadId a_threadId) { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return; QMutexLocker l(&m_accessMutex); m_threadInfo[a_threadId].isConstructed = true; } bool PrtCnvApplication::isInitialized(const E_ThreadId a_threadId) const { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return false; QMutexLocker l(&m_accessMutex); return m_threadInfo[a_threadId].isInitialized; } void PrtCnvApplication::setInitialized(const E_ThreadId a_threadId) { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return; QMutexLocker l(&m_accessMutex); m_threadInfo[a_threadId].isInitialized = true; } bool PrtCnvApplication::isCreated(const E_ThreadId a_threadId) const { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return false; QMutexLocker l(&m_accessMutex); return m_threadInfo[a_threadId].isCreated; } void PrtCnvApplication::setCreated(const E_ThreadId a_threadId) { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return; QMutexLocker l(&m_accessMutex); m_threadInfo[a_threadId].isCreated = true; } bool PrtCnvApplication::isStarted(const E_ThreadId a_threadId) const { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return false; QMutexLocker l(&m_accessMutex); return m_threadInfo[a_threadId].isStarted; } void PrtCnvApplication::setStarted(const E_ThreadId a_threadId) { if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax) return; QMutexLocker l(&m_accessMutex); m_threadInfo[a_threadId].isStarted = true; } }