Esempio n. 1
0
void Interpreter::handlePendingCommand()
{
    QMutexLocker locker(&m_mutexQueue);
    if (m_commandQueue.empty())
        return;
    const Command command = m_commandQueue.front();
    m_commandQueue.pop();
    locker.unlock();

    switch (command.first)
    {
    case STOP:
        sendStop();
        break;

    case RUN:
        sendRun();
        break;

    case GET_ACTION:
        sendGetAction(command.second.toInt());
        break;

    case LOAD_PARAMS:
        handleLoadParams();
        break;

    case SAVE_PARAMS:
        handleSaveParams();
        break;
    }

}
void Interpreter::run()
{
    int res;
    QTime time;
    QString paramScriptlet;

    // init
    try
    {
        int i;
        ChirpProc versionProc;
        uint16_t *ver;
        uint32_t verLen, responseInt;

        if (m_link.open()<0)
            throw std::runtime_error("Unable to open USB device.");
        m_chirp = new ChirpMon(this, &m_link);        

        // get version and compare
        versionProc = m_chirp->getProc("version");
        if (versionProc<0)
            throw std::runtime_error("Can't get firmware version.");
        res = m_chirp->callSync(versionProc, END_OUT_ARGS, &responseInt, &verLen, &ver, END_IN_ARGS);
        if (res<0)
            throw std::runtime_error("Can't get firmware version.");
        memcpy(m_version, ver, 3*sizeof(uint16_t));
        emit version(m_version[0], m_version[1], m_version[2]);
        if (m_version[0]!=VER_MAJOR || m_version[1]>VER_MINOR)
        {
            char buf[0x100];
            sprintf(buf, "This Pixy's firmware version (%d.%d.%d) is not compatible with this PixyMon version (%d.%d.%d).",
                    m_version[0], m_version[1], m_version[2], VER_MAJOR, VER_MINOR, VER_BUILD);
            throw std::runtime_error(buf);
        }

        m_exec_run = m_chirp->getProc("run");
        m_exec_running = m_chirp->getProc("running");
        m_exec_stop = m_chirp->getProc("stop");
        m_exec_get_action = m_chirp->getProc("getAction");
        m_get_param = m_chirp->getProc("prm_get");
        m_getAll_param = m_chirp->getProc("prm_getAll");
        m_set_param = m_chirp->getProc("prm_set");
        m_reload_params = m_chirp->getProc("prm_reload");
        m_set_shadow_param = m_chirp->getProc("prm_setShadow");
        m_reset_shadows = m_chirp->getProc("prm_resetShadows");

        if (m_exec_run<0 || m_exec_running<0 || m_exec_stop<0 || m_exec_get_action<0 ||
                m_get_param<0 || m_getAll_param<0 || m_set_param<0 || m_reload_params<0 ||
                m_set_shadow_param<0 || m_reset_shadows<0)
            throw std::runtime_error("Hmm... missing procedures.");

        // create pixymon modules
        m_modules.push_back(m_renderer); // add renderer to monmodule list so we can send it updates, etc
        MonModuleUtil::createModules(&m_modules, this);
        // reload any parameters that the mon modules might have created
        m_pixymonParameters->load();
        // notify mon modules of parameter change
        sendMonModulesParamChange();
        // load debug
        m_pixymonParameters->clean();

        // get all actions
        for (i=0; sendGetAction(i)>=0; i++);
    }
    catch (std::runtime_error &exception)
    {
        emit error(QString(exception.what()) + '\n');
        return;
    }
    DBG("*** init done");

    time.start();
    getRunning();
    paramScriptlet = m_pixymonParameters->value("Pixy start command").toString();
    paramScriptlet.remove(QRegExp("^\\s+")); // remove initial whitespace
    handleLoadParams(); // load params upon initialization
    if (m_initScript!="")
        execute(parseScriptlet(m_initScript));
    else if (paramScriptlet!="")
        execute(paramScriptlet);


    while(m_run)
    {
        // poll to see if we're still connected
        if (!m_programming &&
                ((m_fastPoll && time.elapsed()>RUN_POLL_PERIOD_FAST) ||
                (!m_fastPoll && time.elapsed()>RUN_POLL_PERIOD_SLOW)))
        {
            getRunning();
            time.start();
        }
        // service chirps -- but if we're running a local program it just slows things down
        else if (!m_localProgramRunning)
        {
            m_chirp->service(false);
            msleep(1); // give config thread time to run
        }
        handlePendingCommand();
        handleLocalProgram();
        if (!m_running && !m_localProgramRunning)
        {
            emit enableConsole(true);
            Sleeper::msleep(10);
            if (m_mutexProg.tryLock())
            {
                if (m_argv.size())
                {
                    if (m_argv[0]=="help")
                        handleHelp();
                    else
                    {
                        res = call(m_argv, true);
                        if (res<0)
                        {
                            if (m_programming)
                            {
                                endLocalProgram();
                                clearLocalProgram();
                            }
                            m_commandList.clear(); // abort our little scriptlet
                        }
                    }
                    m_argv.clear();
                    // check quickly to see if we're running after this command
                    if (!m_programming)
                        getRunning();
                    // is there another command in our little scriptlet?
                    if (m_commandList.size())
                    {
                        execute(m_commandList[0]);
                        m_commandList.removeFirst();
                    }
                }
                m_mutexProg.unlock();
            }
        }
    }
    DBG("worker thead exiting");
}