From 474b412b47d61ad0b070df708af928322b57a577 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 2 Jul 2010 18:08:00 +0200 Subject: [PATCH] implemented local script execution --- CMakeLists.txt | 6 +- apps/openmw/engine.cpp | 4 +- apps/openmw/mwscript/interpretercontext.cpp | 72 +++++++++++++++++++++ apps/openmw/mwscript/interpretercontext.hpp | 44 +++++++++++++ apps/openmw/mwscript/scriptmanager.cpp | 24 +++++-- apps/openmw/mwscript/scriptmanager.hpp | 7 +- components/interpreter/context.hpp | 3 + 7 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 apps/openmw/mwscript/interpretercontext.cpp create mode 100644 apps/openmw/mwscript/interpretercontext.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f3aa546ac..c0ce129df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,12 +38,14 @@ set(GAMEINPUT_HEADER source_group(apps\\openmw\\mwinput FILES ${GAMEINPUT} ${GAMEINPUT_HEADER}) set(GAMESCRIPT - apps/openmw/mwscript/scriptmanager.cpp) + apps/openmw/mwscript/scriptmanager.cpp + apps/openmw/mwscript/interpretercontext.cpp) set(GAMESCRIPT_HEADER apps/openmw/mwscript/locals.hpp apps/openmw/mwscript/scriptmanager.hpp apps/openmw/mwscript/compilercontext.hpp - apps/openmw/mwscript/compilercontextscript.hpp) + apps/openmw/mwscript/compilercontextscript.hpp + apps/openmw/mwscript/interpretercontext.hpp) source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER}) set(APPS ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT}) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 526e316c7..507cbc453 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -10,6 +10,7 @@ #include "mwinput/inputmanager.hpp" #include "mwscript/scriptmanager.hpp" #include "mwscript/compilercontextscript.hpp" +#include "mwscript/interpretercontext.hpp" #include "world.hpp" @@ -18,7 +19,8 @@ void OMW::Engine::executeLocalScripts() for (World::ScriptList::const_iterator iter (mWorld->getLocalScripts().begin()); iter!=mWorld->getLocalScripts().end(); ++iter) { - mScriptManager->run (iter->first, *iter->second); + MWScript::InterpreterContext interpreterContext (*mWorld, iter->second); + mScriptManager->run (iter->first, interpreterContext); } } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp new file mode 100644 index 000000000..784cc9afa --- /dev/null +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -0,0 +1,72 @@ + +#include "interpretercontext.hpp" + +#include +#include + +#include "locals.hpp" + +namespace MWScript +{ + InterpreterContext::InterpreterContext (OMW::World& world, MWScript::Locals *locals) + : mWorld (world), mLocals (locals) + {} + + int InterpreterContext::getLocalShort (int index) const + { + if (!mLocals) + throw std::runtime_error ("local variables not available in this context"); + + return mLocals->mShorts.at (index); + } + + int InterpreterContext::getLocalLong (int index) const + { + if (!mLocals) + throw std::runtime_error ("local variables not available in this context"); + + return mLocals->mLongs.at (index); + } + + float InterpreterContext::getLocalFloat (int index) const + { + if (!mLocals) + throw std::runtime_error ("local variables not available in this context"); + + return mLocals->mFloats.at (index); + } + + void InterpreterContext::setLocalShort (int index, int value) + { + if (!mLocals) + throw std::runtime_error ("local variables not available in this context"); + + mLocals->mShorts.at (index) = value; + } + + void InterpreterContext::setLocalLong (int index, int value) + { + if (!mLocals) + throw std::runtime_error ("local variables not available in this context"); + + mLocals->mLongs.at (index) = value; + } + + void InterpreterContext::setLocalFloat (int index, float value) + { + if (!mLocals) + throw std::runtime_error ("local variables not available in this context"); + + mLocals->mFloats.at (index) = value; + } + + void InterpreterContext::messageBox (const std::string& message, + const std::vector& buttons) + { + std::cout << "message box: " << message << std::endl; + + if (!buttons.empty()) + std::cerr << "error: message box buttons not supported" << std::endl; + } +} + diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp new file mode 100644 index 000000000..c023b67d0 --- /dev/null +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -0,0 +1,44 @@ +#ifndef GAME_SCRIPT_INTERPRETERCONTEXT_H +#define GAME_SCRIPT_INTERPRETERCONTEXT_H + +#include + +namespace OMW +{ + class World; +} + +namespace MWScript +{ + struct Locals; + + class InterpreterContext : public Interpreter::Context + { + OMW::World& mWorld; + Locals *mLocals; + + public: + + InterpreterContext (OMW::World& world, MWScript::Locals *locals); + ///< The ownership of \a locals is not transferred. 0-pointer allowed. + + 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); + }; +} + +#endif + + diff --git a/apps/openmw/mwscript/scriptmanager.cpp b/apps/openmw/mwscript/scriptmanager.cpp index 06d6616c7..607cfc829 100644 --- a/apps/openmw/mwscript/scriptmanager.cpp +++ b/apps/openmw/mwscript/scriptmanager.cpp @@ -1,8 +1,6 @@ #include "scriptmanager.hpp" -#include - #include #include #include @@ -11,6 +9,12 @@ #include #include +#include + +#include +#include + + namespace MWScript { ScriptManager::ScriptManager (const ESMS::ESMStore& store, bool verbose, @@ -70,8 +74,7 @@ namespace MWScript return false; } - void ScriptManager::run (const std::string& name/*, - Interpreter::Context& interpreterContext*/, Locals& locals) + void ScriptManager::run (const std::string& name, Interpreter::Context& interpreterContext) { // compile script std::map >::iterator iter = @@ -92,7 +95,18 @@ namespace MWScript } // execute script - + if (!iter->second.empty()) + try + { + Interpreter::Interpreter interpreter (interpreterContext); + Interpreter::installOpcodes (interpreter); + interpreter.run (&iter->second[0], iter->second.size()); + } + catch (...) + { + std::cerr << "exeution of script " << name << " failed." << std::endl; + iter->second.clear(); // don't execute again. + } } } diff --git a/apps/openmw/mwscript/scriptmanager.hpp b/apps/openmw/mwscript/scriptmanager.hpp index 1b5176609..c029d6506 100644 --- a/apps/openmw/mwscript/scriptmanager.hpp +++ b/apps/openmw/mwscript/scriptmanager.hpp @@ -26,9 +26,7 @@ namespace Interpreter } namespace MWScript -{ - struct Locals; - +{ class ScriptManager { Compiler::StreamErrorHandler mErrorHandler; @@ -46,8 +44,7 @@ namespace MWScript ScriptManager (const ESMS::ESMStore& store, bool verbose, Compiler::Context& compilerContext); - void run (const std::string& name/*, - Interpreter::Context& interpreterContext*/, Locals& locals); + void run (const std::string& name, Interpreter::Context& interpreterContext); }; }; diff --git a/components/interpreter/context.hpp b/components/interpreter/context.hpp index 32bde722e..d08e6dac0 100644 --- a/components/interpreter/context.hpp +++ b/components/interpreter/context.hpp @@ -1,6 +1,9 @@ #ifndef INTERPRETER_CONTEXT_H_INCLUDED #define INTERPRETER_CONTEXT_H_INCLUDED +#include +#include + namespace Interpreter { class Context