From 532ccbd1f89f7151628ceeaf57a478c6c8d12333 Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Thu, 22 Jul 2010 14:15:02 +0200 Subject: [PATCH] Killed clientconsole, mwcompiler, mwinterpreter and command server --- CMakeLists.txt | 26 +-- apps/clientconsole/CMakeLists.txt | 4 - apps/clientconsole/client.cpp | 142 ---------------- apps/esmtool/esmtool.cpp | 2 +- apps/mwcompiler/CMakeLists.txt | 9 -- apps/mwcompiler/context.cpp | 21 --- apps/mwcompiler/context.hpp | 24 --- apps/mwcompiler/main.cpp | 78 --------- apps/mwinterpreter/CMakeLists.txt | 9 -- apps/mwinterpreter/context.cpp | 156 ------------------ apps/mwinterpreter/context.hpp | 76 --------- apps/mwinterpreter/main.cpp | 57 ------- apps/openmw/engine.cpp | 37 ----- apps/openmw/engine.hpp | 11 -- apps/openmw/main.cpp | 4 - components/commandserver/command.hpp | 21 --- components/commandserver/server.cpp | 232 --------------------------- components/commandserver/server.hpp | 64 -------- components/misc/tsdeque.hpp | 56 ------- 19 files changed, 3 insertions(+), 1026 deletions(-) delete mode 100644 apps/clientconsole/CMakeLists.txt delete mode 100755 apps/clientconsole/client.cpp delete mode 100644 apps/mwcompiler/CMakeLists.txt delete mode 100644 apps/mwcompiler/context.cpp delete mode 100644 apps/mwcompiler/context.hpp delete mode 100644 apps/mwcompiler/main.cpp delete mode 100644 apps/mwinterpreter/CMakeLists.txt delete mode 100644 apps/mwinterpreter/context.cpp delete mode 100644 apps/mwinterpreter/context.hpp delete mode 100644 apps/mwinterpreter/main.cpp delete mode 100755 components/commandserver/command.hpp delete mode 100755 components/commandserver/server.cpp delete mode 100755 components/commandserver/server.hpp delete mode 100755 components/misc/tsdeque.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4efe2ad5b6..2a61e61aa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,20 +50,13 @@ source_group(components\\esm_store FILES ${ESM_STORE} ${ESM_STORE_HEADER}) file(GLOB ESM_HEADER ${COMP_DIR}/esm/*.hpp) source_group(components\\esm FILES ${ESM_HEADER}) -set(COMMANDSERVER - ${COMP_DIR}/commandserver/command.hpp - ${COMP_DIR}/commandserver/server.hpp - ${COMP_DIR}/commandserver/server.cpp) -source_group(components\\commandserver FILES ${COMMANDSERVER}) - set(MISC ${COMP_DIR}/misc/stringops.cpp ${COMP_DIR}/misc/fileops.cpp) set(MISC_HEADER ${COMP_DIR}/misc/fileops.hpp ${COMP_DIR}/misc/slice_array.hpp - ${COMP_DIR}/misc/stringops.hpp - ${COMP_DIR}/misc/tsdeque.hpp) + ${COMP_DIR}/misc/stringops.hpp) source_group(components\\misc FILES ${MISC} ${MISC_HEADER}) file(GLOB COMPILER ${COMP_DIR}/compiler/*.cpp) @@ -75,7 +68,7 @@ file(GLOB INTERPRETER_HEADER ${COMP_DIR}/interpreter/*.hpp) source_group(components\\interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER}) set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${MISC} - ${COMMANDSERVER} ${COMPILER} ${INTERPRETER}) + ${COMPILER} ${INTERPRETER}) set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER} ${ESM_HEADER} ${MISC_HEADER} ${COMPILER_HEADER} ${INTERPRETER_HEADER}) @@ -195,18 +188,3 @@ option(BUILD_ESMTOOL "build ESM inspector" ON) if (BUILD_ESMTOOL) add_subdirectory( apps/esmtool ) endif() - -option(BUILD_CLIENTCONSOLE "build external console for script interpreter" ON) -if (BUILD_CLIENTCONSOLE) - add_subdirectory( apps/clientconsole ) -endif() - -option(BUILD_MWCOMPILER "build standalone Morrowind script compiler" ON) -if (BUILD_MWCOMPILER) - add_subdirectory( apps/mwcompiler ) -endif() - -option(BUILD_MWINTERPRETER "build standalone Morrowind script code interpreter" ON) -if (BUILD_MWINTERPRETER) - add_subdirectory( apps/mwinterpreter ) -endif() diff --git a/apps/clientconsole/CMakeLists.txt b/apps/clientconsole/CMakeLists.txt deleted file mode 100644 index c3bdfd4994..0000000000 --- a/apps/clientconsole/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - -find_package(Threads REQUIRED) -add_executable(clientconsole client.cpp) -target_link_libraries(clientconsole ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/apps/clientconsole/client.cpp b/apps/clientconsole/client.cpp deleted file mode 100755 index 6d3e0ccc47..0000000000 --- a/apps/clientconsole/client.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include - -#include - -using boost::asio::ip::tcp; - -#ifdef WIN32 -#pragma warning( disable : 4966 ) -#endif - -class Client -{ -protected: - struct Header - { - char magic[4]; - boost::uint32_t dataLength; - }; - - boost::asio::io_service mIOService; - tcp::socket* mpSocket; - -public: - - bool connect(const char* port) - { - tcp::resolver resolver(mIOService); - tcp::resolver::query query("localhost", port); - tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); - tcp::resolver::iterator end; - - mpSocket = new tcp::socket(mIOService); - boost::system::error_code error = boost::asio::error::host_not_found; - while (error && endpoint_iterator != end) - { - mpSocket->close(); - mpSocket->connect(*endpoint_iterator++, error); - } - - return (error) ? false : true; - } - void disconnect() - { - mpSocket->close(); - mIOService.stop(); - } - - bool send (const char* msg) - { - const size_t slen = strlen(msg); - const size_t plen = sizeof(Header) + slen + 1; - - std::vector packet(plen); - Header* pHeader = reinterpret_cast(&packet[0]); - strncpy(pHeader->magic, "OMW0", 4); - pHeader->dataLength = slen + 1; // Include the null terminator - strncpy(&packet[8], msg, pHeader->dataLength); - - boost::system::error_code ec; - boost::asio::write(*mpSocket, boost::asio::buffer(packet), - boost::asio::transfer_all(), ec); - if (ec) - std::cout << "Error: " << ec.message() << std::endl; - - return !ec; - } - - bool receive (std::string& reply) - { - Header header; - boost::system::error_code error; - mpSocket->read_some(boost::asio::buffer(&header, sizeof(Header)), error); - - if (error != boost::asio::error::eof) - { - if (strncmp(header.magic, "OMW0", 4) == 0) - { - std::vector msg; - msg.resize(header.dataLength); - - boost::system::error_code error; - mpSocket->read_some(boost::asio::buffer(&msg[0], header.dataLength), error); - if (!error) - { - reply = &msg[0]; - return true; - } - } - else - throw str_exception("Unexpected header!"); - } - return false; - } -}; - - -int main(int argc, char* argv[]) -{ - std::cout << "OpenMW client console" << std::endl; - std::cout << "=====================" << std::endl; - std::cout << "Type 'quit' to exit." << std::endl; - std::cout << "Connecting..."; - - Client client; - if (client.connect("27917")) - { - std::cout << "success." << std::endl; - - bool bDone = false; - do - { - std::cout << "Client> "; - std::string buffer; - std::getline(std::cin, buffer); - - if (buffer == "quit") - bDone = true; - else - { - if (client.send(buffer.c_str())) - { - std::string reply; - if (client.receive(reply)) - std::cout << "Server: " << reply << std::endl; - else - bDone = true; - } - else - bDone = true; - } - - } while (!bDone); - - client.disconnect(); - } - else - std::cout << "failed." << std::endl; - - return 0; -} diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 32d1f6b134..ff8e53824f 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -56,7 +56,7 @@ int main(int argc, char**argv) cout << "Special flag: " << esm.getSpecial() << endl; cout << "Masters:\n"; ESMReader::MasterList m = esm.getMasters(); - for(int i=0;i - -namespace SACompiler -{ - class Context : public Compiler::Context - { - public: - - virtual bool canDeclareLocals() const; - ///< Is the compiler allowed to declare local variables? - - virtual char getGlobalType (const std::string& name) const; - ///< 'l: long, 's': short, 'f': float, ' ': does not exist. - - virtual bool isId (const std::string& name) const; - ///< Does \a name match an ID, that can be referenced? - }; -} - -#endif - diff --git a/apps/mwcompiler/main.cpp b/apps/mwcompiler/main.cpp deleted file mode 100644 index a19a50ab39..0000000000 --- a/apps/mwcompiler/main.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Stand-alone MW-script compiler - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "context.hpp" - -int main (int argc, char **argv) -{ - try - { - SACompiler::Context context; - Compiler::StreamErrorHandler errorHandler (std::cout); - Compiler::FileParser parser (errorHandler, context); - - std::string filename = argc>1 ? argv[1] : "test.mwscript"; - - try - { - std::ifstream file (filename.c_str()); - - if (!file.is_open()) - { - std::cout << "can't open script file: " << filename << std::endl; - return 1; - } - - Compiler::Scanner scanner (errorHandler, file); - - scanner.scan (parser); - } - catch (const Compiler::SourceException&) - { - // ignore exception (problem has already been reported to the user) - } - - if (errorHandler.countErrors() || errorHandler.countWarnings()) - { - std::cout - << errorHandler.countErrors() << " error(s), " - << errorHandler.countWarnings() << " warning(s)" << std::endl - << std::endl; - } - - if (errorHandler.isGood()) - { - std::vector code; - parser.getCode (code); - - std::ofstream codeFile ((filename + ".code").c_str()); - - codeFile.write (reinterpret_cast (&code[0]), - code.size()*sizeof (Interpreter::Type_Code)); - - std::ofstream localFile ((filename + ".locals").c_str()); - - parser.getLocals().write (localFile); - - return 0; - } - - return 1; - } - catch (const std::exception &e) - { - std::cout << "\nERROR: " << e.what() << std::endl; - return 1; - } -} - diff --git a/apps/mwinterpreter/CMakeLists.txt b/apps/mwinterpreter/CMakeLists.txt deleted file mode 100644 index 0789256577..0000000000 --- a/apps/mwinterpreter/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -project(MWInterpreter) - -set(TOOLS_MWINTERPRETER - ${INTERPRETER} - main.cpp - context.cpp - context.hpp) - -add_executable(mwinterpreter ${TOOLS_MWINTERPRETER}) diff --git a/apps/mwinterpreter/context.cpp b/apps/mwinterpreter/context.cpp deleted file mode 100644 index 7924f1dc73..0000000000 --- a/apps/mwinterpreter/context.cpp +++ /dev/null @@ -1,156 +0,0 @@ - -#include "context.hpp" - -#include -#include -#include -#include - -namespace SAInterpreter -{ - Context::Context (const std::string& filename) - { - std::ifstream file (filename.c_str()); - - if (!file.is_open()) - throw std::runtime_error ("can't open locals file: " + filename); - - std::size_t shortSize, longSize, floatSize; - - file >> shortSize >> longSize >> floatSize; - - mShorts.resize (shortSize, 0); - mLongs.resize (longSize, 0); - mFloats.resize (floatSize, 0.0); - - std::size_t size = shortSize + longSize + floatSize; - - mNames.resize (size); - - for (std::size_t i=0; i> mNames[i]; - } - - int Context::getLocalShort (int index) const - { - assert (index>=0); - return mShorts.at (index); - } - - int Context::getLocalLong (int index) const - { - assert (index>=0); - return mLongs.at (index); - } - - float Context::getLocalFloat (int index) const - { - assert (index>=0); - return mFloats.at (index); - } - - void Context::setLocalShort (int index, int value) - { - assert (index>=0); - mShorts.at (index) = value; - } - - void Context::setLocalLong (int index, int value) - { - assert (index>=0); - mLongs.at (index) = value; - } - - void Context::setLocalFloat (int index, float value) - { - assert (index>=0); - mFloats.at (index) = value; - } - - void Context::messageBox (const std::string& message, - const std::vector& buttons) - { - std::cout << "message box: " << message << std::endl; - for (std::size_t i=0; i::const_iterator iter (mShorts.begin()); - iter!=mShorts.end(); ++iter) - std::cout << mNames[i++] << ": " << *iter << std::endl; - - std::cout << "local longs:" << std::endl; - - for (std::vector::const_iterator iter (mLongs.begin()); - iter!=mLongs.end(); ++iter) - std::cout << mNames[i++] << ": " << *iter << std::endl; - - std::cout << "local floats:" << std::endl; - - for (std::vector::const_iterator iter (mFloats.begin()); - iter!=mFloats.end(); ++iter) - std::cout << mNames[i++] << ": " << *iter << std::endl; - - } -} - diff --git a/apps/mwinterpreter/context.hpp b/apps/mwinterpreter/context.hpp deleted file mode 100644 index 6cf4f8cd7b..0000000000 --- a/apps/mwinterpreter/context.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef SAINTERPRETER_CONTEXT_H_INCLUDED -#define SAINTERPRETER_CONTEXT_H_INCLUDED - -#include -#include - -#include -#include - -namespace SAInterpreter -{ - class Context : public Interpreter::Context - { - std::vector mShorts; - std::vector mLongs; - std::vector mFloats; - std::vector mNames; - - public: - - Context (const std::string& filename); - ///< Create context from file - /// \note A context for an integreted interpreter will typically not - /// configure at construction, but will offer a separate function. - - virtual int getLocalShort (int index) const; - - virtual int getLocalLong (int index) const; - - virtual float getLocalFloat (int index) const; - - virtual void setLocalShort (int index, int value); - - virtual void setLocalLong (int index, int value); - - virtual void setLocalFloat (int index, float value); - - virtual void messageBox (const std::string& message, - const std::vector& buttons); - - virtual bool menuMode(); - - virtual int getGlobalShort (const std::string& name) const; - - virtual int getGlobalLong (const std::string& name) const; - - virtual float getGlobalFloat (const std::string& name) const; - - virtual void setGlobalShort (const std::string& name, int value); - - virtual void setGlobalLong (const std::string& name, int value); - - virtual void setGlobalFloat (const std::string& name, float value); - - virtual bool isScriptRunning (const std::string& name) const; - - virtual void startScript (const std::string& name); - - virtual void stopScript (const std::string& name); - - virtual float getDistance (const std::string& name, const std::string& id = "") const; - - virtual float getSecondsPassed() const; - - virtual bool isDisabled (const std::string& id = "") const; - - virtual void enable (const std::string& id = ""); - - virtual void disable (const std::string& id = ""); - - void report(); - ///< Write state to std::cout - }; -} - -#endif diff --git a/apps/mwinterpreter/main.cpp b/apps/mwinterpreter/main.cpp deleted file mode 100644 index e8f0c8783b..0000000000 --- a/apps/mwinterpreter/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Stand-alone MW-script code interpreter - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "context.hpp" - -int main (int argc, char **argv) -{ - try - { - std::string filename = argc>1 ? argv[1] : "test.mwscript"; - - std::string localfilename = filename + ".locals"; - - SAInterpreter::Context context (localfilename); - Interpreter::Interpreter interpreter (context); - Interpreter::installOpcodes (interpreter); - - std::string codefilename = filename + ".code"; - - std::ifstream codefile (codefilename.c_str()); - - if (!codefile.is_open()) - { - std::cout << "can't open code file: " << codefilename << std::endl; - return 1; - } - - std::vector code (4); - - codefile.read (reinterpret_cast (&code[0]), 4 * sizeof (Interpreter::Type_Code)); - - unsigned int size = code[0] + code[1] + code[2] + code[3]; - - code.resize (4+size); - - codefile.read (reinterpret_cast (&code[4]), size * sizeof (Interpreter::Type_Code)); - - interpreter.run (&code[0], size+4); - - context.report(); - } - catch (const std::exception &e) - { - std::cout << "\nERROR: " << e.what() << std::endl; - return 1; - } -} - diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 0234b727f0..39cfd7e2b1 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -45,9 +45,6 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) { mEnvironment.mFrameDuration = evt.timeSinceLastFrame; - // console - processCommands(); - // global scripts mEnvironment.mGlobalScripts->run (mEnvironment); @@ -68,27 +65,11 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) return true; } - -void OMW::Engine::processCommands() -{ - Command cmd; - while (mCommandQueue.try_pop_front(cmd)) - { - ///\todo Add actual processing of the received command strings - std::cout << "Command: '" << cmd.mCommand << "'" << std::endl; - - ///\todo Replace with real output. For now, echo back the string in uppercase - std::string reply(cmd.mCommand); - std::transform(reply.begin(), reply.end(), reply.begin(), toupper); - cmd.mReplyFunction(reply); - } -} OMW::Engine::Engine() : mDebug (false) , mVerboseScripts (false) , mNewGame (false) - , mEnableCommandServer (false) , mScriptManager (0) , mScriptContext (0) { @@ -96,9 +77,6 @@ OMW::Engine::Engine() OMW::Engine::~Engine() { - if (mspCommandServer.get()) - mspCommandServer->stop(); - delete mGuiManager; delete mEnvironment.mWorld; delete mEnvironment.mSoundManager; @@ -167,11 +145,6 @@ void OMW::Engine::enableDebugMode() { mDebug = true; } - -void OMW::Engine::enableCommandServer() -{ - mEnableCommandServer = true; -} void OMW::Engine::enableVerboseScripts() { @@ -239,16 +212,6 @@ void OMW::Engine::go() MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), *mEnvironment.mWindowManager, mDebug); - // Launch the console server - if (mEnableCommandServer) - { - std::cout << "Starting command server on port " << kCommandServerPort << std::endl; - mspCommandServer.reset(new OMW::CommandServer::Server(&mCommandQueue, kCommandServerPort)); - mspCommandServer->start(); - } - else - std::cout << "Command server disabled" << std::endl; - std::cout << "\nPress Q/ESC or close window to exit.\n"; mOgre.getRoot()->addFrameListener (this); diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index a0d6a16e3d..9923f49906 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -8,9 +8,6 @@ #include #include -#include -#include -#include #include #include "mwworld/environment.hpp" @@ -54,8 +51,6 @@ namespace OMW class Engine : private Ogre::FrameListener { - enum { kCommandServerPort = 27917 }; - boost::filesystem::path mDataDir; OEngine::Render::OgreRenderer mOgre; std::string mCellName; @@ -64,10 +59,6 @@ namespace OMW bool mVerboseScripts; bool mNewGame; - TsDeque mCommandQueue; - bool mEnableCommandServer; - std::auto_ptr mspCommandServer; - MWWorld::Environment mEnvironment; MWScript::ScriptManager *mScriptManager; Compiler::Extensions mExtensions; @@ -90,7 +81,6 @@ namespace OMW virtual bool frameStarted(const Ogre::FrameEvent& evt); /// Process pending commands - void processCommands(); public: @@ -115,7 +105,6 @@ namespace OMW /// Enable the command server so external apps can send commands to the console. /// Must be set before go(). - void enableCommandServer(); /// Enable verbose script output void enableVerboseScripts(); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index c3bbe33c13..ff3f32e3df 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -33,7 +33,6 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) ( "debug", "debug mode" ) ( "script-verbose", "verbose script output" ) ( "new-game", "activate char gen/new game mechanics" ) - ( "disable-command-server", "turn off the command server" ) ; bpo::variables_map variables; @@ -72,9 +71,6 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) if (variables.count ("new-game")) engine.setNewGame(); - if (variables.count("disable-command-server") == 0) - engine.enableCommandServer(); - return true; } diff --git a/components/commandserver/command.hpp b/components/commandserver/command.hpp deleted file mode 100755 index f58177f6ea..0000000000 --- a/components/commandserver/command.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef COMMANDSERVER_COMMAND_HPP -#define COMMANDSERVER_COMMAND_HPP - -#include - -namespace OMW -{ - /// - /// A Command is currently defined as a string input that, when processed, - /// will generate a string output. The string output is passed to the - /// mReplyFunction as soon as the command has been processed. - /// - class Command - { - public: - std::string mCommand; - boost::function1 mReplyFunction; - }; -} - -#endif //COMMANDSERVER_COMMAND_HPP diff --git a/components/commandserver/server.cpp b/components/commandserver/server.cpp deleted file mode 100755 index 53d7b2bf24..0000000000 --- a/components/commandserver/server.cpp +++ /dev/null @@ -1,232 +0,0 @@ -#include "server.hpp" -#include "libs/platform/strings.h" - -using boost::asio::ip::tcp; - -// -// Namespace for containing implementation details that the -// rest of OpenMW doesn't need to worry about -// -namespace OMW { namespace CommandServer { namespace Detail { - - struct Header - { - char magic[4]; - size_t dataLength; - } header; - - /// - /// Tracks an active connection to the CommandServer - /// - class Connection - { - public: - Connection (boost::asio::io_service& io_service, Server* pServer); - - void start(); - void stop(); - - tcp::socket& socket(); - void reply (std::string s); - - protected: - void handle (); - - tcp::socket mSocket; - Server* mpServer; - boost::thread* mpThread; - }; - - Connection::Connection (boost::asio::io_service& io_service, Server* pServer) - : mSocket (io_service) - , mpServer (pServer) - { - } - - void Connection::start() - { - mpThread = new boost::thread(boost::bind(&Connection::handle, this)); - } - - /// - /// Stops and disconnects the connection - /// - void Connection::stop() - { - mSocket.shutdown(boost::asio::socket_base::shutdown_both); - mSocket.close(); - mpThread->join(); - } - - tcp::socket& Connection::socket() - { - return mSocket; - } - - void Connection::reply (std::string reply) - { - const size_t plen = sizeof(Header) + reply.length() + 1; - - std::vector packet(plen); - Header* pHeader = reinterpret_cast(&packet[0]); - strncpy(pHeader->magic, "OMW0", 4); - pHeader->dataLength = reply.length() + 1; // Include the null terminator - strncpy(&packet[8], reply.c_str(), pHeader->dataLength); - - boost::system::error_code ec; - boost::asio::write(mSocket, boost::asio::buffer(packet), - boost::asio::transfer_all(), ec); - if (ec) - std::cout << "Error: " << ec.message() << std::endl; - } - - void Connection::handle () - { - bool bDone = false; - while (!bDone) - { - // Read the header - boost::system::error_code error; - mSocket.read_some(boost::asio::buffer(&header, sizeof(Header)), error); - - if (error != boost::asio::error::eof) - { - if (strncmp(header.magic, "OMW0", 4) == 0) - { - std::vector msg; - msg.resize(header.dataLength); - - boost::system::error_code error; - mSocket.read_some(boost::asio::buffer(&msg[0], header.dataLength), error); - if (!error) - mpServer->postCommand(this, &msg[0]); - else - bDone = true; - } - else - throw std::runtime_error("Unexpected header!"); - } - else - bDone = true; - } - mpServer->removeConnection(this); - } - -}}} - -namespace OMW { namespace CommandServer { - - using namespace Detail; - - Server::Server (Deque* pCommandQueue, const int port) - : mPort (port) - , mAcceptor (mIOService, tcp::endpoint(tcp::v4(), mPort)) - , mbStopping (false) - , mpCommandQueue (pCommandQueue) - { - } - - void Server::start() - { - mIOService.run(); - mpThread = new boost::thread(boost::bind(&Server::threadMain, this)); - } - - // - // Helper function - see Server::stop() - // - static void connectAndDisconnect (int port) - { - char portString[64]; - snprintf(portString, 64, "%d", port); - - boost::asio::io_service ioService; - tcp::resolver resolver(ioService); - tcp::resolver::query query("localhost", portString); - tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); - tcp::resolver::iterator end; - - tcp::socket socket(ioService); - boost::system::error_code error = boost::asio::error::host_not_found; - while (error && endpoint_iterator != end) - { - socket.close(); - socket.connect(*endpoint_iterator++, error); - } - - socket.close(); - ioService.stop(); - } - - void Server::stop() - { - // Boost.Asio doesn't have a way to cancel the blocking accept() call - // in the listening thread. Therefore, set an internal flag to let - // the server know it's stopping and then unblock it via a do-nothing - // connect/disconnect. - mbStopping = true; - connectAndDisconnect(mPort); - - // (1) Stop accepting new connections - // (2) Wait for the listener thread to finish - mAcceptor.close(); - mpThread->join(); - - // Now that no new connections are possible, close any existing - // open connections - { - boost::mutex::scoped_lock lock(mConnectionsMutex); - for (ConnectionSet::iterator it = mConnections.begin(); - it != mConnections.end(); - ++it) - { - (*it)->stop(); - } - } - } - - void Server::removeConnection (Connection* ptr) - { - // If the server is shutting down (rather the client closing the - // connection), don't remove the connection from the list: that - // would corrupt the iterator the server is using to shutdown all - // clients. - if (!mbStopping) - { - boost::mutex::scoped_lock lock(mConnectionsMutex); - std::set::iterator it = mConnections.find(ptr); - if (it != mConnections.end()) - mConnections.erase(it); - } - delete ptr; - } - - void Server::postCommand (Connection* pConnection, const char* s) - { - Command cmd; - cmd.mCommand = s; - cmd.mReplyFunction = std::bind1st(std::mem_fun(&Connection::reply), pConnection); - mpCommandQueue->push_back(cmd); - } - - void Server::threadMain() - { - // Loop until accept() fails, which will cause the break statement to be hit - while (true) - { - std::auto_ptr spConnection(new Connection(mAcceptor.io_service(), this)); - boost::system::error_code ec; - mAcceptor.accept(spConnection->socket(), ec); - if (!ec && !mbStopping) - { - boost::mutex::scoped_lock lock(mConnectionsMutex); - mConnections.insert(spConnection.get()); - spConnection->start(); - spConnection.release(); - } - else - break; - } - } - -}} diff --git a/components/commandserver/server.hpp b/components/commandserver/server.hpp deleted file mode 100755 index 3d7665a147..0000000000 --- a/components/commandserver/server.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef CONSOLESERVER_H -#define CONSOLESERVER_H - -#include -#include -#include -#include -#include -#include - -#include "components/misc/tsdeque.hpp" -#include "components/commandserver/command.hpp" - -namespace OMW { namespace CommandServer -{ - // - // Forward Declarations - // - namespace Detail - { - class Connection; - } - - // - // Server that opens a port to listen for string commands which will be - // put into the deque provided in the Server constructor. - // - class Server - { - public: - typedef TsDeque Deque; - - Server (Deque* pCommandQueue, const int port); - - void start(); - void stop(); - - protected: - friend class Detail::Connection; - typedef std::set ConnectionSet; - - void removeConnection (Detail::Connection* ptr); - void postCommand (Detail::Connection*, const char* s); - - void threadMain(); - - // Objects used to set up the listening server - int mPort; - boost::asio::io_service mIOService; - boost::asio::ip::tcp::acceptor mAcceptor; - boost::thread* mpThread; - bool mbStopping; - - // Track active connections - ConnectionSet mConnections; - mutable boost::mutex mConnectionsMutex; - - // Pointer to command queue - Deque* mpCommandQueue; - }; - -}} - -#endif // CONSOLESERVER_H diff --git a/components/misc/tsdeque.hpp b/components/misc/tsdeque.hpp deleted file mode 100755 index 88b2ce001c..0000000000 --- a/components/misc/tsdeque.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef TSDEQUE_H -#define TSDEQUE_H - -#include - -// -// Adapted from http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html -// -template -class TsDeque -{ -private: - std::deque the_queue; - mutable boost::mutex the_mutex; - boost::condition_variable the_condition_variable; - -public: - void push_back(Data const& data) - { - boost::mutex::scoped_lock lock(the_mutex); - the_queue.push_back(data); - lock.unlock(); - the_condition_variable.notify_one(); - } - - bool empty() const - { - boost::mutex::scoped_lock lock(the_mutex); - return the_queue.empty(); - } - - bool try_pop_front(Data& popped_value) - { - boost::mutex::scoped_lock lock(the_mutex); - if(the_queue.empty()) - return false; - - popped_value=the_queue.front(); - the_queue.pop_front(); - return true; - } - - void wait_and_pop_front(Data& popped_value) - { - boost::mutex::scoped_lock lock(the_mutex); - while(the_queue.empty()) - { - the_condition_variable.wait(lock); - } - - popped_value=the_queue.front(); - the_queue.pop_front(); - } -}; - -#endif // TSDEQUE_H