diff --git a/source/graphics/tests/test_LOSTexture.h b/source/graphics/tests/test_LOSTexture.h index bb9ae4c9a5..a4f5e80f28 100644 --- a/source/graphics/tests/test_LOSTexture.h +++ b/source/graphics/tests/test_LOSTexture.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -36,7 +36,7 @@ class TestLOSTexture : public CxxTest::TestSuite public: void test_basic() { - CSimulation2 sim{nullptr, *g_ScriptContext, nullptr}; + CSimulation2 sim{nullptr, *g_ScriptContext, nullptr, {}}; CLOSTexture tex(sim); const ssize_t size = 8; @@ -75,7 +75,7 @@ public: void DISABLED_test_perf() { - CSimulation2 sim{nullptr, *g_ScriptContext, nullptr}; + CSimulation2 sim{nullptr, *g_ScriptContext, nullptr, {}}; CLOSTexture tex(sim); const ssize_t size = 257; diff --git a/source/graphics/tests/test_Model.h b/source/graphics/tests/test_Model.h index 4ce99ba49d..d52e18e732 100644 --- a/source/graphics/tests/test_Model.h +++ b/source/graphics/tests/test_Model.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -200,7 +200,7 @@ public: TestLogger logger; CMaterial material{}; - CSimulation2 simulation{nullptr, *g_ScriptContext, nullptr}; + CSimulation2 simulation{nullptr, *g_ScriptContext, nullptr, {}}; CTerrain terrain; terrain.Initialize(4, nullptr); @@ -266,7 +266,7 @@ public: CSkeletonAnimManager skeletonAnimationManager{colladaManager}; CUnitManager unitManager; - CSimulation2 simulation{&unitManager, *g_ScriptContext, nullptr}; + CSimulation2 simulation{&unitManager, *g_ScriptContext, nullptr, {}}; CObjectManager objectManager{ meshManager, skeletonAnimationManager, simulation}; unitManager.SetObjectManager(objectManager); diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 7b2517eda2..f57b78f56b 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -80,7 +80,7 @@ const CStr CGame::EventNameSimulationUpdate = "SimulationUpdate"; CGame::CGame(bool replayLog, const SimulationDebugOptions debugOptions): m_World(new CWorld(*this)), m_Simulation2{new CSimulation2{&m_World->GetUnitManager(), *g_ScriptContext, &m_World->GetTerrain(), - debugOptions}}, + CSimulation2::DEFAULT_SCRIPTS, debugOptions}}, // TODO: we need to remove that global dependency. Maybe the game view // should be created outside only if needed. m_GameView(CRenderer::IsInitialised() ? new CGameView(g_VideoMode.GetBackendDevice(), this) : nullptr), @@ -106,8 +106,6 @@ CGame::CGame(bool replayLog, const SimulationDebugOptions debugOptions): m_World->GetUnitManager().SetObjectManager(m_GameView->GetObjectManager()); m_TurnManager = new CLocalTurnManager(*m_Simulation2, GetReplayLogger()); // this will get replaced if we're a net server/client - - m_Simulation2->LoadDefaultScripts(); } /** diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 03d7c2a186..2c41194476 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -596,8 +596,7 @@ bool Init(const CmdLineArgs& args, int flags) { try { - CSimulation2 sim{NULL, *g_ScriptContext, NULL}; - sim.LoadDefaultScripts(); + CSimulation2 sim{NULL, *g_ScriptContext, NULL, CSimulation2::DEFAULT_SCRIPTS}; std::ofstream f("entity.rng", std::ios_base::out | std::ios_base::trunc); f << sim.GenerateSchema(); debug_printf("Generated entity.rng\n"); diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 6bc88957d6..858f7b2120 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,7 @@ class CSimulation2Impl { public: CSimulation2Impl(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain, - const SimulationDebugOptions debugOptions) : + const std::span scriptDirectories, const SimulationDebugOptions debugOptions) : m_SimContext{terrain, unitManager}, m_ComponentManager{m_SimContext, cx}, m_InitAttributes{cx.GetGeneralJSContext()}, @@ -101,6 +102,9 @@ public: m_OOSLogPath = createDateIndexSubdirectory(psLogDir() / "oos_logs"); debug_printf("Writing ooslogs to %s\n", m_OOSLogPath.string8().c_str()); } + + std::ranges::for_each(scriptDirectories, + std::bind_front(LoadScripts, std::ref(m_ComponentManager), &m_LoadedScripts)); } ~CSimulation2Impl() @@ -122,7 +126,6 @@ public: componentManager.AddSystemComponents(skipScriptedComponents, skipAI); } - static void LoadDefaultScripts(CComponentManager& componentManager, std::set* loadedScripts); static void LoadScripts(CComponentManager& componentManager, std::set* loadedScripts, const VfsPath& path); static bool LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue mapSettings, std::set* loadedScripts); Status ReloadChangedFile(const VfsPath& path); @@ -200,13 +203,6 @@ public: } }; -void CSimulation2Impl::LoadDefaultScripts(CComponentManager& componentManager, std::set* loadedScripts) -{ - LoadScripts(componentManager, loadedScripts, L"simulation/components/interfaces/"); - LoadScripts(componentManager, loadedScripts, L"simulation/helpers/"); - LoadScripts(componentManager, loadedScripts, L"simulation/components/"); -} - void CSimulation2Impl::LoadScripts(CComponentManager& componentManager, std::set* loadedScripts, const VfsPath& path) { VfsPaths pathnames; @@ -419,7 +415,8 @@ void CSimulation2Impl::Update(int turnLength, const std::vectorLoadComponentTypes(); m_SecondaryLoadedScripts = std::make_unique>(); - LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts.get()); + std::ranges::for_each(CSimulation2::DEFAULT_SCRIPTS, std::bind_front(LoadScripts, + std::ref(*m_SecondaryComponentManager), m_SecondaryLoadedScripts.get())); ResetComponentState(*m_SecondaryComponentManager, false, false); ScriptRequest rq(scriptInterface); @@ -639,8 +636,8 @@ void CSimulation2Impl::DumpState() //////////////////////////////////////////////////////////////// CSimulation2::CSimulation2(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain, - const SimulationDebugOptions debugOptions) : - m(std::make_unique(unitManager, cx, terrain, debugOptions)) + const std::span scriptDirectories, const SimulationDebugOptions debugOptions) : + m(std::make_unique(unitManager, cx, terrain, scriptDirectories, debugOptions)) { } @@ -756,16 +753,6 @@ float CSimulation2::GetLastFrameOffset() const return m->m_LastFrameOffset; } -void CSimulation2::LoadScripts(const VfsPath& path) -{ - m->LoadScripts(m->m_ComponentManager, &m->m_LoadedScripts, path); -} - -void CSimulation2::LoadDefaultScripts() -{ - m->LoadDefaultScripts(m->m_ComponentManager, &m->m_LoadedScripts); -} - void CSimulation2::SetStartupScript(const std::string& code) { m->m_StartupScript = code; diff --git a/source/simulation2/Simulation2.h b/source/simulation2/Simulation2.h index b27beae4b9..643b0f0fe5 100644 --- a/source/simulation2/Simulation2.h +++ b/source/simulation2/Simulation2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -25,9 +25,11 @@ #include "simulation2/system/DebugOptions.h" #include "simulation2/system/Entity.h" +#include #include #include #include +#include #include #include #include @@ -60,26 +62,21 @@ public: using std::runtime_error::runtime_error; }; + constexpr static auto DEFAULT_SCRIPTS{std::to_array({L"simulation/components/interfaces/", + L"simulation/helpers/", L"simulation/components/"})}; + // TODO: CUnitManager should probably be handled automatically by this // module, but for now we'll have it passed in externally instead + /** + * @param scriptDirectories All scripts in the specified directory + * (non-recursively) are loaded, so that they can register new + * component types and functions. + */ CSimulation2(CUnitManager* unitManager, ScriptContext& cx, CTerrain* terrain, + const std::span scriptDirectories, const SimulationDebugOptions debugOptions = {}); ~CSimulation2(); - /** - * Load all scripts in the specified directory (non-recursively), - * so they can register new component types and functions. This - * should be called immediately after constructing the CSimulation2 object. - * @return false on failure - */ - void LoadScripts(const VfsPath& path); - - /** - * Call LoadScripts for each of the game's standard simulation script paths. - * @return false on failure - */ - void LoadDefaultScripts(); - /** * Loads the player settings script (called before map is loaded) * @param newPlayers will delete all the existing player entities (if any) and create new ones diff --git a/source/simulation2/components/tests/test_Pathfinder.h b/source/simulation2/components/tests/test_Pathfinder.h index 9117c87df1..4e6c89c4f4 100644 --- a/source/simulation2/components/tests/test_Pathfinder.h +++ b/source/simulation2/components/tests/test_Pathfinder.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -158,8 +158,7 @@ public: { CTerrain terrain; - CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain}; - sim2.LoadDefaultScripts(); + CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain, CSimulation2::DEFAULT_SCRIPTS}; sim2.ResetState(); std::unique_ptr mapReader = std::make_unique(); @@ -217,8 +216,7 @@ public: CTerrain terrain; terrain.Initialize(5, NULL); - CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain}; - sim2.LoadDefaultScripts(); + CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain, CSimulation2::DEFAULT_SCRIPTS}; sim2.ResetState(); const entity_pos_t range = entity_pos_t::FromInt(48); @@ -272,8 +270,7 @@ public: { CTerrain terrain; - CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain}; - sim2.LoadDefaultScripts(); + CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain, CSimulation2::DEFAULT_SCRIPTS}; sim2.ResetState(); std::unique_ptr mapReader = std::make_unique(); @@ -329,8 +326,7 @@ public: { CTerrain terrain; - CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain}; - sim2.LoadDefaultScripts(); + CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain, CSimulation2::DEFAULT_SCRIPTS}; sim2.ResetState(); std::unique_ptr mapReader = std::make_unique(); diff --git a/source/simulation2/tests/test_CmpTemplateManager.h b/source/simulation2/tests/test_CmpTemplateManager.h index 03641a2eb2..8657969891 100644 --- a/source/simulation2/tests/test_CmpTemplateManager.h +++ b/source/simulation2/tests/test_CmpTemplateManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -253,8 +253,7 @@ public: { CXeromycesEngine xeromycesEngine; CTerrain dummy; - CSimulation2 sim{nullptr, *g_ScriptContext, &dummy}; - sim.LoadDefaultScripts(); + CSimulation2 sim{nullptr, *g_ScriptContext, &dummy, CSimulation2::DEFAULT_SCRIPTS}; sim.ResetState(); CmpPtr cmpTemplateManager(sim, SYSTEM_ENTITY); diff --git a/source/simulation2/tests/test_Serializer.h b/source/simulation2/tests/test_Serializer.h index 3a00285e48..8628f2549d 100644 --- a/source/simulation2/tests/test_Serializer.h +++ b/source/simulation2/tests/test_Serializer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -901,8 +901,7 @@ public: CTerrain terrain; - CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain}; - sim2.LoadDefaultScripts(); + CSimulation2 sim2{nullptr, *g_ScriptContext, &terrain, CSimulation2::DEFAULT_SCRIPTS}; sim2.ResetState(); std::unique_ptr mapReader = std::make_unique(); diff --git a/source/simulation2/tests/test_Simulation2.h b/source/simulation2/tests/test_Simulation2.h index 8637a33100..8ce041f6ea 100644 --- a/source/simulation2/tests/test_Simulation2.h +++ b/source/simulation2/tests/test_Simulation2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -64,9 +64,8 @@ public: void test_AddEntity() { CXeromycesEngine xeromycesEngine; - CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain}; - sim.LoadScripts(L"simulation/components/addentity/"); - + CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain, + {{L"simulation/components/addentity/"}}}; sim.ResetState(true, true); entity_id_t ent1 = sim.AddEntity(L"test1"); @@ -85,9 +84,8 @@ public: void test_DestroyEntity() { CXeromycesEngine xeromycesEngine; - CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain}; - sim.LoadScripts(L"simulation/components/addentity/"); - + CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain, + {{L"simulation/components/addentity/"}}}; sim.ResetState(true, true); entity_id_t ent1 = sim.AddEntity(L"test1"); @@ -142,15 +140,14 @@ public: void test_hotload_scripts() { CXeromycesEngine xeromycesEngine; - CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain}; TS_ASSERT_OK(CreateDirectories(DataDir()/"mods"/"_test.sim"/"simulation"/"components"/"hotload"/"", 0700)); 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/")); - sim.LoadScripts(L"simulation/components/hotload/"); + CSimulation2 sim{nullptr, *g_ScriptContext, &m_Terrain, {{L"simulation/components/hotload/"}}}; sim.ResetState(true, true); entity_id_t ent = sim.AddEntity(L"hotload"); diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 33e1e197c5..30005e4a22 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -94,7 +94,7 @@ public: MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager), UnitManager(), - Simulation2{&UnitManager, *g_ScriptContext, &Terrain}, + Simulation2{&UnitManager, *g_ScriptContext, &Terrain, CSimulation2::DEFAULT_SCRIPTS}, ObjectManager(MeshManager, SkeletonAnimManager, Simulation2), LOSTexture(Simulation2), TerritoryTexture(Simulation2), @@ -320,14 +320,6 @@ ActorViewer::ActorViewer() } // Prepare the simulation - try - { - m.Simulation2.LoadDefaultScripts(); - } - catch (const CSimulation2::LoadScriptError& e) - { - LOGERROR("%s", e.what()); - } m.Simulation2.ResetState(); // Set player data diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index 54d634de43..c4078b9ac6 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -29,6 +29,7 @@ #include "maths/Matrix3D.h" #include "maths/Vector2D.h" #include "ps/CStr.h" +#include "ps/CLogger.h" #include "ps/ConfigDB.h" #include "ps/Game.h" #include "ps/VideoMode.h" @@ -456,8 +457,15 @@ AtlasViewGame* AtlasView::GetView_Game() AtlasViewActor* AtlasView::GetView_Actor() { - if (! view_Actor) - view_Actor = new AtlasViewActor(); + try + { + if (!view_Actor) + view_Actor = new AtlasViewActor(); + } + catch (const CSimulation2::LoadScriptError& e) + { + LOGERROR("%s", e.what()); + } return view_Actor; } diff --git a/source/tools/lint/cppcheck/suppressions-list.txt b/source/tools/lint/cppcheck/suppressions-list.txt index 3df9d1a1a6..20c3cda2a2 100644 --- a/source/tools/lint/cppcheck/suppressions-list.txt +++ b/source/tools/lint/cppcheck/suppressions-list.txt @@ -65,6 +65,6 @@ unknownMacro:source/lib/sysdep/os/win/wfirmware.cpp unknownMacro:source/lib/sysdep/os/win/wposix/wutsname.cpp unknownMacro:source/ps/CStr.cpp -uninitvar:source/ps/Game.cpp:248 +uninitvar:source/ps/Game.cpp:246 danglingLifetime:source/renderer/backend/gl/Device.cpp