From 5fe4313b95eba6bf37b462a64ffc594b53060b6a Mon Sep 17 00:00:00 2001 From: athile Date: Sun, 4 Jul 2010 20:17:10 -0700 Subject: [PATCH 1/4] Various Windows fixes to CMake, compile errors, and a few warnings. Also made the command server optional and disabled by default since it is not currently working correctly on Linux. --- CMakeLists.txt | 8 ++++--- apps/clientconsole/CMakeLists.txt | 4 +--- apps/openmw/engine.cpp | 25 +++++++++++++++------ apps/openmw/engine.hpp | 5 +++++ apps/openmw/main.cpp | 4 ++++ apps/openmw/mwscript/interpretercontext.cpp | 2 +- apps/openmw/mwworld/environment.hpp | 3 ++- apps/openmw/mwworld/world.cpp | 5 +++-- components/esm/loadscpt.hpp | 3 ++- components/esm_store/cell_store.hpp | 2 +- extern/caelum/CMakeLists.txt | 9 +++++++- 11 files changed, 50 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb4958df3..d58befce8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,7 +178,8 @@ set(OPENMW_LIBS_HEADER) # Platform specific if (WIN32) -set(PLATFORM_INCLUDE_DIR "platform") + set(PLATFORM_INCLUDE_DIR "platform") + add_definitions(-DBOOST_ALL_NO_LIB) else (WIN32) set(PLATFORM_INCLUDE_DIR "") endif (WIN32) @@ -186,10 +187,11 @@ endif (WIN32) # Dependencies find_package(OGRE REQUIRED) -find_package(Boost REQUIRED COMPONENTS system filesystem program_options) +find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread) find_package(OIS REQUIRED) include_directories("." - ${OGRE_INCLUDE_DIR} ${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} + ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre + ${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} ${CMAKE_HOME_DIRECTORY}/extern/caelum/include) link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR}) diff --git a/apps/clientconsole/CMakeLists.txt b/apps/clientconsole/CMakeLists.txt index f73610863..f030d9024 100644 --- a/apps/clientconsole/CMakeLists.txt +++ b/apps/clientconsole/CMakeLists.txt @@ -1,5 +1,3 @@ -project(clientconsole) -find_package(Boost REQUIRED COMPONENTS system) -link_directories(${Boost_LIBRARY_DIRS}) + add_executable(clientconsole client.cpp) target_link_libraries(clientconsole ${Boost_LIBRARIES}) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 30cae5897..5859d9c0e 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -64,15 +64,15 @@ void OMW::Engine::processCommands() OMW::Engine::Engine() : mDebug (false), mVerboseScripts (false), mNewGame (false), mScriptManager (0), - mScriptContext (0) -{ - mspCommandServer.reset( - new OMW::CommandServer::Server(&mCommandQueue, kCommandServerPort)); + mScriptContext (0), mEnableCommandServer (false) +{ } OMW::Engine::~Engine() { -// mspCommandServer->stop(); + if (mspCommandServer.get()) + mspCommandServer->stop(); + delete mEnvironment.mWorld; delete mEnvironment.mSoundManager; delete mEnvironment.mGlobalScripts; @@ -140,6 +140,11 @@ void OMW::Engine::enableDebugMode() { mDebug = true; } + +void OMW::Engine::enableCommandServer() +{ + mEnableCommandServer = true; +} void OMW::Engine::enableVerboseScripts() { @@ -201,8 +206,14 @@ void OMW::Engine::go() MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), mDebug); // Launch the console server - std::cout << "Starting command server on port " << kCommandServerPort << std::endl; - mspCommandServer->start(); + 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 << "\nStart! Press Q/ESC or close window to exit.\n"; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index f0b46c6ab..cf982ad0e 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -52,6 +52,7 @@ namespace OMW bool mNewGame; TsDeque mCommandQueue; + bool mEnableCommandServer; std::auto_ptr mspCommandServer; MWWorld::Environment mEnvironment; @@ -98,6 +99,10 @@ namespace OMW /// - non-exclusive input void enableDebugMode(); + /// 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 70530c2ef..82d69fcd8 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -32,6 +32,7 @@ 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" ) + ( "enable-command-server", "turn on the command server" ) ; bpo::variables_map variables; @@ -62,6 +63,9 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) if (variables.count ("new-game")) engine.setNewGame(); + + if (variables.count("enable-command-server")) + engine.enableCommandServer(); return true; } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 525aef183..5a8294ec9 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -110,7 +110,7 @@ namespace MWScript void InterpreterContext::setGlobalLong (const std::string& name, int value) { // a global long is internally a float. - float value2 = value; + float value2 = float(value); mEnvironment.mWorld->getGlobalVariable (name) = *reinterpret_cast (&value2); diff --git a/apps/openmw/mwworld/environment.hpp b/apps/openmw/mwworld/environment.hpp index b208d95a2..d1771d4ee 100644 --- a/apps/openmw/mwworld/environment.hpp +++ b/apps/openmw/mwworld/environment.hpp @@ -16,8 +16,9 @@ namespace MWWorld class World; ///< Collection of script-accessable sub-systems - struct Environment + class Environment { + public: Environment() : mWorld (0), mSoundManager (0), mGlobalScripts (0) {} World *mWorld; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 217bff7da..32fd3008f 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -99,8 +99,9 @@ namespace MWWorld iter->second->show(); // Optionally enable the sky -// if (mEnableSky) -// mpSkyManager = MWRender::SkyManager::create(renderer.getWindow(), mScene.getCamera()); + ///\todo FIXME + if (false) + mSkyManager = MWRender::SkyManager::create(renderer.getWindow(), mScene.getCamera()); } diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index 6025e528c..aa189c888 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -9,8 +9,9 @@ namespace ESM { * Script definitions */ -struct Script +class Script { +public: struct SCHDstruct { /* Script name. diff --git a/components/esm_store/cell_store.hpp b/components/esm_store/cell_store.hpp index 90cd5d1a6..29ab42fd1 100644 --- a/components/esm_store/cell_store.hpp +++ b/components/esm_store/cell_store.hpp @@ -87,7 +87,7 @@ namespace ESMS CellRefList ingreds; CellRefList creatureLists; CellRefList itemLists; - CellRefList lights; + CellRefList lights; CellRefList lockpicks; CellRefList miscItems; CellRefList npcs; diff --git a/extern/caelum/CMakeLists.txt b/extern/caelum/CMakeLists.txt index 4226d8d4a..b95b3fd8c 100755 --- a/extern/caelum/CMakeLists.txt +++ b/extern/caelum/CMakeLists.txt @@ -1,7 +1,14 @@ project(Caelum) +IF(MSVC) + add_definitions("-D_SCL_SECURE_NO_WARNINGS /wd4305 /wd4244" ) +ENDIF(MSVC) + ADD_DEFINITIONS(-DCAELUM_LIB) -INCLUDE_DIRECTORIES( ${CMAKE_HOME_DIRECTORY}/extern/caelum/include ) +INCLUDE_DIRECTORIES( + ${CMAKE_HOME_DIRECTORY}/extern/caelum/include + ${OGRE_INCLUDE_DIR}/Ogre + ) file(GLOB_RECURSE CAELUM_SRC src/*) file(GLOB_RECURSE CAELUM_HDR include/*) From 22c13147384c1b804f7ee5209e16b36fd1b86295 Mon Sep 17 00:00:00 2001 From: athile Date: Tue, 6 Jul 2010 10:03:49 -0700 Subject: [PATCH 2/4] Potential fix for inability to cancel Boost.Asio blocking accept on Linux --- components/commandserver/server.cpp | 46 ++++++++++++++++++++++++----- components/commandserver/server.hpp | 1 + 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/components/commandserver/server.cpp b/components/commandserver/server.cpp index c8bf34bfa..a63424242 100755 --- a/components/commandserver/server.cpp +++ b/components/commandserver/server.cpp @@ -1,10 +1,8 @@ - #include "server.hpp" +#include "libs/platform/strings.h" using boost::asio::ip::tcp; -#include - // // Namespace for containing implementation details that the // rest of OpenMW doesn't need to worry about @@ -105,7 +103,7 @@ namespace OMW { namespace CommandServer { namespace Detail { bDone = true; } else - throw str_exception("Unexpected header!"); + throw std::runtime_error("Unexpected header!"); } else bDone = true; @@ -120,12 +118,12 @@ namespace OMW { namespace CommandServer { using namespace Detail; Server::Server (Deque* pCommandQueue, const int port) - : mAcceptor (mIOService, tcp::endpoint(tcp::v4(), port)) + : mPort (port) + , mAcceptor (mIOService, tcp::endpoint(tcp::v4(), mPort)) , mbStopping (false) , mpCommandQueue (pCommandQueue) { } - void Server::start() { @@ -133,8 +131,41 @@ namespace OMW { namespace CommandServer { 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(); @@ -144,7 +175,6 @@ namespace OMW { namespace CommandServer { // open connections { boost::mutex::scoped_lock lock(mConnectionsMutex); - mbStopping = true; for (ConnectionSet::iterator it = mConnections.begin(); it != mConnections.end(); ++it) @@ -186,7 +216,7 @@ namespace OMW { namespace CommandServer { std::auto_ptr spConnection(new Connection(mAcceptor.io_service(), this)); boost::system::error_code ec; mAcceptor.accept(spConnection->socket(), ec); - if (!ec) + if (!ec && !mbStopping) { boost::mutex::scoped_lock lock(mConnectionsMutex); mConnections.insert(spConnection.get()); diff --git a/components/commandserver/server.hpp b/components/commandserver/server.hpp index b53e0f23a..3d7665a14 100755 --- a/components/commandserver/server.hpp +++ b/components/commandserver/server.hpp @@ -45,6 +45,7 @@ namespace OMW { namespace CommandServer 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; From 57de436db4310119c3960106789b4d37e9fd24cb Mon Sep 17 00:00:00 2001 From: athile Date: Tue, 6 Jul 2010 10:21:18 -0700 Subject: [PATCH 3/4] Command server Linux fix for open client connections. --- components/commandserver/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/commandserver/server.cpp b/components/commandserver/server.cpp index a63424242..26f328ecd 100755 --- a/components/commandserver/server.cpp +++ b/components/commandserver/server.cpp @@ -53,7 +53,7 @@ namespace OMW { namespace CommandServer { namespace Detail { /// void Connection::stop() { - mSocket.close(); + mSocket.shutdown(boost::asio::socket_base::shutdown_both); mpThread->join(); } From a638c330ec11fee74e2efcd11018bb321ddf2c53 Mon Sep 17 00:00:00 2001 From: athile Date: Tue, 6 Jul 2010 10:28:48 -0700 Subject: [PATCH 4/4] Add one more command server fix so it still works correctly on Windows and reeanble the command server by default. --- apps/openmw/main.cpp | 4 ++-- components/commandserver/server.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 82d69fcd8..63ea7e427 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -32,7 +32,7 @@ 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" ) - ( "enable-command-server", "turn on the command server" ) + ( "disable-command-server", "turn off the command server" ) ; bpo::variables_map variables; @@ -64,7 +64,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) if (variables.count ("new-game")) engine.setNewGame(); - if (variables.count("enable-command-server")) + if (variables.count("disable-command-server") == 0) engine.enableCommandServer(); return true; diff --git a/components/commandserver/server.cpp b/components/commandserver/server.cpp index 26f328ecd..53d7b2bf2 100755 --- a/components/commandserver/server.cpp +++ b/components/commandserver/server.cpp @@ -54,6 +54,7 @@ namespace OMW { namespace CommandServer { namespace Detail { void Connection::stop() { mSocket.shutdown(boost::asio::socket_base::shutdown_both); + mSocket.close(); mpThread->join(); }