int Interpreter::execute() { int res; emit runState(true); emit enableConsole(false); QMutexLocker locker(&m_mutexProg); while(1) { for (; m_pc<m_program.size(); m_pc++) { if (!m_localProgramRunning) { prompt(); res = 0; goto end; } res = m_chirp->execute(m_program[m_pc]); if (res<0) goto end; } m_pc = 0; } end: m_localProgramRunning = false; emit runState(false); emit enableConsole(true); return res; }
void Interpreter::getRunning() { int res, running; res = m_chirp->callSync(m_exec_running, END_OUT_ARGS, &running, END_IN_ARGS); qDebug("running %d %d", res, running); if (res<0 && !m_notified) { running = false; m_notified = true; emit connected(PIXY, false); } // emit state if we've changed if (m_running!=running) { if (running==2) m_fastPoll = true; else m_fastPoll = false; m_running = running; emit runState(running); emit enableConsole(!running); if (!running && m_externalCommand=="") prompt(); // print prompt only if we expect an actual human to be typing into the command window, and we've stopped } }
//-------------------------------------------------------------------------------// LogMgr::LogMgr(const String& logFile /* = "Log.ini" */, bool enableCon /* = true */, bool enableVS /* = true */) :mLogName(logFile), mConsoleEnable(enableCon), mVSOutput(enableVS), mEnableFileLog(true) { if(mConsoleEnable) enableConsole(); if(logFile == "") mEnableFileLog = false; if(mEnableFileLog) { fopen_s(&mpFile, mLogName.c_str(), "w"); } }
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::getRunning() { int res, running; res = m_chirp->callSync(m_exec_running, END_OUT_ARGS, &running, END_IN_ARGS); DBG("running %d %d", res, running); if (res<0 && !m_notified) { running = false; m_notified = true; emit connected(PIXY, false); } // emit state if we've changed if (m_running!=running) { if (running==2) m_fastPoll = true; else m_fastPoll = false; m_running = running; emit runState(running); emit enableConsole(!running); } }
int Interpreter::call(const QStringList &argv, bool interactive) { ChirpProc proc; ProcInfo info; int args[20]; int i, j, k, n, base, res; bool ok; uint type; ArgList list; // not allowed if (argv.size()<1) return -1; // check modules to see if they handle this command, if so, skip to end emit enableConsole(false); for (i=0; i<m_modules.size(); i++) { if (m_modules[i]->command(argv)) return 0; } // a procedure needs extension info (arg info, etc) in order for us to call... if ((proc=m_chirp->getProc(argv[0].toLocal8Bit()))>=0 && m_chirp->getProcInfo(proc, &info)>=0) { memset(args, 0, sizeof(args)); // zero args getArgs(&info, &list); n = strlen((char *)info.argTypes); // if we have fewer args than required... if ((int)list.size()>argv.size()-1) { // if we're interactive, ask for values if (interactive && argv.size()>0) { QStringList cargv = argv; QString pstring, pstring2; for (i=cargv.size()-1; i<(int)list.size(); i++) { if (info.argTypes[i]==CRP_TYPE_HINT) { if (n>i+4) { type = *(uint *)&info.argTypes[i+1]; if (type==FOURCC('R','E','G','1')) { emit videoInput(VideoWidget::REGION); pstring2 = "(select region with mouse)"; } if (type==FOURCC('P','N','T','1')) { emit videoInput(VideoWidget::POINT); pstring2 = "(select point with mouse)"; } } } k = i; pstring = printArgType(&info.argTypes[i], i) + " " + list[k].first + (list[k].second=="" ? "?" : " (" + list[k].second + ")?") + " " + pstring2; emit enableConsole(true); emit prompt(pstring); m_mutexInput.lock(); m_waiting = true; m_waitInput.wait(&m_mutexInput); m_waiting = false; m_mutexInput.unlock(); emit prompt(PROMPT); emit enableConsole(false); if (m_key==Qt::Key_Escape) return -1; cargv << m_command.split(QRegExp("\\s+")); } // call ourselves again, now that we have all the args return call(cargv, true); } else { emit error("too few arguments.\n"); return -1; } } augmentProcInfo(&info); // if we have all the args we need, parse, put in args array for (i=0, j=0; m_argTypes[i]; i++) { if (argv.size()>i+1) { if (m_argTypes[i]==CRP_INT8 || m_argTypes[i]==CRP_INT16 || m_argTypes[i]==CRP_INT32) { args[j++] = m_argTypes[i]; if (argv[i+1].left(2)=="0x") base = 16; else base = 10; args[j++] = argv[i+1].toInt(&ok, base); if (!ok) { emit error("argument didn't parse.\n"); return -1; } } #if 0 else if (m_argTypes[i]==CRP_STRING) { args[j++] = m_argTypes[i]; // string goes where? can't cast pointer to int... } #endif else { // deal with non-integer types return -1; } } } #if 0 // print helpful chirp argument string if (interactive && argv.size()>1) { QString callString = "Chirp arguments for " + argv[0] + " (ChirpProc=" + QString::number(proc) + "): "; for (i=1; i<argv.size(); i++) { if (i>1) callString += ", "; j = i; callString += printArgType(&m_argTypes[i-1], i) + "(" + argv[j] + ")"; } emit textOut(callString + "\n"); } #endif // make chirp call res = m_chirp->callAsync(proc, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13], args[14], args[15], args[16], args[17], args[18], args[19], END_OUT_ARGS); // check for cable disconnect if (res<0 && !m_notified) //res==LIBUSB_ERROR_PIPE) { m_notified = true; emit connected(PIXY, false); return res; } // get response if we're not programming, save text if we are if (m_programming) addProgram(argv); else m_chirp->serviceChirp(); } else { emit error("procedure unsupported.\n"); return -1; } return 0; }
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"); }
CommandAndArguments Console::getNextCommand() { out_ << endl << ps1_; out_.flush(); char c = '\0'; QString string; bool endOfLine = false; enableConsole(false); int currentHistoryIndex = history_.size(); int cursorPos = string.size(); do { c = getchar(); const int origStringLen = string.size(); const int oldCursorPos = cursorPos; if (c == '\n' || c == '\r') { endOfLine = true; } else if (c == 0x1b) { // escape char char escape1 = getchar(); char escape2 = getchar(); if (escape1 == '[') { if (escape2 == 'A') { // up if (!history_.isEmpty()) { currentHistoryIndex = qMax(currentHistoryIndex - 1, 0); string = history_.at(currentHistoryIndex).toString(); } cursorPos = string.size(); } else if (escape2 == 'B') { // down currentHistoryIndex = qMin(currentHistoryIndex + 1, history_.size()); if (currentHistoryIndex >= history_.size()) { string = ""; } else { string = history_.at(currentHistoryIndex).toString(); } cursorPos = string.size(); } else if (escape2 == 'D') { // left cursorPos = qMax(cursorPos - 1, 0); } else if (escape2 == 'C') { // right cursorPos = qMin(cursorPos + 1, string.size()); } else if (escape2 == '3') { char escape3 = getchar(); if (escape3 == '~') { // delete key if (cursorPos < string.size()) { string.remove(cursorPos, 1); } } else { qCWarning(CONSOLE_CLIENT) << "Unhandled escape3:" << escape3; } } else { qCWarning(CONSOLE_CLIENT) << "Unhandled escape2:" << escape2; } } else { qCWarning(CONSOLE_CLIENT) << "Unhandled escape1:" << escape1; } c ='\0'; } else if (c == 0x7f) { // backspace if (string.size() > 0) { c = '\b'; string.chop(1); --cursorPos; } } else { string.insert(cursorPos, c); ++cursorPos; } // move cursor behind word for (int i = 0; i < origStringLen - oldCursorPos; ++i) printf(" "); // write new string for(int i = 0; i < origStringLen; ++i) printf("\b \b"); printf("%s", qPrintable(string)); // move cursor into position for (int i = 0; i < string.size() - cursorPos; ++i) printf("\b"); } while (!endOfLine); printf("\n"); enableConsole(true); QStringList enteredValues = string.split(" "); const QString command = enteredValues.takeFirst(); const CommandAndArguments commandAndArguments(command, enteredValues); history_ << commandAndArguments; return commandAndArguments; }