mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 21:07:59 +03:00
Merge branch 'unloadedcontainers' into 'master'
Fix Lua memory usage See merge request OpenMW/openmw!4363
This commit is contained in:
commit
bac0018a09
10 changed files with 425 additions and 97 deletions
|
@ -6,6 +6,7 @@
|
|||
#include <components/lua/asyncpackage.hpp>
|
||||
#include <components/lua/luastate.hpp>
|
||||
#include <components/lua/scriptscontainer.hpp>
|
||||
#include <components/lua/scripttracker.hpp>
|
||||
|
||||
#include <components/testing/util.hpp>
|
||||
|
||||
|
@ -135,6 +136,31 @@ return {
|
|||
end,
|
||||
},
|
||||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView unloadPath("unload.lua");
|
||||
|
||||
VFSTestFile unloadScript(R"X(
|
||||
x = 0
|
||||
y = 0
|
||||
z = 0
|
||||
return {
|
||||
engineHandlers = {
|
||||
onSave = function(state)
|
||||
print('saving', x, y, z)
|
||||
return {x = x, y = y}
|
||||
end,
|
||||
onLoad = function(state)
|
||||
x, y = state.x, state.y
|
||||
print('loaded', x, y, z)
|
||||
end
|
||||
},
|
||||
eventHandlers = {
|
||||
Set = function(eventData)
|
||||
x, y, z = eventData.x, eventData.y, eventData.z
|
||||
end
|
||||
}
|
||||
}
|
||||
)X");
|
||||
|
||||
struct LuaScriptsContainerTest : Test
|
||||
|
@ -151,6 +177,7 @@ return {
|
|||
{ testInterfacePath, &interfaceScript },
|
||||
{ overrideInterfacePath, &overrideInterfaceScript },
|
||||
{ useInterfacePath, &useInterfaceScript },
|
||||
{ unloadPath, &unloadScript },
|
||||
});
|
||||
|
||||
LuaUtil::ScriptsConfiguration mCfg;
|
||||
|
@ -171,6 +198,7 @@ CUSTOM, NPC: loadSave2.lua
|
|||
CUSTOM, PLAYER: testInterface.lua
|
||||
CUSTOM, PLAYER: overrideInterface.lua
|
||||
CUSTOM, PLAYER: useInterface.lua
|
||||
CUSTOM: unload.lua
|
||||
)X");
|
||||
mCfg.init(std::move(cfg));
|
||||
}
|
||||
|
@ -511,4 +539,35 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
Log::sMinDebugLevel = level;
|
||||
}
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, Unload)
|
||||
{
|
||||
LuaUtil::ScriptTracker tracker;
|
||||
LuaUtil::ScriptsContainer scripts1(&mLua, "Test", &tracker, false);
|
||||
|
||||
EXPECT_TRUE(scripts1.addCustomScript(*mCfg.findId(unloadPath)));
|
||||
EXPECT_EQ(tracker.size(), 1);
|
||||
|
||||
mLua.protectedCall([&](LuaUtil::LuaView& lua) {
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(lua.sol().create_table_with("x", 3, "y", 2, "z", 1)));
|
||||
testing::internal::CaptureStdout();
|
||||
for (int i = 0; i < 600; ++i)
|
||||
tracker.unloadInactiveScripts(lua);
|
||||
EXPECT_EQ(tracker.size(), 0);
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(lua.sol().create_table_with("x", 10, "y", 20, "z", 30)));
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[unload.lua]:\tsaving\t3\t2\t1\n"
|
||||
"Test[unload.lua]:\tloaded\t3\t2\t0\n");
|
||||
});
|
||||
EXPECT_EQ(tracker.size(), 1);
|
||||
ESM::LuaScripts data;
|
||||
scripts1.save(data);
|
||||
EXPECT_EQ(tracker.size(), 1);
|
||||
mLua.protectedCall([&](LuaUtil::LuaView& lua) {
|
||||
for (int i = 0; i < 600; ++i)
|
||||
tracker.unloadInactiveScripts(lua);
|
||||
});
|
||||
EXPECT_EQ(tracker.size(), 0);
|
||||
scripts1.load(data);
|
||||
EXPECT_EQ(tracker.size(), 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,8 +224,8 @@ namespace MWLua
|
|||
};
|
||||
}
|
||||
|
||||
LocalScripts::LocalScripts(LuaUtil::LuaState* lua, const LObject& obj)
|
||||
: LuaUtil::ScriptsContainer(lua, "L" + obj.id().toString())
|
||||
LocalScripts::LocalScripts(LuaUtil::LuaState* lua, const LObject& obj, LuaUtil::ScriptTracker* tracker)
|
||||
: LuaUtil::ScriptsContainer(lua, "L" + obj.id().toString(), tracker, false)
|
||||
, mData(obj)
|
||||
{
|
||||
lua->protectedCall(
|
||||
|
|
|
@ -62,12 +62,13 @@ namespace MWLua
|
|||
{
|
||||
public:
|
||||
static void initializeSelfPackage(const Context&);
|
||||
LocalScripts(LuaUtil::LuaState* lua, const LObject& obj);
|
||||
LocalScripts(LuaUtil::LuaState* lua, const LObject& obj, LuaUtil::ScriptTracker* tracker = nullptr);
|
||||
|
||||
MWBase::LuaManager::ActorControls* getActorControls() { return &mData.mControls; }
|
||||
const MWWorld::Ptr& getPtrOrEmpty() const { return mData.ptrOrEmpty(); }
|
||||
|
||||
void setActive(bool active);
|
||||
bool isActive() const override { return mData.mIsActive; }
|
||||
void onConsume(const LObject& consumable) { callEngineHandlers(mOnConsumeHandlers, consumable); }
|
||||
void onActivated(const LObject& actor) { callEngineHandlers(mOnActivatedHandlers, actor); }
|
||||
void onTeleported() { callEngineHandlers(mOnTeleportedHandlers); }
|
||||
|
|
|
@ -210,6 +210,8 @@ namespace MWLua
|
|||
scripts->update(frameDuration);
|
||||
mGlobalScripts.update(frameDuration);
|
||||
}
|
||||
|
||||
mLua.protectedCall([&](LuaUtil::LuaView& lua) { mScriptTracker.unloadInactiveScripts(lua); });
|
||||
}
|
||||
|
||||
void LuaManager::objectTeleported(const MWWorld::Ptr& ptr)
|
||||
|
@ -560,7 +562,7 @@ namespace MWLua
|
|||
}
|
||||
else
|
||||
{
|
||||
scripts = std::make_shared<LocalScripts>(&mLua, LObject(getId(ptr)));
|
||||
scripts = std::make_shared<LocalScripts>(&mLua, LObject(getId(ptr)), &mScriptTracker);
|
||||
if (!autoStartConf.has_value())
|
||||
autoStartConf = mConfiguration.getLocalConf(type, ptr.getCellRef().getRefId(), getId(ptr));
|
||||
scripts->setAutoStartConf(std::move(*autoStartConf));
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <components/lua/inputactions.hpp>
|
||||
#include <components/lua/luastate.hpp>
|
||||
#include <components/lua/scripttracker.hpp>
|
||||
#include <components/lua/storage.hpp>
|
||||
#include <components/lua_ui/resources.hpp>
|
||||
#include <components/misc/color.hpp>
|
||||
|
@ -234,6 +235,8 @@ namespace MWLua
|
|||
|
||||
LuaUtil::InputAction::Registry mInputActions;
|
||||
LuaUtil::InputTrigger::Registry mInputTriggers;
|
||||
|
||||
LuaUtil::ScriptTracker mScriptTracker;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue