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");
}
Ejemplo n.º 2
0
void Interpreter::run()
{
    int res;
    QTime time;

    // init
    try
    {
        ChirpProc versionProc;
        uint16_t *version;
        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, &version, END_IN_ARGS);
        if (res<0)
            throw std::runtime_error("Can't get firmware version.");
        memcpy(m_version, version, 3*sizeof(uint16_t));
        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");

        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)
            throw std::runtime_error("Communication error with Pixy.");
    }
    catch (std::runtime_error &exception)
    {
        emit error(QString(exception.what()));
        return;
    }
    qDebug() << "*** init done";

    time.start();
    getRunning();

    handleLoadParams(); // load params upon initialization

    while(m_run)
    {
        if (!m_programming &&
                ((m_fastPoll && time.elapsed()>RUN_POLL_PERIOD_FAST) ||
                (!m_fastPoll && time.elapsed()>RUN_POLL_PERIOD_SLOW)))
        {
            getRunning();
            time.start();
        }
        else
        {
            m_chirp->service(false);
            msleep(1); // give config thread time to run
        }
        handlePendingCommand();
        if (!m_running)
        {
            if (m_localProgramRunning)
                execute();
            else
            {
                Sleeper::msleep(10);
                if (m_mutexProg.tryLock())
                {
                    if (m_argv.size())
                    {
                        if (m_externalCommand!="") // print command to make things explicit and all pretty
                            emit textOut(PROMPT " " + m_externalCommand);
                        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();
                        if (m_externalCommand=="")
                            prompt(); // print prompt only if we expect an actual human to be typing into the command window
                        else
                            m_externalCommand = "";
                        // 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();
                }
            }
        }
    }
    sendStop();
    msleep(200); // let things settle a bit
    qDebug("worker thead exiting");
}