mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 17:15:34 +00:00
Store Lua script path as VFS normalized
This commit is contained in:
parent
96ec3a8125
commit
b4f77e8bd7
14 changed files with 203 additions and 123 deletions
|
@ -9,8 +9,9 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
constexpr VFS::Path::NormalizedView techniquePropertiesPath("shaders/technique_properties.omwfx");
|
||||
|
||||
TestingOpenMW::VFSTestFile technique_properties(R"(
|
||||
TestingOpenMW::VFSTestFile techniqueProperties(R"(
|
||||
fragment main {}
|
||||
vertex main {}
|
||||
technique {
|
||||
|
@ -26,7 +27,9 @@ namespace
|
|||
}
|
||||
)");
|
||||
|
||||
TestingOpenMW::VFSTestFile rendertarget_properties{ R"(
|
||||
constexpr VFS::Path::NormalizedView rendertargetPropertiesPath("shaders/rendertarget_properties.omwfx");
|
||||
|
||||
TestingOpenMW::VFSTestFile rendertargetProperties{ R"(
|
||||
render_target rendertarget {
|
||||
width_ratio = 0.5;
|
||||
height_ratio = 0.5;
|
||||
|
@ -52,7 +55,9 @@ namespace
|
|||
technique { passes = downsample2x, main; }
|
||||
)" };
|
||||
|
||||
TestingOpenMW::VFSTestFile uniform_properties{ R"(
|
||||
constexpr VFS::Path::NormalizedView uniformPropertiesPath("shaders/uniform_properties.omwfx");
|
||||
|
||||
TestingOpenMW::VFSTestFile uniformProperties{ R"(
|
||||
uniform_vec4 uVec4 {
|
||||
default = vec4(0,0,0,0);
|
||||
min = vec4(0,1,0,0);
|
||||
|
@ -66,13 +71,17 @@ namespace
|
|||
technique { passes = main; }
|
||||
)" };
|
||||
|
||||
TestingOpenMW::VFSTestFile missing_sampler_source{ R"(
|
||||
constexpr VFS::Path::NormalizedView missingSamplerSourcePath("shaders/missing_sampler_source.omwfx");
|
||||
|
||||
TestingOpenMW::VFSTestFile missingSamplerSource{ R"(
|
||||
sampler_1d mysampler1d { }
|
||||
fragment main { }
|
||||
technique { passes = main; }
|
||||
)" };
|
||||
|
||||
TestingOpenMW::VFSTestFile repeated_shared_block{ R"(
|
||||
constexpr VFS::Path::NormalizedView repeatedSharedBlockPath("shaders/repeated_shared_block.omwfx");
|
||||
|
||||
TestingOpenMW::VFSTestFile repeatedSharedBlock{ R"(
|
||||
shared {
|
||||
float myfloat = 1.0;
|
||||
}
|
||||
|
@ -92,11 +101,11 @@ namespace
|
|||
|
||||
TechniqueTest()
|
||||
: mVFS(TestingOpenMW::createTestVFS({
|
||||
{ "shaders/technique_properties.omwfx", &technique_properties },
|
||||
{ "shaders/rendertarget_properties.omwfx", &rendertarget_properties },
|
||||
{ "shaders/uniform_properties.omwfx", &uniform_properties },
|
||||
{ "shaders/missing_sampler_source.omwfx", &missing_sampler_source },
|
||||
{ "shaders/repeated_shared_block.omwfx", &repeated_shared_block },
|
||||
{ techniquePropertiesPath, &techniqueProperties },
|
||||
{ rendertargetPropertiesPath, &rendertargetProperties },
|
||||
{ uniformPropertiesPath, &uniformProperties },
|
||||
{ missingSamplerSourcePath, &missingSamplerSource },
|
||||
{ repeatedSharedBlockPath, &repeatedSharedBlock },
|
||||
}))
|
||||
, mImageManager(mVFS.get(), 0)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace
|
|||
EXPECT_EQ(LuaUtil::scriptCfgToString(cfg.mScripts[1]), "PLAYER : my_mod/player.lua");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(cfg.mScripts[2]), "CUSTOM : my_mod/some_other_script.lua");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(cfg.mScripts[3]), "PLAYER NPC CREATURE : my_mod/some_other_script.lua");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(cfg.mScripts[4]), ": my_mod/player.LUA");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(cfg.mScripts[4]), ": my_mod/player.lua");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(cfg.mScripts[5]), "CUSTOM CREATURE : my_mod/creature.lua");
|
||||
|
||||
LuaUtil::ScriptsConfiguration conf;
|
||||
|
@ -54,7 +54,7 @@ namespace
|
|||
// cfg.mScripts[1] is overridden by cfg.mScripts[4]
|
||||
// cfg.mScripts[2] is overridden by cfg.mScripts[3]
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[1]), "PLAYER NPC CREATURE : my_mod/some_other_script.lua");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[2]), ": my_mod/player.LUA");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[2]), ": my_mod/player.lua");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[3]), "CUSTOM CREATURE : my_mod/creature.lua");
|
||||
|
||||
EXPECT_THAT(asVector(conf.getGlobalConf()), ElementsAre(Pair(0, "")));
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
{
|
||||
ESM::LuaScriptsCfg cfg;
|
||||
ESM::LuaScriptCfg& script1 = cfg.mScripts.emplace_back();
|
||||
script1.mScriptPath = "Script1.lua";
|
||||
script1.mScriptPath = VFS::Path::Normalized("Script1.lua");
|
||||
script1.mInitializationData = "data1";
|
||||
script1.mFlags = ESM::LuaScriptCfg::sPlayer;
|
||||
script1.mTypes.push_back(ESM::REC_CREA);
|
||||
|
@ -98,12 +98,12 @@ namespace
|
|||
script1.mRefs.push_back({ true, 2, 4, "" });
|
||||
|
||||
ESM::LuaScriptCfg& script2 = cfg.mScripts.emplace_back();
|
||||
script2.mScriptPath = "Script2.lua";
|
||||
script2.mScriptPath = VFS::Path::Normalized("Script2.lua");
|
||||
script2.mFlags = ESM::LuaScriptCfg::sCustom;
|
||||
script2.mTypes.push_back(ESM::REC_CONT);
|
||||
|
||||
ESM::LuaScriptCfg& script1Extra = cfg.mScripts.emplace_back();
|
||||
script1Extra.mScriptPath = "script1.LUA";
|
||||
script1Extra.mScriptPath = VFS::Path::Normalized("script1.LUA");
|
||||
script1Extra.mFlags = ESM::LuaScriptCfg::sCustom | ESM::LuaScriptCfg::sMerge;
|
||||
script1Extra.mTypes.push_back(ESM::REC_NPC_);
|
||||
script1Extra.mRecords.push_back({ false, ESM::RefId::stringRefId("rat"), "" });
|
||||
|
@ -115,8 +115,8 @@ namespace
|
|||
conf.init(cfg);
|
||||
ASSERT_EQ(conf.size(), 2);
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[0]),
|
||||
"CUSTOM PLAYER CREATURE NPC : Script1.lua ; data 5 bytes ; 3 records ; 4 objects");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[1]), "CUSTOM CONTAINER : Script2.lua");
|
||||
"CUSTOM PLAYER CREATURE NPC : script1.lua ; data 5 bytes ; 3 records ; 4 objects");
|
||||
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[1]), "CUSTOM CONTAINER : script2.lua");
|
||||
|
||||
EXPECT_THAT(asVector(conf.getPlayerConf()), ElementsAre(Pair(0, "data1")));
|
||||
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, ESM::RefId::stringRefId("something"), ESM::RefNum())),
|
||||
|
@ -139,7 +139,7 @@ namespace
|
|||
ElementsAre(Pair(0, "data1"), Pair(1, "")));
|
||||
|
||||
ESM::LuaScriptCfg& script3 = cfg.mScripts.emplace_back();
|
||||
script3.mScriptPath = "script1.lua";
|
||||
script3.mScriptPath = VFS::Path::Normalized("script1.lua");
|
||||
script3.mFlags = ESM::LuaScriptCfg::sGlobal;
|
||||
EXPECT_ERROR(conf.init(cfg), "Flags mismatch for script1.lua");
|
||||
}
|
||||
|
@ -168,13 +168,13 @@ namespace
|
|||
}
|
||||
{
|
||||
ESM::LuaScriptCfg& script = cfg.mScripts.emplace_back();
|
||||
script.mScriptPath = "test_global.lua";
|
||||
script.mScriptPath = VFS::Path::Normalized("test_global.lua");
|
||||
script.mFlags = ESM::LuaScriptCfg::sGlobal;
|
||||
script.mInitializationData = luaData;
|
||||
}
|
||||
{
|
||||
ESM::LuaScriptCfg& script = cfg.mScripts.emplace_back();
|
||||
script.mScriptPath = "test_local.lua";
|
||||
script.mScriptPath = VFS::Path::Normalized("test_local.lua");
|
||||
script.mFlags = ESM::LuaScriptCfg::sMerge;
|
||||
script.mTypes.push_back(ESM::REC_DOOR);
|
||||
script.mTypes.push_back(ESM::REC_MISC);
|
||||
|
|
|
@ -18,6 +18,13 @@ namespace
|
|||
return lua.safe_script("return " + luaCode).get<T>();
|
||||
}
|
||||
|
||||
constexpr VFS::Path::NormalizedView test1EnPath("l10n/test1/en.yaml");
|
||||
constexpr VFS::Path::NormalizedView test1EnUsPath("l10n/test1/en_us.yaml");
|
||||
constexpr VFS::Path::NormalizedView test1DePath("l10n/test1/de.yaml");
|
||||
constexpr VFS::Path::NormalizedView test2EnPath("l10n/test2/en.yaml");
|
||||
constexpr VFS::Path::NormalizedView test3EnPath("l10n/test3/en.yaml");
|
||||
constexpr VFS::Path::NormalizedView test3DePath("l10n/test3/de.yaml");
|
||||
|
||||
VFSTestFile invalidScript("not a script");
|
||||
VFSTestFile incorrectScript(
|
||||
"return { incorrectSection = {}, engineHandlers = { incorrectHandler = function() end } }");
|
||||
|
@ -67,12 +74,12 @@ you_have_arrows: "Arrows count: {count}"
|
|||
struct LuaL10nTest : Test
|
||||
{
|
||||
std::unique_ptr<VFS::Manager> mVFS = createTestVFS({
|
||||
{ "l10n/Test1/en.yaml", &test1En },
|
||||
{ "l10n/Test1/en_US.yaml", &test1EnUS },
|
||||
{ "l10n/Test1/de.yaml", &test1De },
|
||||
{ "l10n/Test2/en.yaml", &test2En },
|
||||
{ "l10n/Test3/en.yaml", &test1En },
|
||||
{ "l10n/Test3/de.yaml", &test1De },
|
||||
{ test1EnPath, &test1En },
|
||||
{ test1EnUsPath, &test1EnUS },
|
||||
{ test1DePath, &test1De },
|
||||
{ test2EnPath, &test2En },
|
||||
{ test3EnPath, &test1En },
|
||||
{ test3DePath, &test1De },
|
||||
});
|
||||
|
||||
LuaUtil::ScriptsConfiguration mCfg;
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace
|
|||
{
|
||||
using namespace testing;
|
||||
|
||||
constexpr VFS::Path::NormalizedView counterPath("aaa/counter.lua");
|
||||
|
||||
TestingOpenMW::VFSTestFile counterFile(R"X(
|
||||
x = 42
|
||||
return {
|
||||
|
@ -17,8 +19,12 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView invalidPath("invalid.lua");
|
||||
|
||||
TestingOpenMW::VFSTestFile invalidScriptFile("Invalid script");
|
||||
|
||||
constexpr VFS::Path::NormalizedView testsPath("bbb/tests.lua");
|
||||
|
||||
TestingOpenMW::VFSTestFile testsFile(R"X(
|
||||
return {
|
||||
-- should work
|
||||
|
@ -51,6 +57,8 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView metaIndexErrorPath("metaindexerror.lua");
|
||||
|
||||
TestingOpenMW::VFSTestFile metaIndexErrorFile(
|
||||
"return setmetatable({}, { __index = function(t, key) error('meta index error') end })");
|
||||
|
||||
|
@ -66,14 +74,24 @@ return {
|
|||
return buf.str();
|
||||
}
|
||||
|
||||
constexpr VFS::Path::NormalizedView bigPath("big.lua");
|
||||
|
||||
TestingOpenMW::VFSTestFile bigScriptFile(genBigScript());
|
||||
|
||||
constexpr VFS::Path::NormalizedView requireBigPath("requirebig.lua");
|
||||
|
||||
TestingOpenMW::VFSTestFile requireBigScriptFile("local x = require('big') ; return {x}");
|
||||
|
||||
struct LuaStateTest : Test
|
||||
{
|
||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({ { "aaa/counter.lua", &counterFile },
|
||||
{ "bbb/tests.lua", &testsFile }, { "invalid.lua", &invalidScriptFile }, { "big.lua", &bigScriptFile },
|
||||
{ "requireBig.lua", &requireBigScriptFile }, { "metaIndexError.lua", &metaIndexErrorFile } });
|
||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({
|
||||
{ counterPath, &counterFile },
|
||||
{ testsPath, &testsFile },
|
||||
{ invalidPath, &invalidScriptFile },
|
||||
{ bigPath, &bigScriptFile },
|
||||
{ requireBigPath, &requireBigScriptFile },
|
||||
{ metaIndexErrorPath, &metaIndexErrorFile },
|
||||
});
|
||||
|
||||
LuaUtil::ScriptsConfiguration mCfg;
|
||||
LuaUtil::LuaState mLua{ mVFS.get(), &mCfg };
|
||||
|
@ -81,7 +99,7 @@ return {
|
|||
|
||||
TEST_F(LuaStateTest, Sandbox)
|
||||
{
|
||||
const VFS::Path::Normalized path("aaa/counter.lua");
|
||||
const VFS::Path::Normalized path(counterPath);
|
||||
sol::table script1 = mLua.runInNewSandbox(path);
|
||||
|
||||
EXPECT_EQ(LuaUtil::call(script1["get"]).get<int>(), 42);
|
||||
|
|
|
@ -14,11 +14,22 @@ namespace
|
|||
using namespace testing;
|
||||
using namespace TestingOpenMW;
|
||||
|
||||
constexpr VFS::Path::NormalizedView invalidPath("invalid.lua");
|
||||
|
||||
VFSTestFile invalidScript("not a script");
|
||||
|
||||
constexpr VFS::Path::NormalizedView incorrectPath("incorrect.lua");
|
||||
|
||||
VFSTestFile incorrectScript(
|
||||
"return { incorrectSection = {}, engineHandlers = { incorrectHandler = function() end } }");
|
||||
|
||||
constexpr VFS::Path::NormalizedView emptyPath("empty.lua");
|
||||
|
||||
VFSTestFile emptyScript("");
|
||||
|
||||
constexpr VFS::Path::NormalizedView test1Path("test1.lua");
|
||||
constexpr VFS::Path::NormalizedView test2Path("test2.lua");
|
||||
|
||||
VFSTestFile testScript(R"X(
|
||||
return {
|
||||
engineHandlers = {
|
||||
|
@ -33,6 +44,8 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView stopEventPath("stopevent.lua");
|
||||
|
||||
VFSTestFile stopEventScript(R"X(
|
||||
return {
|
||||
eventHandlers = {
|
||||
|
@ -44,6 +57,9 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView loadSave1Path("loadsave1.lua");
|
||||
constexpr VFS::Path::NormalizedView loadSave2Path("loadsave2.lua");
|
||||
|
||||
VFSTestFile loadSaveScript(R"X(
|
||||
x = 0
|
||||
y = 0
|
||||
|
@ -70,6 +86,8 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView testInterfacePath("testinterface.lua");
|
||||
|
||||
VFSTestFile interfaceScript(R"X(
|
||||
return {
|
||||
interfaceName = "TestInterface",
|
||||
|
@ -80,6 +98,8 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView overrideInterfacePath("overrideinterface.lua");
|
||||
|
||||
VFSTestFile overrideInterfaceScript(R"X(
|
||||
local old = nil
|
||||
local interface = {
|
||||
|
@ -104,6 +124,8 @@ return {
|
|||
}
|
||||
)X");
|
||||
|
||||
constexpr VFS::Path::NormalizedView useInterfacePath("useinterface.lua");
|
||||
|
||||
VFSTestFile useInterfaceScript(R"X(
|
||||
local interfaces = require('openmw.interfaces')
|
||||
return {
|
||||
|
@ -118,17 +140,17 @@ return {
|
|||
struct LuaScriptsContainerTest : Test
|
||||
{
|
||||
std::unique_ptr<VFS::Manager> mVFS = createTestVFS({
|
||||
{ "invalid.lua", &invalidScript },
|
||||
{ "incorrect.lua", &incorrectScript },
|
||||
{ "empty.lua", &emptyScript },
|
||||
{ "test1.lua", &testScript },
|
||||
{ "test2.lua", &testScript },
|
||||
{ "stopEvent.lua", &stopEventScript },
|
||||
{ "loadSave1.lua", &loadSaveScript },
|
||||
{ "loadSave2.lua", &loadSaveScript },
|
||||
{ "testInterface.lua", &interfaceScript },
|
||||
{ "overrideInterface.lua", &overrideInterfaceScript },
|
||||
{ "useInterface.lua", &useInterfaceScript },
|
||||
{ invalidPath, &invalidScript },
|
||||
{ incorrectPath, &incorrectScript },
|
||||
{ emptyPath, &emptyScript },
|
||||
{ test1Path, &testScript },
|
||||
{ test2Path, &testScript },
|
||||
{ stopEventPath, &stopEventScript },
|
||||
{ loadSave1Path, &loadSaveScript },
|
||||
{ loadSave2Path, &loadSaveScript },
|
||||
{ testInterfacePath, &interfaceScript },
|
||||
{ overrideInterfacePath, &overrideInterfaceScript },
|
||||
{ useInterfacePath, &useInterfaceScript },
|
||||
});
|
||||
|
||||
LuaUtil::ScriptsConfiguration mCfg;
|
||||
|
@ -152,39 +174,49 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
)X");
|
||||
mCfg.init(std::move(cfg));
|
||||
}
|
||||
|
||||
int getId(VFS::Path::NormalizedView path) const
|
||||
{
|
||||
const std::optional<int> id = mCfg.findId(path);
|
||||
if (!id.has_value())
|
||||
throw std::invalid_argument("Script id is not found: " + std::string(path.value()));
|
||||
return *id;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, VerifyStructure)
|
||||
TEST_F(LuaScriptsContainerTest, addCustomScriptShouldNotStartInvalidScript)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_FALSE(scripts.addCustomScript(*mCfg.findId("invalid.lua")));
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("Can't start Test[invalid.lua]"));
|
||||
}
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("incorrect.lua")));
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("Not supported handler 'incorrectHandler' in Test[incorrect.lua]"));
|
||||
EXPECT_THAT(output, HasSubstr("Not supported section 'incorrectSection' in Test[incorrect.lua]"));
|
||||
}
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("empty.lua")));
|
||||
EXPECT_FALSE(scripts.addCustomScript(*mCfg.findId("empty.lua"))); // already present
|
||||
EXPECT_EQ(internal::GetCapturedStdout(), "");
|
||||
}
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_FALSE(scripts.addCustomScript(getId(invalidPath)));
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("Can't start Test[invalid.lua]"));
|
||||
}
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, addCustomScriptShouldNotSuportScriptsWithInvalidHandlerAndSection)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(incorrectPath)));
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_THAT(output, HasSubstr("Not supported handler 'incorrectHandler' in Test[incorrect.lua]"));
|
||||
EXPECT_THAT(output, HasSubstr("Not supported section 'incorrectSection' in Test[incorrect.lua]"));
|
||||
}
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, addCustomScriptShouldReturnFalseForDuplicates)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(emptyPath)));
|
||||
EXPECT_FALSE(scripts.addCustomScript(getId(emptyPath)));
|
||||
}
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, CallHandler)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test1.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("stopEvent.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test2.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(test1Path)));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(stopEventPath)));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
||||
scripts.update(1.5f);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[test1.lua]:\t update 1.5\n"
|
||||
|
@ -194,9 +226,10 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
TEST_F(LuaScriptsContainerTest, CallEvent)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test1.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("stopEvent.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test2.lua")));
|
||||
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(test1Path)));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(stopEventPath)));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
||||
|
||||
sol::state_view sol = mLua.unsafeState();
|
||||
std::string X0 = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
||||
|
@ -212,7 +245,7 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
scripts.receiveEvent("Event1", X1);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[test2.lua]:\t event1 1.5\n"
|
||||
"Test[stopEvent.lua]:\t event1 1.5\n"
|
||||
"Test[stopevent.lua]:\t event1 1.5\n"
|
||||
"Test[test1.lua]:\t event1 1.5\n");
|
||||
}
|
||||
{
|
||||
|
@ -227,7 +260,7 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
scripts.receiveEvent("Event1", X0);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[test2.lua]:\t event1 0.5\n"
|
||||
"Test[stopEvent.lua]:\t event1 0.5\n");
|
||||
"Test[stopevent.lua]:\t event1 0.5\n");
|
||||
}
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
|
@ -241,9 +274,11 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
TEST_F(LuaScriptsContainerTest, RemoveScript)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test1.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("stopEvent.lua")));
|
||||
EXPECT_TRUE(scripts.addCustomScript(*mCfg.findId("test2.lua")));
|
||||
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(test1Path)));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(stopEventPath)));
|
||||
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
||||
|
||||
sol::state_view sol = mLua.unsafeState();
|
||||
std::string X = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
||||
|
||||
|
@ -255,11 +290,11 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
"Test[test1.lua]:\t update 1.5\n"
|
||||
"Test[test2.lua]:\t update 1.5\n"
|
||||
"Test[test2.lua]:\t event1 0.5\n"
|
||||
"Test[stopEvent.lua]:\t event1 0.5\n");
|
||||
"Test[stopevent.lua]:\t event1 0.5\n");
|
||||
}
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
int stopEventScriptId = *mCfg.findId("stopEvent.lua");
|
||||
const int stopEventScriptId = getId(stopEventPath);
|
||||
EXPECT_TRUE(scripts.hasScript(stopEventScriptId));
|
||||
scripts.removeScript(stopEventScriptId);
|
||||
EXPECT_FALSE(scripts.hasScript(stopEventScriptId));
|
||||
|
@ -273,7 +308,7 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
}
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
scripts.removeScript(*mCfg.findId("test1.lua"));
|
||||
scripts.removeScript(getId(test1Path));
|
||||
scripts.update(1.5f);
|
||||
scripts.receiveEvent("Event1", X);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
|
@ -290,19 +325,19 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
scripts.addAutoStartedScripts();
|
||||
scripts.update(1.5f);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[overrideInterface.lua]:\toverride\n"
|
||||
"Test[overrideInterface.lua]:\tinit\n"
|
||||
"Test[overrideInterface.lua]:\tNEW FN\t4.5\n"
|
||||
"Test[testInterface.lua]:\tFN\t4.5\n");
|
||||
"Test[overrideinterface.lua]:\toverride\n"
|
||||
"Test[overrideinterface.lua]:\tinit\n"
|
||||
"Test[overrideinterface.lua]:\tNEW FN\t4.5\n"
|
||||
"Test[testinterface.lua]:\tFN\t4.5\n");
|
||||
}
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, Interface)
|
||||
{
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
scripts.setAutoStartConf(mCfg.getLocalConf(ESM::REC_CREA, ESM::RefId(), ESM::RefNum()));
|
||||
int addIfaceId = *mCfg.findId("testInterface.lua");
|
||||
int overrideIfaceId = *mCfg.findId("overrideInterface.lua");
|
||||
int useIfaceId = *mCfg.findId("useInterface.lua");
|
||||
const int addIfaceId = getId(testInterfacePath);
|
||||
const int overrideIfaceId = getId(overrideInterfacePath);
|
||||
const int useIfaceId = getId(useInterfacePath);
|
||||
|
||||
testing::internal::CaptureStdout();
|
||||
scripts.addAutoStartedScripts();
|
||||
|
@ -317,11 +352,11 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
scripts.removeScript(overrideIfaceId);
|
||||
scripts.update(1.5f);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[overrideInterface.lua]:\toverride\n"
|
||||
"Test[overrideInterface.lua]:\tinit\n"
|
||||
"Test[overrideInterface.lua]:\tNEW FN\t4.5\n"
|
||||
"Test[testInterface.lua]:\tFN\t4.5\n"
|
||||
"Test[testInterface.lua]:\tFN\t3.5\n");
|
||||
"Test[overrideinterface.lua]:\toverride\n"
|
||||
"Test[overrideinterface.lua]:\tinit\n"
|
||||
"Test[overrideinterface.lua]:\tNEW FN\t4.5\n"
|
||||
"Test[testinterface.lua]:\tFN\t4.5\n"
|
||||
"Test[testinterface.lua]:\tFN\t3.5\n");
|
||||
}
|
||||
|
||||
TEST_F(LuaScriptsContainerTest, LoadSave)
|
||||
|
@ -334,7 +369,7 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
scripts3.setAutoStartConf(mCfg.getPlayerConf());
|
||||
|
||||
scripts1.addAutoStartedScripts();
|
||||
EXPECT_TRUE(scripts1.addCustomScript(*mCfg.findId("test1.lua")));
|
||||
EXPECT_TRUE(scripts1.addCustomScript(getId(test1Path)));
|
||||
|
||||
sol::state_view sol = mLua.unsafeState();
|
||||
scripts1.receiveEvent("Set", LuaUtil::serialize(sol.create_table_with("n", 1, "x", 0.5, "y", 3.5)));
|
||||
|
@ -349,23 +384,23 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
scripts2.receiveEvent("Print", "");
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Test[test1.lua]:\tload\n"
|
||||
"Test[loadSave2.lua]:\t0.5\t3.5\n"
|
||||
"Test[loadSave1.lua]:\t2.5\t1.5\n"
|
||||
"Test[loadsave2.lua]:\t0.5\t3.5\n"
|
||||
"Test[loadsave1.lua]:\t2.5\t1.5\n"
|
||||
"Test[test1.lua]:\tprint\n");
|
||||
EXPECT_FALSE(scripts2.hasScript(*mCfg.findId("testInterface.lua")));
|
||||
EXPECT_FALSE(scripts2.hasScript(getId(testInterfacePath)));
|
||||
}
|
||||
{
|
||||
testing::internal::CaptureStdout();
|
||||
scripts3.load(data);
|
||||
scripts3.receiveEvent("Print", "");
|
||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||
"Ignoring Test[loadSave1.lua]; this script is not allowed here\n"
|
||||
"Ignoring Test[loadsave1.lua]; this script is not allowed here\n"
|
||||
"Test[test1.lua]:\tload\n"
|
||||
"Test[overrideInterface.lua]:\toverride\n"
|
||||
"Test[overrideInterface.lua]:\tinit\n"
|
||||
"Test[loadSave2.lua]:\t0.5\t3.5\n"
|
||||
"Test[overrideinterface.lua]:\toverride\n"
|
||||
"Test[overrideinterface.lua]:\tinit\n"
|
||||
"Test[loadsave2.lua]:\t0.5\t3.5\n"
|
||||
"Test[test1.lua]:\tprint\n");
|
||||
EXPECT_TRUE(scripts3.hasScript(*mCfg.findId("testInterface.lua")));
|
||||
EXPECT_TRUE(scripts3.hasScript(getId(testInterfacePath)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,8 +408,8 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
{
|
||||
using TimerType = LuaUtil::ScriptsContainer::TimerType;
|
||||
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
|
||||
int test1Id = *mCfg.findId("test1.lua");
|
||||
int test2Id = *mCfg.findId("test2.lua");
|
||||
const int test1Id = getId(test1Path);
|
||||
const int test2Id = getId(test2Path);
|
||||
|
||||
testing::internal::CaptureStdout();
|
||||
EXPECT_TRUE(scripts.addCustomScript(test1Id));
|
||||
|
|
|
@ -8,16 +8,17 @@ namespace
|
|||
using namespace Misc::ResourceHelpers;
|
||||
TEST(CorrectSoundPath, wav_files_not_overridden_with_mp3_in_vfs_are_not_corrected)
|
||||
{
|
||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({ { "sound/bar.wav", nullptr } });
|
||||
constexpr VFS::Path::NormalizedView path("sound/bar.wav");
|
||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({ { path, nullptr } });
|
||||
EXPECT_EQ(correctSoundPath(path, *mVFS), "sound/bar.wav");
|
||||
}
|
||||
|
||||
TEST(CorrectSoundPath, wav_files_overridden_with_mp3_in_vfs_are_corrected)
|
||||
{
|
||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({ { "sound/foo.mp3", nullptr } });
|
||||
constexpr VFS::Path::NormalizedView path("sound/foo.wav");
|
||||
EXPECT_EQ(correctSoundPath(path, *mVFS), "sound/foo.mp3");
|
||||
constexpr VFS::Path::NormalizedView mp3("sound/foo.mp3");
|
||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({ { mp3, nullptr } });
|
||||
constexpr VFS::Path::NormalizedView wav("sound/foo.wav");
|
||||
EXPECT_EQ(correctSoundPath(wav, *mVFS), "sound/foo.mp3");
|
||||
}
|
||||
|
||||
TEST(CorrectSoundPath, corrected_path_does_not_check_existence_in_vfs)
|
||||
|
|
|
@ -850,8 +850,8 @@ namespace MWLua
|
|||
bool isMenu = mConfiguration[i].mFlags & ESM::LuaScriptCfg::sMenu;
|
||||
|
||||
out << std::left;
|
||||
out << " " << std::setw(nameW) << mConfiguration[i].mScriptPath;
|
||||
if (mConfiguration[i].mScriptPath.size() > nameW)
|
||||
out << " " << std::setw(nameW) << mConfiguration[i].mScriptPath.value();
|
||||
if (mConfiguration[i].mScriptPath.value().size() > nameW)
|
||||
out << "\n " << std::setw(nameW) << ""; // if path is too long, break line
|
||||
out << std::right;
|
||||
out << std::setw(valueW) << static_cast<int64_t>(activeStats[i].mAvgInstructionCount);
|
||||
|
|
|
@ -390,7 +390,7 @@ namespace MWLua
|
|||
};
|
||||
objectT["addScript"] = [context](const GObject& object, std::string_view path, sol::object initData) {
|
||||
const LuaUtil::ScriptsConfiguration& cfg = context.mLua->getConfiguration();
|
||||
std::optional<int> scriptId = cfg.findId(path);
|
||||
std::optional<int> scriptId = cfg.findId(VFS::Path::Normalized(path));
|
||||
if (!scriptId)
|
||||
throw std::runtime_error("Unknown script: " + std::string(path));
|
||||
if (!(cfg[*scriptId].mFlags & ESM::LuaScriptCfg::sCustom))
|
||||
|
@ -407,7 +407,7 @@ namespace MWLua
|
|||
};
|
||||
objectT["hasScript"] = [lua = context.mLua](const GObject& object, std::string_view path) {
|
||||
const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration();
|
||||
std::optional<int> scriptId = cfg.findId(path);
|
||||
std::optional<int> scriptId = cfg.findId(VFS::Path::Normalized(path));
|
||||
if (!scriptId)
|
||||
return false;
|
||||
MWWorld::Ptr ptr = object.ptr();
|
||||
|
@ -419,7 +419,7 @@ namespace MWLua
|
|||
};
|
||||
objectT["removeScript"] = [lua = context.mLua](const GObject& object, std::string_view path) {
|
||||
const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration();
|
||||
std::optional<int> scriptId = cfg.findId(path);
|
||||
std::optional<int> scriptId = cfg.findId(VFS::Path::Normalized(path));
|
||||
if (!scriptId)
|
||||
throw std::runtime_error("Unknown script: " + std::string(path));
|
||||
MWWorld::Ptr ptr = object.ptr();
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define OPENMW_ESM_LUASCRIPTS_H
|
||||
|
||||
#include <components/esm/refid.hpp>
|
||||
#include <components/vfs/pathutil.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -25,7 +27,7 @@ namespace ESM
|
|||
|
||||
static constexpr Flags sMenu = 1ull << 4; // start as a menu script
|
||||
|
||||
std::string mScriptPath; // VFS path to the script.
|
||||
VFS::Path::Normalized mScriptPath;
|
||||
std::string mInitializationData; // Serialized Lua table. It is a binary data. Can contain '\0'.
|
||||
Flags mFlags; // bitwise OR of Flags.
|
||||
|
||||
|
@ -85,7 +87,7 @@ namespace ESM
|
|||
|
||||
struct LuaScript
|
||||
{
|
||||
std::string mScriptPath;
|
||||
VFS::Path::Normalized mScriptPath;
|
||||
std::string mData; // Serialized Lua table. It is a binary data. Can contain '\0'.
|
||||
std::vector<LuaTimer> mTimers;
|
||||
};
|
||||
|
|
|
@ -60,16 +60,17 @@ namespace LuaUtil
|
|||
const ESM::LuaScriptCfg& script = cfg.mScripts[i];
|
||||
bool global = script.mFlags & ESM::LuaScriptCfg::sGlobal;
|
||||
if (global && (script.mFlags & ~ESM::LuaScriptCfg::sMerge) != ESM::LuaScriptCfg::sGlobal)
|
||||
throw std::runtime_error(std::string("Global script can not have local flags: ") + script.mScriptPath);
|
||||
throw std::runtime_error(
|
||||
std::string("Global script can not have local flags: ") + script.mScriptPath.value());
|
||||
if (global && (!script.mTypes.empty() || !script.mRecords.empty() || !script.mRefs.empty()))
|
||||
throw std::runtime_error(std::string("Global script can not have per-type and per-object configuration")
|
||||
+ script.mScriptPath);
|
||||
auto [it, inserted] = mPathToIndex.emplace(Misc::StringUtils::lowerCase(script.mScriptPath), i);
|
||||
+ script.mScriptPath.value());
|
||||
auto [it, inserted] = mPathToIndex.emplace(script.mScriptPath, i);
|
||||
if (inserted)
|
||||
continue;
|
||||
ESM::LuaScriptCfg& oldScript = cfg.mScripts[it->second];
|
||||
if (global != bool(oldScript.mFlags & ESM::LuaScriptCfg::sGlobal))
|
||||
throw std::runtime_error(std::string("Flags mismatch for ") + script.mScriptPath);
|
||||
throw std::runtime_error(std::string("Flags mismatch for ") + script.mScriptPath.value());
|
||||
if (script.mFlags & ESM::LuaScriptCfg::sMerge)
|
||||
{
|
||||
oldScript.mFlags |= (script.mFlags & ~ESM::LuaScriptCfg::sMerge);
|
||||
|
@ -113,7 +114,7 @@ namespace LuaUtil
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<int> ScriptsConfiguration::findId(std::string_view path) const
|
||||
std::optional<int> ScriptsConfiguration::findId(VFS::Path::NormalizedView path) const
|
||||
{
|
||||
auto it = mPathToIndex.find(path);
|
||||
if (it != mPathToIndex.end())
|
||||
|
@ -199,7 +200,7 @@ namespace LuaUtil
|
|||
scriptPath = scriptPath.substr(1);
|
||||
|
||||
ESM::LuaScriptCfg& script = cfg.mScripts.emplace_back();
|
||||
script.mScriptPath = std::string(scriptPath);
|
||||
script.mScriptPath = VFS::Path::Normalized(scriptPath);
|
||||
script.mFlags = 0;
|
||||
|
||||
// Parse tags
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
#include "components/esm/luascripts.hpp"
|
||||
#include "components/esm3/cellref.hpp"
|
||||
#include <components/esm/luascripts.hpp>
|
||||
#include <components/esm3/refnum.hpp>
|
||||
#include <components/vfs/pathutil.hpp>
|
||||
|
||||
namespace LuaUtil
|
||||
{
|
||||
|
@ -19,7 +20,8 @@ namespace LuaUtil
|
|||
size_t size() const { return mScripts.size(); }
|
||||
const ESM::LuaScriptCfg& operator[](int id) const { return mScripts[id]; }
|
||||
|
||||
std::optional<int> findId(std::string_view path) const;
|
||||
std::optional<int> findId(VFS::Path::NormalizedView path) const;
|
||||
|
||||
bool isCustomScript(int id) const { return mScripts[id].mFlags & ESM::LuaScriptCfg::sCustom; }
|
||||
|
||||
ScriptIdsWithInitializationData getMenuConf() const { return getConfByFlag(ESM::LuaScriptCfg::sMenu); }
|
||||
|
@ -32,7 +34,7 @@ namespace LuaUtil
|
|||
ScriptIdsWithInitializationData getConfByFlag(ESM::LuaScriptCfg::Flags flag) const;
|
||||
|
||||
std::vector<ESM::LuaScriptCfg> mScripts;
|
||||
std::map<std::string, int, std::less<>> mPathToIndex;
|
||||
std::map<VFS::Path::Normalized, int, std::less<>> mPathToIndex;
|
||||
|
||||
struct DetailedConf
|
||||
{
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace LuaUtil
|
|||
if (mScripts.count(scriptId) != 0)
|
||||
return false; // already present
|
||||
|
||||
const std::string& path = scriptPath(scriptId);
|
||||
const VFS::Path::Normalized& path = scriptPath(scriptId);
|
||||
std::string debugName = mNamePrefix;
|
||||
debugName.push_back('[');
|
||||
debugName.append(path);
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace LuaUtil
|
|||
sol::table mHiddenData;
|
||||
std::map<std::string, sol::main_protected_function> mRegisteredCallbacks;
|
||||
std::map<int64_t, sol::main_protected_function> mTemporaryCallbacks;
|
||||
std::string mPath;
|
||||
VFS::Path::Normalized mPath;
|
||||
ScriptStats mStats;
|
||||
};
|
||||
struct Timer
|
||||
|
@ -239,7 +239,12 @@ namespace LuaUtil
|
|||
Script& getScript(int scriptId);
|
||||
|
||||
void printError(int scriptId, std::string_view msg, const std::exception& e);
|
||||
const std::string& scriptPath(int scriptId) const { return mLua.getConfiguration()[scriptId].mScriptPath; }
|
||||
|
||||
const VFS::Path::Normalized& scriptPath(int scriptId) const
|
||||
{
|
||||
return mLua.getConfiguration()[scriptId].mScriptPath;
|
||||
}
|
||||
|
||||
void callOnInit(LuaView& view, int scriptId, const sol::function& onInit, std::string_view data);
|
||||
void callTimer(const Timer& t);
|
||||
void updateTimerQueue(std::vector<Timer>& timerQueue, double time);
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace TestingOpenMW
|
|||
}
|
||||
|
||||
inline std::unique_ptr<VFS::Manager> createTestVFS(
|
||||
std::initializer_list<std::pair<std::string_view, VFS::File*>> files)
|
||||
std::initializer_list<std::pair<VFS::Path::NormalizedView, VFS::File*>> files)
|
||||
{
|
||||
return createTestVFS(VFS::FileMap(files.begin(), files.end()));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue