Monitor::Monitor(QWidget* parent, Doc* doc, Qt::WindowFlags f) : QWidget(parent, f) , m_doc(doc) , m_props(NULL) , m_toolBar(NULL) , m_scrollArea(NULL) , m_monitorWidget(NULL) , m_monitorLayout(NULL) , m_currentUniverse(Universe::invalid()) , m_splitter(NULL) , m_graphicsView(NULL) , m_fixtureItemEditor(NULL) , m_gridWSpin(NULL) , m_gridHSpin(NULL) , m_unitsCombo(NULL) , m_labelsAction(NULL) { Q_ASSERT(doc != NULL); m_props = m_doc->monitorProperties(); /* Master layout for toolbar and scroll area */ new QVBoxLayout(this); initView(); /* Listen to fixture additions and changes from Doc */ connect(m_doc, SIGNAL(fixtureAdded(quint32)), this, SLOT(slotFixtureAdded(quint32))); connect(m_doc, SIGNAL(fixtureChanged(quint32)), this, SLOT(slotFixtureChanged(quint32))); connect(m_doc, SIGNAL(fixtureRemoved(quint32)), this, SLOT(slotFixtureRemoved(quint32))); connect(m_doc->masterTimer(), SIGNAL(functionStarted(quint32)), this, SLOT(slotFunctionStarted(quint32))); connect(m_doc->inputOutputMap(), SIGNAL(universesWritten(int, const QByteArray&)), this, SLOT(slotUniversesWritten(int, const QByteArray&))); }
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(); }