1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 03:29:55 +00:00

Console command "reload lua"

This commit is contained in:
Petr Mikheev 2021-04-12 03:15:17 +02:00
parent 9d09ecf8ca
commit d5cda61855
10 changed files with 58 additions and 3 deletions

View file

@ -59,6 +59,9 @@ namespace MWBase
// Should be called before loading. The map is used to fix refnums if the order of content files was changed.
virtual void setContentFileMapping(const std::map<int, int>&) = 0;
// Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script.
virtual void reloadAllScripts() = 0;
};
}

View file

@ -20,6 +20,7 @@
#include "../mwbase/scriptmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/luamanager.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/class.hpp"

View file

@ -334,4 +334,30 @@ namespace MWLua
scripts->setSerializer(mLocalSerializer.get());
}
void LuaManager::reloadAllScripts()
{
Log(Debug::Info) << "Reload Lua";
mLua.dropScriptCache();
{ // Reload global scripts
ESM::LuaScripts data;
mGlobalScripts.save(data);
mGlobalScripts.removeAllScripts();
for (const std::string& path : mGlobalScriptList)
if (mGlobalScripts.addNewScript(path))
Log(Debug::Info) << "Global script restarted: " << path;
mGlobalScripts.load(data, false);
}
for (const auto& [id, ptr] : mWorldView.getObjectRegistry()->mObjectMapping)
{ // Reload local scripts
LocalScripts* scripts = ptr.getRefData().getLuaScripts();
if (scripts == nullptr)
continue;
ESM::LuaScripts data;
scripts->save(data);
scripts->load(data, true);
}
}
}

View file

@ -62,6 +62,9 @@ namespace MWLua
void loadLocalScripts(const MWWorld::Ptr& ptr, const ESM::LuaScripts& data) override;
void setContentFileMapping(const std::map<int, int>& mapping) override { mContentFileMapping = mapping; }
// Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script.
void reloadAllScripts() override;
private:
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr);

View file

@ -47,6 +47,7 @@ namespace MWLua
friend class Object;
friend class GObject;
friend class LObject;
friend class LuaManager;
bool mChanged = false;
int64_t mUpdateCounter = 0;

View file

@ -480,5 +480,6 @@ op 0x200031d: StartScript, explicit
op 0x200031e: GetDistance
op 0x200031f: GetDistance, explicit
op 0x2000320: Help
op 0x2000321: ReloadLua
opcodes 0x2000321-0x3ffffff unused
opcodes 0x2000322-0x3ffffff unused

View file

@ -28,6 +28,7 @@
#include "../mwbase/scriptmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/luamanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
@ -169,8 +170,6 @@ namespace MWScript
void execute (Interpreter::Runtime& runtime) override
{
MWWorld::Ptr ptr = R()(runtime);
if(!ptr.isEmpty() && !ptr.mRef->mData.isEnabled())
ptr.mRef->mData.mPhysicsPostponed = false;
MWBase::Environment::get().getWorld()->enable (ptr);
}
};
@ -1599,6 +1598,17 @@ namespace MWScript
}
};
class OpReloadLua : public Interpreter::Opcode0
{
public:
void execute (Interpreter::Runtime& runtime) override
{
MWBase::Environment::get().getLuaManager()->reloadAllScripts();
runtime.getContext().report("All Lua scripts are reloaded");
}
};
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (Compiler::Misc::opcodeMenuMode, new OpMenuMode);
@ -1719,6 +1729,7 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Misc::opcodeRepairedOnMeExplicit, new OpRepairedOnMe<ExplicitRef>);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleRecastMesh, new OpToggleRecastMesh);
interpreter.installSegment5 (Compiler::Misc::opcodeHelp, new OpHelp);
interpreter.installSegment5 (Compiler::Misc::opcodeReloadLua, new OpReloadLua);
}
}
}

View file

@ -338,6 +338,7 @@ namespace Compiler
extensions.registerFunction ("repairedonme", 'l', "S", opcodeRepairedOnMe, opcodeRepairedOnMeExplicit);
extensions.registerInstruction ("togglerecastmesh", "", opcodeToggleRecastMesh);
extensions.registerInstruction ("help", "", opcodeHelp);
extensions.registerInstruction ("reloadlua", "", opcodeReloadLua);
}
}

View file

@ -319,6 +319,7 @@ namespace Compiler
const int opcodeGetDisabledExplicit = 0x200031c;
const int opcodeStartScriptExplicit = 0x200031d;
const int opcodeHelp = 0x2000320;
const int opcodeReloadLua = 0x2000321;
}
namespace Sky

View file

@ -114,6 +114,13 @@ Finally :ref:`register <Lua scripting>` it in ``openmw.cfg``:
Now every time the player presses "X" on a keyboard, a message is shown.
Hot reloading
=============
It is possible to modify a script without restarting OpenMW. To apply changes open in-game console and run the command ``reloadlua``.
It will restart all Lua scripts using `onSave and onLoad`_ handlers the same way as if the game was saved and loaded.
It works only with existing ``*.lua`` files that are not packed to any archives. Adding new scripts or modifying ``*.omwscripts`` files always requires restarting the game.
Script structure
================