예제 #1
0
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()));
}
예제 #2
0
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;
}
예제 #3
0
파일: app.cpp 프로젝트: jscissr/qlcplus
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
}
예제 #4
0
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();
}
예제 #5
0
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);
    }
}
예제 #6
0
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();
}