mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:56:42 +00:00 
			
		
		
		
	added local script compiling
This commit is contained in:
		
							parent
							
								
									2064c43d89
								
							
						
					
					
						commit
						076b01559f
					
				
					 9 changed files with 187 additions and 39 deletions
				
			
		|  | @ -41,7 +41,9 @@ set(GAMESCRIPT | |||
|     apps/openmw/mwscript/scriptmanager.cpp) | ||||
| set(GAMESCRIPT_HEADER  | ||||
|     apps/openmw/mwscript/locals.hpp | ||||
|     apps/openmw/mwscript/scriptmanager.hpp) | ||||
|     apps/openmw/mwscript/scriptmanager.hpp | ||||
|     apps/openmw/mwscript/compilercontext.hpp | ||||
|     apps/openmw/mwscript/compilercontextscript.hpp) | ||||
| source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER})     | ||||
| 
 | ||||
| set(APPS ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT}) | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| 
 | ||||
| #include "mwinput/inputmanager.hpp" | ||||
| #include "mwscript/scriptmanager.hpp" | ||||
| #include "mwscript/compilercontextscript.hpp" | ||||
| 
 | ||||
| #include "world.hpp" | ||||
| 
 | ||||
|  | @ -30,12 +31,13 @@ void OMW::Engine::executeLocalScripts() | |||
|     for (World::ScriptList::const_iterator iter (mWorld->getLocalScripts().begin()); | ||||
|         iter!=mWorld->getLocalScripts().end(); ++iter) | ||||
|     { | ||||
|         mScriptManager->run (iter->first); | ||||
|         mScriptManager->run (iter->first, *iter->second); | ||||
|      | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| OMW::Engine::Engine() : mWorld(NULL), mDebug (false), mScriptManager (0) | ||||
| OMW::Engine::Engine() | ||||
| : mWorld(NULL), mDebug (false), mScriptManager (0), mScriptContext (0) | ||||
| { | ||||
|     mspCommandServer.reset( | ||||
|         new OMW::CommandServer::Server(&mCommandQueue, kCommandServerPort)); | ||||
|  | @ -46,6 +48,7 @@ OMW::Engine::~Engine() | |||
| //    mspCommandServer->stop();
 | ||||
|     delete mWorld; | ||||
|     delete mScriptManager; | ||||
|     delete mScriptContext; | ||||
| } | ||||
| 
 | ||||
| // Load all BSA files in data directory.
 | ||||
|  | @ -158,8 +161,11 @@ void OMW::Engine::go() | |||
| 
 | ||||
|     // Create the world
 | ||||
|     mWorld = new World (mOgre, mDataDir, mMaster, mCellName); | ||||
|      | ||||
|     mScriptManager = new MWScript::ScriptManager (mWorld->getStore(), mVerboseScripts); | ||||
| 
 | ||||
|     mScriptContext = new MWScript::CompilerContextScript; | ||||
| 
 | ||||
|     mScriptManager = new MWScript::ScriptManager (mWorld->getStore(), mVerboseScripts, | ||||
|         *mScriptContext); | ||||
|      | ||||
|     executeLocalScripts(); // TODO move into a framelistener
 | ||||
|      | ||||
|  |  | |||
|  | @ -12,6 +12,11 @@ | |||
| 
 | ||||
| #include "mwrender/mwscene.hpp" | ||||
| 
 | ||||
| namespace Compiler | ||||
| { | ||||
|     class Context; | ||||
| } | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     class ScriptManager; | ||||
|  | @ -39,6 +44,7 @@ namespace OMW | |||
|             std::auto_ptr<OMW::CommandServer::Server> mspCommandServer; | ||||
| 
 | ||||
|             MWScript::ScriptManager *mScriptManager; | ||||
|             Compiler::Context *mScriptContext; | ||||
| 
 | ||||
|             // not implemented
 | ||||
|             Engine (const Engine&); | ||||
|  |  | |||
							
								
								
									
										15
									
								
								apps/openmw/mwscript/compilercontext.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								apps/openmw/mwscript/compilercontext.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| #ifndef GAME_SCRIPT_COMPILERCONTEXT_H | ||||
| #define GAME_SCRIPT_COMPILERCONTEXT_H | ||||
| 
 | ||||
| #include <components/compiler/context.hpp> | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     class CompilerContext : public Compiler::Context | ||||
|     { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										22
									
								
								apps/openmw/mwscript/compilercontextscript.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								apps/openmw/mwscript/compilercontextscript.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #ifndef GAME_SCRIPT_COMPILERCONTEXTSCRIPT_H | ||||
| #define GAME_SCRIPT_COMPILERCONTEXTSCRIPT_H | ||||
| 
 | ||||
| #include "compilercontext.hpp" | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     /// Context for local scripts, global scripts and targetted scripts
 | ||||
| 
 | ||||
|     class CompilerContextScript : public CompilerContext | ||||
|     { | ||||
|         public: | ||||
|          | ||||
|             // Is the compiler allowed to declare local variables?
 | ||||
|             virtual bool canDeclareLocals() const | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -1,19 +1,98 @@ | |||
| 
 | ||||
| #include "scriptmanager.hpp" | ||||
| 
 | ||||
| #include <components/compiler/scanner.hpp> | ||||
| 
 | ||||
| #include <cassert> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <exception> | ||||
| 
 | ||||
| #include <components/esm/loadscpt.hpp> | ||||
| #include <components/esm_store/store.hpp> | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     ScriptManager::ScriptManager (const ESMS::ESMStore& store, bool verbose) | ||||
|     : mStore (store), mVerbose (verbose) | ||||
|     ScriptManager::ScriptManager (const ESMS::ESMStore& store, bool verbose, | ||||
|         Compiler::Context& compilerContext) | ||||
|     : mErrorHandler (std::cerr), mStore (store), mVerbose (verbose), | ||||
|       mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext) | ||||
|     {} | ||||
|      | ||||
|     void ScriptManager::run (const std::string& name/*, Compiler::Context& compilerContext,
 | ||||
|         Interpreter::Context& interpreterContext, Locals& locals*/) | ||||
|     bool ScriptManager::compile (const std::string& name) | ||||
|     { | ||||
|         std::cout << "script request: " << name << std::endl; | ||||
|         mParser.reset(); | ||||
|         mErrorHandler.reset(); | ||||
| 
 | ||||
|         bool Success = true; | ||||
| 
 | ||||
|         if (const ESM::Script *script = mStore.scripts.find (name)) | ||||
|         {              | ||||
|             if (mVerbose) | ||||
|                 std::cout << "compiling script: " << name << std::endl; | ||||
|              | ||||
|             try | ||||
|             {         | ||||
|                 std::istringstream input (script->scriptText); | ||||
|              | ||||
|                 Compiler::Scanner scanner (mErrorHandler, input); | ||||
|              | ||||
|                 scanner.scan (mParser); | ||||
|                  | ||||
|                 if (!mErrorHandler.isGood()) | ||||
|                     Success = false; | ||||
|             } | ||||
|             catch (const std::exception& error) | ||||
|             { | ||||
|                 Success = false; | ||||
|             } | ||||
| 
 | ||||
|             if (!Success && mVerbose) | ||||
|             { | ||||
|                 std::cerr | ||||
|                     << "compiling failed: " << name << std::endl | ||||
|                     << script->scriptText | ||||
|                     << std::endl << std::endl; | ||||
|             } | ||||
|              | ||||
|             if (Success) | ||||
|             { | ||||
|                 std::vector<Interpreter::Type_Code> code; | ||||
|                 mParser.getCode (code); | ||||
|                 mScripts.insert (std::make_pair (name, code)); | ||||
|                  | ||||
|                 // TODO sanity check on generated locals
 | ||||
|                  | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         return false;     | ||||
|     } | ||||
| 
 | ||||
|     void ScriptManager::run (const std::string& name/*,
 | ||||
|         Interpreter::Context& interpreterContext*/, Locals& locals) | ||||
|     { | ||||
|         // compile script
 | ||||
|         std::map<std::string, std::vector<Interpreter::Type_Code> >::iterator iter = | ||||
|             mScripts.find (name); | ||||
|              | ||||
|         if (iter==mScripts.end()) | ||||
|         { | ||||
|             if (!compile (name)) | ||||
|             { | ||||
|                 // failed -> ignore script from now on.
 | ||||
|                 std::vector<Interpreter::Type_Code> empty; | ||||
|                 mScripts.insert (std::make_pair (name, empty)); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             iter = mScripts.find (name); | ||||
|             assert (iter!=mScripts.end()); | ||||
|         } | ||||
|      | ||||
|         // execute script
 | ||||
|          | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,6 +5,9 @@ | |||
| #include <vector> | ||||
| #include <string> | ||||
| 
 | ||||
| #include <components/compiler/streamerrorhandler.hpp> | ||||
| #include <components/compiler/fileparser.hpp> | ||||
| 
 | ||||
| #include <components/interpreter/types.hpp> | ||||
| 
 | ||||
| namespace ESMS | ||||
|  | @ -28,20 +31,25 @@ namespace MWScript | |||
|      | ||||
|     class ScriptManager | ||||
|     { | ||||
|             Compiler::StreamErrorHandler mErrorHandler; | ||||
|             const ESMS::ESMStore& mStore; | ||||
|             bool mVerbose; | ||||
|             Compiler::Context& mCompilerContext; | ||||
|             Compiler::FileParser mParser; | ||||
|              | ||||
|             std::map<std::string, std::vector<Interpreter::Type_Code> > mScripts; | ||||
|              | ||||
|             bool compile (const std::string& name); | ||||
|              | ||||
|         public: | ||||
|          | ||||
|             ScriptManager (const ESMS::ESMStore& store, bool verbose); | ||||
|             ScriptManager (const ESMS::ESMStore& store, bool verbose, | ||||
|                 Compiler::Context& compilerContext); | ||||
|              | ||||
|             void run (const std::string& name/*, Compiler::Context& compilerContext,
 | ||||
|                 Interpreter::Context& interpreterContext, Locals& locals*/); | ||||
|             void run (const std::string& name/*,
 | ||||
|                 Interpreter::Context& interpreterContext*/, Locals& locals); | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,8 +19,11 @@ namespace OMW | |||
|             MWScript::Locals mLocals; // if we find the overhead of heaving a locals
 | ||||
|                                       // object in the refdata of refs without a script,
 | ||||
|                                       // we can make this a pointer later.
 | ||||
|             bool mHasLocals; | ||||
|          | ||||
|         public: | ||||
|          | ||||
|             RefData() : mHasLocals (false) {} | ||||
|                           | ||||
|             std::string getHandle() | ||||
|             { | ||||
|  | @ -29,7 +32,11 @@ namespace OMW | |||
|                          | ||||
|             void setLocals (const ESM::Script& script) | ||||
|             { | ||||
|                 mLocals.configure (script); | ||||
|                 if (!mHasLocals) | ||||
|                 { | ||||
|                     mLocals.configure (script); | ||||
|                     mHasLocals = true; | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             void setHandle (const std::string& handle) | ||||
|  |  | |||
|  | @ -10,20 +10,23 @@ | |||
| namespace | ||||
| { | ||||
|     template<typename T> | ||||
|     void listCellScripts (ESMS::CellRefList<T, OMW::RefData>& cellRefList, | ||||
|         OMW::World::ScriptList& scriptList) | ||||
|     void listCellScripts (const ESMS::ESMStore& store, | ||||
|         ESMS::CellRefList<T, OMW::RefData>& cellRefList, OMW::World::ScriptList& scriptList) | ||||
|     { | ||||
|         for (typename ESMS::CellRefList<T, OMW::RefData>::List::iterator iter ( | ||||
|             cellRefList.list.begin()); | ||||
|             iter!=cellRefList.list.end(); ++iter) | ||||
|         { | ||||
|             if (!iter->base->script.empty()) | ||||
|                 scriptList.push_back ( | ||||
|                     std::make_pair (iter->base->script, static_cast<MWScript::Locals *> (0))); | ||||
|             { | ||||
|                 if (const ESM::Script *script = store.scripts.find (iter->base->script)) | ||||
|                 {            | ||||
|                     iter->mData.setLocals (*script); | ||||
|              | ||||
|             // TODO local variables
 | ||||
|          | ||||
|          | ||||
|                     scriptList.push_back ( | ||||
|                         std::make_pair (iter->base->script, &iter->mData.getLocals())); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -32,23 +35,23 @@ namespace OMW | |||
| { | ||||
|     void World::insertInteriorScripts (ESMS::CellStore<OMW::RefData>& cell) | ||||
|     { | ||||
|         listCellScripts (cell.activators, mLocalScripts); | ||||
|         listCellScripts (cell.potions, mLocalScripts); | ||||
|         listCellScripts (cell.appas, mLocalScripts); | ||||
|         listCellScripts (cell.armors, mLocalScripts); | ||||
|         listCellScripts (cell.books, mLocalScripts); | ||||
|         listCellScripts (cell.clothes, mLocalScripts); | ||||
|         listCellScripts (cell.containers, mLocalScripts); | ||||
|         listCellScripts (cell.creatures, mLocalScripts); | ||||
|         listCellScripts (cell.doors, mLocalScripts); | ||||
|         listCellScripts (cell.ingreds, mLocalScripts); | ||||
|         listCellScripts (cell.lights, mLocalScripts); | ||||
|         listCellScripts (cell.lockpicks, mLocalScripts); | ||||
|         listCellScripts (cell.miscItems, mLocalScripts); | ||||
|         listCellScripts (cell.npcs, mLocalScripts); | ||||
|         listCellScripts (cell.probes, mLocalScripts); | ||||
|         listCellScripts (cell.repairs, mLocalScripts); | ||||
|         listCellScripts (cell.weapons, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.activators, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.potions, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.appas, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.armors, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.books, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.clothes, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.containers, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.creatures, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.doors, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.ingreds, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.lights, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.lockpicks, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.miscItems, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.npcs, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.probes, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.repairs, mLocalScripts); | ||||
|         listCellScripts (mStore, cell.weapons, mLocalScripts); | ||||
|     } | ||||
|      | ||||
|     World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue