void AbstractDb::registerAllFunctions() { for (const RegisteredFunction& regFn : registeredFunctions) { if (!deregisterFunction(regFn.name, regFn.argCount)) qWarning() << "Failed to deregister custom SQL function:" << regFn.name; } registeredFunctions.clear(); RegisteredFunction regFn; for (FunctionManager::ScriptFunction* fnPtr : FUNCTIONS->getScriptFunctionsForDatabase(getName())) { regFn.argCount = fnPtr->undefinedArgs ? -1 : fnPtr->arguments.count(); regFn.name = fnPtr->name; regFn.type = fnPtr->type; registerFunction(regFn); } for (FunctionManager::NativeFunction* fnPtr : FUNCTIONS->getAllNativeFunctions()) { regFn.argCount = fnPtr->undefinedArgs ? -1 : fnPtr->arguments.count(); regFn.name = fnPtr->name; regFn.type = fnPtr->type; registerFunction(regFn); } disconnect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerAllFunctions())); connect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerAllFunctions())); }
bool AbstractDb::closeQuiet() { QWriteLocker locker(&dbOperLock); QWriteLocker connectionLocker(&connectionStateLock); interruptExecution(); bool res = closeInternal(); clearAttaches(); registeredFunctions.clear(); registeredCollations.clear(); if (FUNCTIONS) // FUNCTIONS is already null when closing db while closing entire app disconnect(FUNCTIONS, SIGNAL(functionListChanged()), this, SLOT(registerAllFunctions())); return res; }
void App::init() { QSettings settings; setWindowIcon(QIcon(":/qlcplus.png")); m_tab = new QTabWidget(this); m_tab->setTabPosition(QTabWidget::South); setCentralWidget(m_tab); QLCFile::checkRaspberry(); QVariant var = settings.value(SETTINGS_GEOMETRY); if (var.isValid() == true) { this->restoreGeometry(var.toByteArray()); } else { /* Application geometry and window state */ QSize size = settings.value("/workspace/size").toSize(); if (size.isValid() == true) resize(size); else { if (QLCFile::isRaspberry()) { QRect geometry = qApp->desktop()->availableGeometry(); if (m_noGui == true) { setGeometry(geometry.width(), geometry.height(), 1, 1); } else { int w = geometry.width(); int h = geometry.height(); if (m_overscan == true) { // if we're on a Raspberry Pi, introduce a 5% margin w = (float)geometry.width() * 0.95; h = (float)geometry.height() * 0.95; } setGeometry((geometry.width() - w) / 2, (geometry.height() - h) / 2, w, h); } } else resize(800, 600); } QVariant state = settings.value("/workspace/state", Qt::WindowNoState); if (state.isValid() == true) setWindowState(Qt::WindowState(state.toInt())); } QVariant dir = settings.value(SETTINGS_WORKINGPATH); if (dir.isValid() == true) m_workingDirectory = QDir(dir.toString()); // The engine object initDoc(); // Main view actions initActions(); // Main tool bar initToolBar(); m_dumpProperties = new DmxDumpFactoryProperties(KUniverseCount); // Create primary views. m_tab->setIconSize(QSize(24, 24)); QWidget* w = new FixtureManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/fixture.png"), tr("Fixtures")); w = new FunctionManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/function.png"), tr("Functions")); w = new ShowManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/show.png"), tr("Shows")); w = new VirtualConsole(m_tab, m_doc); m_tab->addTab(w, QIcon(":/virtualconsole.png"), tr("Virtual Console")); w = new SimpleDesk(m_tab, m_doc); m_tab->addTab(w, QIcon(":/slidermatrix.png"), tr("Simple Desk")); w = new InputOutputManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/input_output.png"), tr("Inputs/Outputs")); // Listen to blackout changes and toggle m_controlBlackoutAction connect(m_doc->inputOutputMap(), SIGNAL(blackoutChanged(bool)), this, SLOT(slotBlackoutChanged(bool))); // Listen to DMX value changes and update each Fixture values array connect(m_doc->inputOutputMap(), SIGNAL(universesWritten(int, const QByteArray&)), this, SLOT(slotUniversesWritten(int, const QByteArray&))); // Enable/Disable panic button connect(m_doc->masterTimer(), SIGNAL(functionListChanged()), this, SLOT(slotRunningFunctionsChanged())); slotRunningFunctionsChanged(); // Start up in non-modified state m_doc->resetModified(); QString ssDir; #if defined(WIN32) || defined(Q_OS_WIN) /* User's input profile directory on Windows */ LPTSTR home = (LPTSTR) malloc(256 * sizeof(TCHAR)); GetEnvironmentVariable(TEXT("UserProfile"), home, 256); ssDir = QString("%1/%2").arg(QString::fromUtf16(reinterpret_cast<ushort*> (home))) .arg(USERQLCPLUSDIR); free(home); HotPlugMonitor::setWinId(winId()); #else /* User's input profile directory on *NIX systems */ ssDir = QString("%1/%2").arg(getenv("HOME")).arg(USERQLCPLUSDIR); #endif QFile ssFile(ssDir + QDir::separator() + "qlcplusStyle.qss"); if (ssFile.exists() == true) { ssFile.open(QFile::ReadOnly); QString styleSheet = QLatin1String(ssFile.readAll()); this->setStyleSheet(styleSheet); } #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) m_videoProvider = new VideoProvider(m_doc, this); #endif }
void App::init() { QSettings settings; setWindowIcon(QIcon(":/qlcplus.png")); m_tab = new QTabWidget(this); m_tab->setTabPosition(QTabWidget::South); setCentralWidget(m_tab); QVariant var = settings.value(SETTINGS_GEOMETRY); if (var.isValid() == true) { this->restoreGeometry(var.toByteArray()); } else { /* Application geometry and window state */ QSize size = settings.value("/workspace/size").toSize(); if (size.isValid() == true) resize(size); else resize(800, 600); QVariant state = settings.value("/workspace/state", Qt::WindowNoState); if (state.isValid() == true) setWindowState(Qt::WindowState(state.toInt())); } // The engine object initDoc(); // Main view actions initActions(); // Main tool bar initToolBar(); // Create primary views. m_tab->setIconSize(QSize(24, 24)); QWidget* w = new FixtureManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/fixture.png"), tr("Fixtures")); w = new FunctionManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/function.png"), tr("Functions")); w = new ShowManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/show.png"), tr("Shows")); w = new VirtualConsole(m_tab, m_doc); m_tab->addTab(w, QIcon(":/virtualconsole.png"), tr("Virtual Console")); w = new SimpleDesk(m_tab, m_doc); m_tab->addTab(w, QIcon(":/slidermatrix.png"), tr("Simple Desk")); w = new InputOutputManager(m_tab, m_doc); m_tab->addTab(w, QIcon(":/input_output.png"), tr("Inputs/Outputs")); // Listen to blackout changes and toggle m_controlBlackoutAction connect(m_doc->outputMap(), SIGNAL(blackoutChanged(bool)), this, SLOT(slotBlackoutChanged(bool))); // Enable/Disable panic button connect(m_doc->masterTimer(), SIGNAL(functionListChanged()), this, SLOT(slotRunningFunctionsChanged())); slotRunningFunctionsChanged(); // Start up in non-modified state m_doc->resetModified(); }
void MasterTimer::timerTickFunctions(UniverseArray* universes) { // List of m_functionList indices that should be removed at the end of this // function. The functions at the indices have been stopped. QList <int> removeList; /* Lock before accessing the running functions list. */ m_functionListMutex.lock(); for (int i = 0; i < m_functionList.size(); i++) { Function* function = m_functionList.at(i); /* No need to access function list on this round anymore */ m_functionListMutex.unlock(); if (function != NULL) { /* Run the function unless it's supposed to be stopped */ if (function->stopped() == false && m_stopAllFunctions == false) function->write(this, universes); if (function->stopped() == true || m_stopAllFunctions == true) { /* Function should be stopped instead */ m_functionListMutex.lock(); function->postRun(this, universes); //qDebug() << "[MasterTimer] Add function (ID: " << function->id() << ") to remove list "; removeList << i; // Don't remove the item from the list just yet. m_functionListMutex.unlock(); emit functionListChanged(); } } /* Lock function list for the next round. */ m_functionListMutex.lock(); } // Remove functions that need to be removed AFTER all functions have been run // for this round. This is done separately to prevent a case when a function // is first removed and then another is added (chaser, for example), keeping the // list's size the same, thus preventing the last added function from being run // on this round. The indices in removeList are automatically sorted because the // list is iterated with an int above from 0 to size, so iterating the removeList // backwards here will always remove the correct indices. QListIterator <int> it(removeList); it.toBack(); while (it.hasPrevious() == true) m_functionList.removeAt(it.previous()); /* No more functions. Get out and wait for next timer event. */ m_functionListMutex.unlock(); foreach (Function* f, m_startQueue) { //qDebug() << "[MasterTimer] Processing ID: " << f->id(); if (m_functionList.contains(f) == false) { m_functionListMutex.lock(); m_functionList.append(f); m_functionListMutex.unlock(); //qDebug() << "[MasterTimer] Starting up ID: " << f->id(); f->preRun(this); f->write(this, universes); emit functionListChanged(); } m_startQueue.removeOne(f); } }
void MasterTimer::timerTickFunctions(QList<Universe *> universes) { // List of m_functionList indices that should be removed at the end of this // function. The functions at the indices have been stopped. QList<int> removeList; bool functionListHasChanged = false; bool stoppedAFunction = true; bool firstIteration = true; while (stoppedAFunction) { stoppedAFunction = false; removeList.clear(); for (int i = 0; i < m_functionList.size(); i++) { Function* function = m_functionList.at(i); if (function != NULL) { /* Run the function unless it's supposed to be stopped */ if (function->stopped() == false && m_stopAllFunctions == false) { if (firstIteration) function->write(this, universes); } else { // Clear function's parentList if (m_stopAllFunctions) function->stop(FunctionParent::master()); /* Function should be stopped instead */ function->postRun(this, universes); //qDebug() << "[MasterTimer] Add function (ID: " << function->id() << ") to remove list "; removeList << i; // Don't remove the item from the list just yet. functionListHasChanged = true; stoppedAFunction = true; } } } // Remove functions that need to be removed AFTER all functions have been run // for this round. This is done separately to prevent a case when a function // is first removed and then another is added (chaser, for example), keeping the // list's size the same, thus preventing the last added function from being run // on this round. The indices in removeList are automatically sorted because the // list is iterated with an int above from 0 to size, so iterating the removeList // backwards here will always remove the correct indices. QListIterator <int> it(removeList); it.toBack(); while (it.hasPrevious() == true) m_functionList.removeAt(it.previous()); firstIteration = false; } m_functionListMutex.lock(); while (m_startQueue.size() > 0) { QList<Function*> startQueue(m_startQueue); m_startQueue.clear(); m_functionListMutex.unlock(); foreach (Function* f, startQueue) { if (m_functionList.contains(f)) { f->postRun(this, universes); } else { m_functionList.append(f); functionListHasChanged = true; } f->preRun(this); f->write(this, universes); emit functionStarted(f->id()); } m_functionListMutex.lock(); } m_functionListMutex.unlock(); if (functionListHasChanged) emit functionListChanged(); }