From 2bb8ba2e1ec62259a2a1efa5507f8f1ec0b158e4 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Sat, 13 Jun 2026 09:35:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Manager=20OnDestroy=20=E5=85=B3=E9=97=AD?= =?UTF-8?q?=20SQLite=20=E8=BF=9E=E6=8E=A5=EF=BC=8C=E4=BF=AE=E5=A4=8D=20dom?= =?UTF-8?q?ain=20reload=20=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 所有 Manager 在 Awake 保存 _db 引用,OnDestroy 调用 Close() - ScenarioManager/ModelManager/ReportManager/GroupManager/SimulationRunner 全部修复 - 崩溃原因:domain reload 时 GC finalizer 线程清理 prepared statements,DB 未关闭导致 sqlite3_finalize 竞态 --- AGENTS.md | 17 ++++++++++------- .../CounterDrone.Core/CounterDrone.Core.dll | Bin 115712 -> 116736 bytes .../Assets/Scripts/Managers/GroupManager.cs | 7 +++++-- .../Assets/Scripts/Managers/ModelManager.cs | 7 +++++-- .../Assets/Scripts/Managers/ReportManager.cs | 7 +++++-- .../Scripts/Managers/ScenarioManager.cs | 13 ++++++++----- .../Scripts/Managers/SimulationRunner.cs | 13 +++++++------ 7 files changed, 40 insertions(+), 24 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index af9de38..12888cc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -76,19 +76,22 @@ pwsh scripts/check_unity_build.ps1 This automatically rebuilds Core.dll, copies it to Unity Plugins, and compiles Unity scripts. Exits 0 if all pass. -## 7. Run Targeted Tests, Not Full Suite +## 7. Run Targeted Tests First -**Never run all tests unless explicitly asked.** Always use `--filter` to run only the tests relevant to what you changed. +**Always run the narrowest relevant test first.** If you just changed `DefensePlannerTests`, run `--filter 'FullyQualifiedName~DefensePlannerTests'`. If you changed `FullPipelineTests`, run that filter. Don't start with `dotnet test` on the whole project — it wastes time and buries the failures you're looking for. + +Run full suite only after the targeted tests pass, to verify nothing else broke. ```bash -# Run a single test: -pwsh -Command "dotnet test test/unit/CounterDrone.Core.Tests/ --filter 'FullyQualifiedName~TestName'" - # Run a test class: pwsh -Command "dotnet test test/unit/CounterDrone.Core.Tests/ --filter 'FullyQualifiedName~DefensePlannerTests'" -``` -Running all 125+ tests wastes ~30 seconds every time and buries the failures you actually care about. +# Run a single test: +pwsh -Command "dotnet test test/unit/CounterDrone.Core.Tests/ --filter 'FullyQualifiedName~Scenario_AirBased'" + +# Run full suite (only after targeted passes): +pwsh -Command "dotnet test test/unit/CounterDrone.Core.Tests/" +``` --- diff --git a/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll b/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll index f57dbb9bef529399f3cfc9caa16761475e69a9b3..1a4b1710c3b8b385c982578a55c84d7d73fa284c 100644 GIT binary patch delta 43561 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 eoug&+f$c)XC^ln97=KZHu{E<&kX1*vg~vXfJQY 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 diff --git a/src/Unity/Assets/Scripts/Managers/GroupManager.cs b/src/Unity/Assets/Scripts/Managers/GroupManager.cs index 3affea1..90402fe 100644 --- a/src/Unity/Assets/Scripts/Managers/GroupManager.cs +++ b/src/Unity/Assets/Scripts/Managers/GroupManager.cs @@ -11,16 +11,19 @@ namespace CounterDrone.Unity public class GroupManager : MonoBehaviour { private IGroupService _service; + private SQLite.SQLiteConnection _db; public IGroupService Service => _service; public void Awake() { var paths = new UnityPathProvider(); - var db = new DatabaseManager(paths).OpenMainDb(); - _service = new GroupService(new GroupRepository(db)); + _db = new DatabaseManager(paths).OpenMainDb(); + _service = new GroupService(new GroupRepository(_db)); } + void OnDestroy() => _db?.Close(); + public Group Create(string name, GroupType type, string desc = "") => _service.CreateGroup(name, type, desc); diff --git a/src/Unity/Assets/Scripts/Managers/ModelManager.cs b/src/Unity/Assets/Scripts/Managers/ModelManager.cs index c588f3d..cc009ac 100644 --- a/src/Unity/Assets/Scripts/Managers/ModelManager.cs +++ b/src/Unity/Assets/Scripts/Managers/ModelManager.cs @@ -13,16 +13,19 @@ namespace CounterDrone.Unity { private IModelService _service; private IPathProvider _paths; + private SQLite.SQLiteConnection _db; public IModelService Service => _service; public void Awake() { _paths = new UnityPathProvider(); - var db = new DatabaseManager(_paths).OpenMainDb(); - _service = new ModelService(new ModelRepository(db), _paths); + _db = new DatabaseManager(_paths).OpenMainDb(); + _service = new ModelService(new ModelRepository(_db), _paths); } + void OnDestroy() => _db?.Close(); + public ModelInfo Import(string filePath, string name) => _service.ImportModel(filePath, name); public void Delete(string id) => _service.DeleteModel(id); public List GetAll() => _service.GetAllModels(); diff --git a/src/Unity/Assets/Scripts/Managers/ReportManager.cs b/src/Unity/Assets/Scripts/Managers/ReportManager.cs index 3af2a2f..288415b 100644 --- a/src/Unity/Assets/Scripts/Managers/ReportManager.cs +++ b/src/Unity/Assets/Scripts/Managers/ReportManager.cs @@ -11,16 +11,19 @@ namespace CounterDrone.Unity { private IReportService _service; private IPathProvider _paths; + private SQLite.SQLiteConnection _db; public IReportService Service => _service; public void Awake() { _paths = new UnityPathProvider(); - var db = new DatabaseManager(_paths).OpenMainDb(); - _service = new ReportService(db, _paths); + _db = new DatabaseManager(_paths).OpenMainDb(); + _service = new ReportService(_db, _paths); } + void OnDestroy() => _db?.Close(); + public SimulationReport Generate(string taskId, TaskFullConfig cfg, List events, string status, float duration) => _service.Generate(taskId, cfg, events, status, duration); diff --git a/src/Unity/Assets/Scripts/Managers/ScenarioManager.cs b/src/Unity/Assets/Scripts/Managers/ScenarioManager.cs index 6266430..e729f51 100644 --- a/src/Unity/Assets/Scripts/Managers/ScenarioManager.cs +++ b/src/Unity/Assets/Scripts/Managers/ScenarioManager.cs @@ -11,6 +11,7 @@ namespace CounterDrone.Unity public class ScenarioManager : MonoBehaviour { private IScenarioService _service; + private SQLite.SQLiteConnection _db; public IScenarioService Service => _service; @@ -20,12 +21,12 @@ namespace CounterDrone.Unity { var paths = new UnityPathProvider(); Debug.Log($"ScenarioManager.Awake: dbPath={paths.GetMainDbPath()}"); - var db = new DatabaseManager(paths).OpenMainDb(); + _db = new DatabaseManager(paths).OpenMainDb(); _service = new ScenarioService( - new SimTaskRepository(db), new CombatSceneRepository(db), - new ControlZoneRepository(db), new TargetConfigRepository(db), - new EquipmentDeploymentRepository(db), new CloudDispersalRepository(db), - new RoutePlanRepository(db), new WaypointRepository(db)); + new SimTaskRepository(_db), new CombatSceneRepository(_db), + new ControlZoneRepository(_db), new TargetConfigRepository(_db), + new EquipmentDeploymentRepository(_db), new CloudDispersalRepository(_db), + new RoutePlanRepository(_db), new WaypointRepository(_db)); Debug.Log("ScenarioManager.Awake: OK"); } catch (System.Exception ex) @@ -34,6 +35,8 @@ namespace CounterDrone.Unity } } + void OnDestroy() => _db?.Close(); + public SimTask CreateTask(string name, string number) => _service.CreateTask(name, number); public void DeleteTask(string id) => _service.DeleteTask(id); public TaskFullConfig GetDetail(string id) => _service.GetTaskDetail(id); diff --git a/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs b/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs index 7095997..87e0b40 100644 --- a/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs +++ b/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs @@ -26,6 +26,7 @@ namespace CounterDrone.Unity private IScenarioService _scenario; private IPathProvider _paths; private string _taskId; + private SQLite.SQLiteConnection _db; private readonly Dictionary _entityVisuals = new(); private readonly Dictionary _clouds = new(); @@ -37,13 +38,13 @@ namespace CounterDrone.Unity public void Awake() { _paths = new UnityPathProvider(); - var db = new DatabaseManager(_paths).OpenMainDb(); + _db = new DatabaseManager(_paths).OpenMainDb(); _scenario = new ScenarioService( - new SimTaskRepository(db), new CombatSceneRepository(db), - new ControlZoneRepository(db), new TargetConfigRepository(db), - new EquipmentDeploymentRepository(db), new CloudDispersalRepository(db), - new RoutePlanRepository(db), new WaypointRepository(db)); + new SimTaskRepository(_db), new CombatSceneRepository(_db), + new ControlZoneRepository(_db), new TargetConfigRepository(_db), + new EquipmentDeploymentRepository(_db), new CloudDispersalRepository(_db), + new RoutePlanRepository(_db), new WaypointRepository(_db)); _frameStore = new FrameDataStore(_paths); _engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths); @@ -148,7 +149,7 @@ namespace CounterDrone.Unity } public void Stop() => _engine?.Stop(); - void OnDestroy() => Stop(); + void OnDestroy() { Stop(); _db?.Close(); } private void SpawnDroneVisual(DroneEntity drone) {