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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user