From 80691250ecffb239505a82e703a2398314c9b6b8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 18 May 2011 16:01:19 +0200 Subject: [PATCH 1/3] don't create a new virtual machine for each script and frame --- apps/openmw/mwgui/console.cpp | 4 +- apps/openmw/mwscript/scriptmanager.cpp | 15 ++++--- apps/openmw/mwscript/scriptmanager.hpp | 3 ++ components/interpreter/interpreter.cpp | 7 ++-- components/interpreter/interpreter.hpp | 23 +++++----- components/interpreter/runtime.cpp | 58 +++++++++++++------------- components/interpreter/runtime.hpp | 38 ++++++++--------- 7 files changed, 77 insertions(+), 71 deletions(-) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 0421dc370..baa1309af 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -223,11 +223,11 @@ namespace MWGui try { ConsoleInterpreterContext interpreterContext (*this, mEnvironment, MWWorld::Ptr()); - Interpreter::Interpreter interpreter (interpreterContext); + Interpreter::Interpreter interpreter; MWScript::installOpcodes (interpreter); std::vector code; output.getCode (code); - interpreter.run (&code[0], code.size()); + interpreter.run (&code[0], code.size(), interpreterContext); } catch (const std::exception& error) { diff --git a/apps/openmw/mwscript/scriptmanager.cpp b/apps/openmw/mwscript/scriptmanager.cpp index 727297a98..07fa93454 100644 --- a/apps/openmw/mwscript/scriptmanager.cpp +++ b/apps/openmw/mwscript/scriptmanager.cpp @@ -12,8 +12,6 @@ #include #include -#include - #include "extensions.hpp" namespace MWScript @@ -21,7 +19,8 @@ namespace MWScript ScriptManager::ScriptManager (const ESMS::ESMStore& store, bool verbose, Compiler::Context& compilerContext) : mErrorHandler (std::cerr), mStore (store), mVerbose (verbose), - mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext) + mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext), + mOpcodesInstalled (false) {} bool ScriptManager::compile (const std::string& name) @@ -99,9 +98,13 @@ namespace MWScript if (!iter->second.empty()) try { - Interpreter::Interpreter interpreter (interpreterContext); - installOpcodes (interpreter); - interpreter.run (&iter->second[0], iter->second.size()); + if (!mOpcodesInstalled) + { + installOpcodes (mInterpreter); + mOpcodesInstalled = true; + } + + mInterpreter.run (&iter->second[0], iter->second.size(), interpreterContext); } catch (const std::exception& e) { diff --git a/apps/openmw/mwscript/scriptmanager.hpp b/apps/openmw/mwscript/scriptmanager.hpp index 639fc59bf..eab9bdcc0 100644 --- a/apps/openmw/mwscript/scriptmanager.hpp +++ b/apps/openmw/mwscript/scriptmanager.hpp @@ -8,6 +8,7 @@ #include #include +#include #include namespace ESMS @@ -35,6 +36,8 @@ namespace MWScript bool mVerbose; Compiler::Context& mCompilerContext; Compiler::FileParser mParser; + Interpreter::Interpreter mInterpreter; + bool mOpcodesInstalled; std::map > mScripts; diff --git a/components/interpreter/interpreter.cpp b/components/interpreter/interpreter.cpp index 44f626aad..10937e6bc 100644 --- a/components/interpreter/interpreter.cpp +++ b/components/interpreter/interpreter.cpp @@ -134,8 +134,7 @@ namespace Interpreter throw std::runtime_error (error.str()); } - Interpreter::Interpreter (Context& context) - : mRuntime (context) + Interpreter::Interpreter() {} Interpreter::~Interpreter() @@ -195,11 +194,11 @@ namespace Interpreter mSegment5.insert (std::make_pair (code, opcode)); } - void Interpreter::run (const Type_Code *code, int codeSize) + void Interpreter::run (const Type_Code *code, int codeSize, Context& context) { assert (codeSize>=4); - mRuntime.configure (code, codeSize); + mRuntime.configure (code, codeSize, context); int opcodes = static_cast (code[0]); diff --git a/components/interpreter/interpreter.hpp b/components/interpreter/interpreter.hpp index c67273707..e1016235a 100644 --- a/components/interpreter/interpreter.hpp +++ b/components/interpreter/interpreter.hpp @@ -21,23 +21,23 @@ namespace Interpreter std::map mSegment3; std::map mSegment4; std::map mSegment5; - + // not implemented Interpreter (const Interpreter&); Interpreter& operator= (const Interpreter&); - + void execute (Type_Code code); - + void abortUnknownCode (int segment, int opcode); - + void abortUnknownSegment (Type_Code code); - + public: - - Interpreter (Context& context); - + + Interpreter(); + ~Interpreter(); - + void installSegment0 (int code, Opcode1 *opcode); ///< ownership of \a opcode is transferred to *this. @@ -55,10 +55,9 @@ namespace Interpreter void installSegment5 (int code, Opcode0 *opcode); ///< ownership of \a opcode is transferred to *this. - - void run (const Type_Code *code, int codeSize); + + void run (const Type_Code *code, int codeSize, Context& context); }; } #endif - diff --git a/components/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index f3a3a905d..dcf17d255 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -7,50 +7,51 @@ namespace Interpreter { - Runtime::Runtime (Context& context) : mContext (context), mCode (0), mPC (0) {} - + Runtime::Runtime() : mContext (0), mCode (0), mPC (0) {} + int Runtime::getPC() const { return mPC; } - + int Runtime::getIntegerLiteral (int index) const { assert (index>=0 && index (mCode[1])); - + const Type_Code *literalBlock = mCode + 4 + mCode[0]; - + return *reinterpret_cast (&literalBlock[index]); } - + float Runtime::getFloatLiteral (int index) const { assert (index>=0 && index (mCode[2])); - + const Type_Code *literalBlock = mCode + 4 + mCode[0] + mCode[1]; - + return *reinterpret_cast (&literalBlock[index]); } - + std::string Runtime::getStringLiteral (int index) const { assert (index>=0 && index (mCode[3])); - + const char *literalBlock = reinterpret_cast (mCode + 4 + mCode[0] + mCode[1] + mCode[2]); - + for (; index; --index) { literalBlock += std::strlen (literalBlock) + 1; } - + return literalBlock; } - - void Runtime::configure (const Interpreter::Type_Code *code, int codeSize) - { + + void Runtime::configure (const Interpreter::Type_Code *code, int codeSize, Context& context) + { clear(); - + + mContext = &context; mCode = code; mCodeSize = codeSize; mPC = 0; @@ -58,54 +59,55 @@ namespace Interpreter void Runtime::clear() { + mContext = 0; mCode = 0; mCodeSize = 0; mStack.clear(); } - + void Runtime::setPC (int PC) { mPC = PC; - } - + } + void Runtime::push (const Data& data) { mStack.push_back (data); } - + void Runtime::push (Type_Integer value) { Data data; data.mInteger = value; push (data); } - + void Runtime::push (Type_Float value) { Data data; data.mFloat = value; push (data); } - + void Runtime::pop() { if (mStack.empty()) throw std::runtime_error ("stack underflow"); - + mStack.resize (mStack.size()-1); } - + Data& Runtime::operator[] (int Index) { if (Index<0 || Index>=static_cast (mStack.size())) throw std::runtime_error ("stack index out of range"); - + return mStack[mStack.size()-Index-1]; } - + Context& Runtime::getContext() { - return mContext; + assert (mContext); + return *mContext; } } - diff --git a/components/interpreter/runtime.hpp b/components/interpreter/runtime.hpp index e9ba01041..2811ab0f0 100644 --- a/components/interpreter/runtime.hpp +++ b/components/interpreter/runtime.hpp @@ -11,52 +11,52 @@ namespace Interpreter class Context; /// Runtime data and engine interface - + class Runtime { - Context& mContext; + Context *mContext; const Type_Code *mCode; int mCodeSize; int mPC; std::vector mStack; - + public: - - Runtime (Context& context); - + + Runtime (); + int getPC() const; ///< return program counter. - + int getIntegerLiteral (int index) const; - + float getFloatLiteral (int index) const; - + std::string getStringLiteral (int index) const; - - void configure (const Type_Code *code, int codeSize); + + void configure (const Type_Code *code, int codeSize, Context& context); ///< \a context and \a code must exist as least until either configure, clear or /// the destructor is called. \a codeSize is given in 32-bit words. - + void clear(); - + void setPC (int PC); ///< set program counter. - + void push (const Data& data); ///< push data on stack - + void push (Type_Integer value); ///< push integer data on stack. - + void push (Type_Float value); ///< push float data on stack. - + void pop(); ///< pop stack - + Data& operator[] (int Index); ///< Access stack member, counted from the top. - + Context& getContext(); }; } From 64d6ee26bd67a317536e6c475171c3f0b8612ef2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 18 May 2011 16:37:09 +0200 Subject: [PATCH 2/3] changed OGRE framelistener function from frameStarted to frameRenderingQueued --- apps/openmw/engine.cpp | 2 +- apps/openmw/engine.hpp | 2 +- apps/openmw/mwinput/inputmanager.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index e1ce97bfa..b2ed0a767 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -76,7 +76,7 @@ void OMW::Engine::executeLocalScripts() } -bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) +bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) { if(mShowFPS) { diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index e49ddfc06..4c70d7f35 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -100,7 +100,7 @@ namespace OMW void executeLocalScripts(); - virtual bool frameStarted(const Ogre::FrameEvent& evt); + virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); /// Process pending commands diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index dc21680af..eb6c59963 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -258,7 +258,7 @@ namespace MWInput } //NOTE: Used to check for movement keys - bool frameStarted(const Ogre::FrameEvent &evt) + bool frameRenderingQueued (const Ogre::FrameEvent &evt) { // Tell OIS to handle all input events input.capture(); From 231be8f38165960856cb5dc6f038a759d8dc78a1 Mon Sep 17 00:00:00 2001 From: athile Date: Tue, 31 May 2011 21:55:08 -0600 Subject: [PATCH 3/3] Add BULLET_ROOT for the prebuilt binaries. Fix a minor VS2010 compile issue (missing header file). --- CMakeLists.txt | 3 ++- components/files/multidircollection.hpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5001a894..8e0c0c463 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,8 @@ IF(EXISTS "${CMAKE_SOURCE_DIR}/prebuilt/vc100-mt-gd/ogre_1_7_1") set(AUDIERE_LIBRARY "${PREBUILT_DIR}/audiere-1.9.4/lib/audiere.lib") set(ENV{OPENALDIR} "${PREBUILT_DIR}/OpenAL 1.1 SDK") - + + set(BULLET_ROOT "${PREBUILT_DIR}/bullet") ELSE() message (STATUS "OpenMW pre-built binaries not found. Using standard locations.") ENDIF() diff --git a/components/files/multidircollection.hpp b/components/files/multidircollection.hpp index bd0304e40..a04c12c22 100644 --- a/components/files/multidircollection.hpp +++ b/components/files/multidircollection.hpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include