1
0
forked from mirrors/0ad

Throw error when simulation script can't be loaded

When a script in "simulation/helpers/" contained an error. Files in
"simulation/components" aren't loaded. The return value of
`LoadDefaultScripts` indicated an error but was ignored. The simulation
still tried to start.

Now instead of returning a ignoreable error code the error is thrown. In
the common path the error is implicitly rethrown to the JS-function
which tried to start the game.

fixes: #8133
This commit is contained in:
phosit
2025-11-05 19:38:19 +01:00
parent 977bf5c0d1
commit 9a526bcae1
5 changed files with 44 additions and 29 deletions
+12 -5
View File
@@ -594,11 +594,18 @@ bool Init(const CmdLineArgs& args, int flags)
// on anything else.)
if (args.Has("dumpSchema"))
{
CSimulation2 sim{NULL, *g_ScriptContext, NULL};
sim.LoadDefaultScripts();
std::ofstream f("entity.rng", std::ios_base::out | std::ios_base::trunc);
f << sim.GenerateSchema();
debug_printf("Generated entity.rng\n");
try
{
CSimulation2 sim{NULL, *g_ScriptContext, NULL};
sim.LoadDefaultScripts();
std::ofstream f("entity.rng", std::ios_base::out | std::ios_base::trunc);
f << sim.GenerateSchema();
debug_printf("Generated entity.rng\n");
}
catch (const CSimulation2::LoadScriptError& e)
{
LOGERROR("%s", e.what());
}
return false;
}
+14 -18
View File
@@ -123,8 +123,8 @@ public:
componentManager.AddSystemComponents(skipScriptedComponents, skipAI);
}
static bool LoadDefaultScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts);
static bool LoadScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts, const VfsPath& path);
static void LoadDefaultScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts);
static void LoadScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts, const VfsPath& path);
static bool LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue mapSettings, std::set<VfsPath>* loadedScripts);
Status ReloadChangedFile(const VfsPath& path);
@@ -202,31 +202,27 @@ public:
}
};
bool CSimulation2Impl::LoadDefaultScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts)
void CSimulation2Impl::LoadDefaultScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts)
{
return (
LoadScripts(componentManager, loadedScripts, L"simulation/components/interfaces/") &&
LoadScripts(componentManager, loadedScripts, L"simulation/helpers/") &&
LoadScripts(componentManager, loadedScripts, L"simulation/components/")
);
LoadScripts(componentManager, loadedScripts, L"simulation/components/interfaces/");
LoadScripts(componentManager, loadedScripts, L"simulation/helpers/");
LoadScripts(componentManager, loadedScripts, L"simulation/components/");
}
bool CSimulation2Impl::LoadScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts, const VfsPath& path)
void CSimulation2Impl::LoadScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts, const VfsPath& path)
{
VfsPaths pathnames;
if (vfs::GetPathnames(g_VFS, path, L"*.js", pathnames) < 0)
return false;
throw CSimulation2::LoadScriptError{"Error enumerating " + path.string8()};
bool ok = true;
for (const VfsPath& scriptPath : pathnames)
{
if (loadedScripts)
loadedScripts->insert(scriptPath);
LOGMESSAGE("Loading simulation script '%s'", scriptPath.string8());
if (!componentManager.LoadScript(scriptPath))
ok = false;
throw CSimulation2::LoadScriptError{"Error loading " + scriptPath.string8()};
}
return ok;
}
bool CSimulation2Impl::LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue mapSettings, std::set<VfsPath>* loadedScripts)
@@ -434,7 +430,7 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
m_SecondaryComponentManager->LoadComponentTypes();
m_SecondaryLoadedScripts = std::make_unique<std::set<VfsPath>>();
ENSURE(LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts.get()));
LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts.get());
ResetComponentState(*m_SecondaryComponentManager, false, false);
ScriptRequest rq(scriptInterface);
@@ -771,14 +767,14 @@ float CSimulation2::GetLastFrameOffset() const
return m->m_LastFrameOffset;
}
bool CSimulation2::LoadScripts(const VfsPath& path)
void CSimulation2::LoadScripts(const VfsPath& path)
{
return m->LoadScripts(m->m_ComponentManager, &m->m_LoadedScripts, path);
m->LoadScripts(m->m_ComponentManager, &m->m_LoadedScripts, path);
}
bool CSimulation2::LoadDefaultScripts()
void CSimulation2::LoadDefaultScripts()
{
return m->LoadDefaultScripts(m->m_ComponentManager, &m->m_LoadedScripts);
m->LoadDefaultScripts(m->m_ComponentManager, &m->m_LoadedScripts);
}
void CSimulation2::SetStartupScript(const std::string& code)
+7 -2
View File
@@ -54,6 +54,11 @@ class CSimulation2
NONCOPYABLE(CSimulation2);
public:
struct LoadScriptError : std::runtime_error
{
using std::runtime_error::runtime_error;
};
// TODO: CUnitManager should probably be handled automatically by this
// module, but for now we'll have it passed in externally instead
CSimulation2(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain,
@@ -66,13 +71,13 @@ public:
* should be called immediately after constructing the CSimulation2 object.
* @return false on failure
*/
bool LoadScripts(const VfsPath& path);
void LoadScripts(const VfsPath& path);
/**
* Call LoadScripts for each of the game's standard simulation script paths.
* @return false on failure
*/
bool LoadDefaultScripts();
void LoadDefaultScripts();
/**
* Loads the player settings script (called before map is loaded)
+3 -3
View File
@@ -65,7 +65,7 @@ public:
{
CXeromycesEngine xeromycesEngine;
CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain};
TS_ASSERT(sim.LoadScripts(L"simulation/components/addentity/"));
sim.LoadScripts(L"simulation/components/addentity/");
sim.ResetState(true, true);
@@ -86,7 +86,7 @@ public:
{
CXeromycesEngine xeromycesEngine;
CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain};
TS_ASSERT(sim.LoadScripts(L"simulation/components/addentity/"));
sim.LoadScripts(L"simulation/components/addentity/");
sim.ResetState(true, true);
@@ -149,7 +149,7 @@ public:
copyFile(L"simulation/components/test-hotload1.js", L"simulation/components/hotload/hotload.js");
TS_ASSERT_OK(g_VFS->RemoveFile(L"simulation/components/hotload/hotload.js"));
TS_ASSERT_OK(g_VFS->RepopulateDirectory(L"simulation/components/hotload/"));
TS_ASSERT(sim.LoadScripts(L"simulation/components/hotload/"));
sim.LoadScripts(L"simulation/components/hotload/");
sim.ResetState(true, true);
@@ -320,7 +320,14 @@ ActorViewer::ActorViewer()
}
// Prepare the simulation
m.Simulation2.LoadDefaultScripts();
try
{
m.Simulation2.LoadDefaultScripts();
}
catch (const CSimulation2::LoadScriptError& e)
{
LOGERROR("%s", e.what());
}
m.Simulation2.ResetState();
// Set player data