📄 scripting.cpp
字号:
/* * Roadnav * Scripting.cpp * * Copyright (c) 2004 - 2007 Richard L. Lynch <rllynch@users.sourceforge.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ ///////////////////////////////////////////////////////////////////////////////// \file////// Scripting class/////////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifdef HAVE_MATH_H#include <math.h>#endif#ifdef _MSC_VER#pragma warning(disable: 4786)#endif#include <wx/wx.h>#include <wx/tokenzr.h>#include <wx/wfstream.h>#include <wx/socket.h>#include <wx/sckstrm.h>#include "libroadnav/MapLookup.h"#include "libroadnav/MapSupport.h"#include "App.h"#include "Scripting.h"#ifdef USE_SCRIPTINGusing namespace std;//////////////////////////////////////////////////////////////////////////////////// \brief Remove and return the front of an STL list/////////////////////////////////////////////////////////////////////////////////wxString PopFrontAndReturn(list<wxString> & lList){ wxString strRtn; strRtn = lList.front(); lList.pop_front(); return strRtn;}//////////////////////////////////////////////////////////////////////////////////// \brief Returns the name of the file that should receive exported commands./////////////////////////////////////////////////////////////////////////////////wxString GetScriptExportFilename(){ wxString strRtn = g_pConfig->Read(wxT("ScriptingExportScriptFilename"), wxT("")); return strRtn;}//////////////////////////////////////////////////////////////////////////////////// \brief Returns if commands should be appended to the export file or if/// they should overwrite it. Always returns true right now./////////////////////////////////////////////////////////////////////////////////bool GetScriptAppendMode(){ return true;}//////////////////////////////////////////////////////////////////////////////////// \brief ScriptStream constructor - initialize all member variables/////////////////////////////////////////////////////////////////////////////////ScriptStream::ScriptStream(wxInputStream * pInputStream, wxOutputStream * pOutputStream, wxSocketBase * pSocket){ m_pInputStream = pInputStream; m_pOutputStream = pOutputStream; m_pSocket = pSocket; m_tLastRead = wxDateTime::Now();}//////////////////////////////////////////////////////////////////////////////////// \brief ScriptStream destructor - free all memory/////////////////////////////////////////////////////////////////////////////////ScriptStream::~ScriptStream(){ if (m_pInputStream) delete m_pInputStream; m_pInputStream = NULL; if (m_pOutputStream) delete m_pOutputStream; m_pOutputStream = NULL; if (m_pSocket) delete m_pSocket; m_pSocket = NULL;}//////////////////////////////////////////////////////////////////////////////////// \brief Scripting constructor - initialize all variables/////////////////////////////////////////////////////////////////////////////////Scripting::Scripting(wxWindow * pParent, MapControl * pctlMap){ m_pParent = pParent; m_pctlMap = pctlMap;}//////////////////////////////////////////////////////////////////////////////////// \brief Destructor - free all memory/////////////////////////////////////////////////////////////////////////////////Scripting::~Scripting(){ vector<ScriptStream *>::iterator i; // free scripts m_mtxScripts.Lock(); for (i = m_vScripts.begin(); i != m_vScripts.end(); i++) { delete (*i); } m_vScripts.clear(); m_mtxScripts.Unlock(); // free servers DeleteAllTCPServers();}//////////////////////////////////////////////////////////////////////////////////// \brief Internal function to add script to list/////////////////////////////////////////////////////////////////////////////////void Scripting::AddScript(wxInputStream * pInputStream, wxOutputStream * pOutputStream, wxSocketBase * pSocket){ m_mtxScripts.Lock(); m_vScripts.push_back(new ScriptStream(pInputStream, pOutputStream, pSocket)); m_mtxScripts.Unlock();}//////////////////////////////////////////////////////////////////////////////////// \brief Internal function to add server to list/////////////////////////////////////////////////////////////////////////////////void Scripting::AddServer(wxSocketServer * pServer){ m_mtxServers.Lock(); m_vServers.push_back(pServer); m_mtxServers.Unlock();}//////////////////////////////////////////////////////////////////////////////////// \brief Processes queued up events - best if run from the main thread/// of the application, in OnIdle or a timer./////////////////////////////////////////////////////////////////////////////////void Scripting::PumpScripts(){ vector<ScriptStream *>::iterator iScript; m_mtxScripts.Lock(); // iterate through scripts for (iScript = m_vScripts.begin(); iScript != m_vScripts.end(); iScript++) { bool bStreamOkay; // decide if this script is okay, or if it should be closed if ((*iScript)->m_pSocket) bStreamOkay = (*iScript)->m_pSocket->IsConnected(); else bStreamOkay = !(*iScript)->m_pInputStream->Eof(); if (bStreamOkay) { int iCRLFPos; int iPadding; if ((*iScript)->m_pSocket) { // CanRead() doesn't seem to work correctly on wxSocketInputStream :( int iCount = 1; // keep reading, until there is no more data while (iCount) { char szBuffer[1025]; // read, then NULL terminate (*iScript)->m_pSocket->Read(szBuffer, 1024); iCount = (*iScript)->m_pSocket->LastCount(); szBuffer[iCount] = 0; if (iCount) { // got something .. append it to input buffer and update last read timestamp (*iScript)->m_strInputBuffer += wxString(szBuffer, *wxConvCurrent); (*iScript)->m_tLastRead = wxDateTime::Now(); } else { // one minute of no activity? send a keepalive if (wxDateTime::Now() - (*iScript)->m_tLastRead > wxTimeSpan(0, 1, 0, 0)) { (*iScript)->m_pSocket->Write("KEEPALIVE\r\n", 11); (*iScript)->m_tLastRead = wxDateTime::Now(); } // make sure everything is okay, otherwise shut down connection if ((*iScript)->m_pSocket->LastError() != wxSOCKET_WOULDBLOCK && (*iScript)->m_pSocket->LastError() != wxSOCKET_NOERROR) bStreamOkay = false; } } // while (iCount) } else // we're not reading from a socket { // do a byte by byte read until there's no more data while ((*iScript)->m_pInputStream->CanRead()) (*iScript)->m_strInputBuffer += (*iScript)->m_pInputStream->GetC(); } iCRLFPos = 1; while (iCRLFPos >= 0) { // look for CR-LF iCRLFPos = (*iScript)->m_strInputBuffer.Find(wxT("\r\n")); iPadding = 2; // try just LF if CR-LF can't be found if (iCRLFPos < 0) { iCRLFPos = (*iScript)->m_strInputBuffer.Find(wxT('\n')); iPadding = 1; } // try just CR if (iCRLFPos < 0) { iCRLFPos = (*iScript)->m_strInputBuffer.Find(wxT('\r')); iPadding = 1; } // if EOL found if (iCRLFPos >= 0) { list<wxString> vRtn; // run command vRtn = ExecuteCommand((*iScript)->m_strInputBuffer.Left(iCRLFPos)); // if output stream available if ((*iScript)->m_pOutputStream) { wxString strOut; strOut = CompileCommand(vRtn); // then send it if non-empty if (strOut.Length()) { strOut += wxT("\r\n"); (*iScript)->m_pOutputStream->Write(strOut.mb_str(*wxConvCurrent), strOut.Length()); } } // remove processed command from buffer (*iScript)->m_strInputBuffer = (*iScript)->m_strInputBuffer.Mid(iCRLFPos + iPadding); } } } // something happened .. EOF or socket closed or something .. free up memory and remove from vector if (!bStreamOkay) { // EOF, free up memory delete (*iScript); // remove from vector m_vScripts.erase(iScript); // exit loop break; } } m_mtxScripts.Unlock();}//////////////////////////////////////////////////////////////////////////////////// \brief Accept connections on any servers running/////////////////////////////////////////////////////////////////////////////////void Scripting::PumpServers(){ vector<wxSocketServer *>::iterator i; m_mtxServers.Lock(); for (i = m_vServers.begin(); i != m_vServers.end(); i++) { wxSocketBase * pSock; pSock = (*i)->Accept(false); if (pSock) { // got a new incoming connection // we need the socket to be non-blocking pSock->SetFlags(wxSOCKET_NOWAIT); // make some input and output stream wrappers, then add it to the list AddScript(new wxSocketInputStream(*pSock), new wxSocketOutputStream(*pSock), pSock); } } m_mtxServers.Unlock();}//////////////////////////////////////////////////////////////////////////////////// \brief Pump everything/////////////////////////////////////////////////////////////////////////////////void Scripting::Pump(){ PumpScripts();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -