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 MainWindow::connectPixy(bool state) { if (state) // connect { try { if (m_pixyDFUConnected) // we're in programming mode { m_flash = new Flash(); if (m_argvFirmwareFile!="") program(m_argvFirmwareFile); else if (m_firmwareFile!="") { program(m_firmwareFile); m_firmwareFile = ""; } else { QString dir; QFileDialog fd(this); dir = m_settings->value("fw_dialog").toString(); fd.setWindowTitle("Select a Firmware File"); fd.setDirectory(QDir(dir)); fd.setNameFilter("Firmware (*.hex)"); if (fd.exec()) { QStringList slist = fd.selectedFiles(); if (slist.size()==1 && m_flash) { program(slist.at(0)); } } dir = fd.directory().absolutePath(); m_settings->setValue("fw_dialog", QVariant(dir)); } } else if (m_interpreter==NULL) { m_console->print("Pixy detected.\n"); clearActions(); m_interpreter = new Interpreter(m_console, m_video, &m_parameters, m_initScript); connect(m_interpreter, SIGNAL(runState(int)), this, SLOT(handleRunState(int))); connect(m_interpreter, SIGNAL(finished()), this, SLOT(interpreterFinished())); // thread will send finished event when it exits connect(m_interpreter, SIGNAL(connected(Device,bool)), this, SLOT(handleConnected(Device,bool))); connect(m_interpreter, SIGNAL(actionScriptlet(QString,QStringList)), this, SLOT(handleActionScriptlet(QString,QStringList))); connect(m_interpreter, SIGNAL(paramLoaded()), this, SLOT(handleLoadParams())); connect(m_interpreter, SIGNAL(version(ushort,ushort,ushort)), this, SLOT(handleVersion(ushort,ushort,ushort))); m_interpreter->start(); } m_pixyConnected = true; } catch (std::runtime_error &exception)
void Interpreter::handlePendingCommand() { QMutexLocker locker(&m_mutexQueue); if (m_commandQueue.empty()) return; const Command command = m_commandQueue.front(); m_commandQueue.pop_front(); locker.unlock(); switch (command.m_type) { case STOP: sendStop(); break; case RUN: sendRun(); break; case STOP_LOCAL: m_localProgramRunning = false; emit runState(false); break; case RUN_LOCAL: if (m_program.size()>0) { m_localProgramRunning = true; emit runState(true); emit enableConsole(false); m_pc = 0; } break; case LOAD_PARAMS: handleLoadParams(); break; case SAVE_PARAMS: handleSaveParams(command.m_arg0.toBool()); break; case UPDATE_PARAM: handleUpdateParam(); break; case CLOSE: emit runState(-1); 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"); }
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"); }