refactor(engine-ambient): BattleManagerBase.GetIns reads ambient first, static fallback
Step 3 of multi-instancing migration. The dominant per-battle singleton now resolves through BattleAmbient.Current.Mgr when a scope is active. The legacy 'main' field is renamed _mainFallback and retained for unwrapped callers (tests, anything not yet scope-wrapped). GetIns() still returns null when neither is set, preserving the '?.Foo ?? default' patterns in engine code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using SVSim.BattleEngine.Ambient;
|
using SVSim.BattleEngine.Ambient;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SVSim.BattleEngine.Tests;
|
namespace SVSim.BattleEngine.Tests;
|
||||||
@@ -129,4 +130,22 @@ public class BattleAmbientTests
|
|||||||
|
|
||||||
BattleManagerBase.IsRandomDraw = false;
|
BattleManagerBase.IsRandomDraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetIns_ReadsAmbient_WhenScopeActive()
|
||||||
|
{
|
||||||
|
var fakeMgr = (BattleManagerBase)System.Runtime.Serialization
|
||||||
|
.FormatterServices.GetUninitializedObject(typeof(BattleManagerBase));
|
||||||
|
var ctx = new BattleAmbientContext { Mgr = fakeMgr };
|
||||||
|
using var _ = BattleAmbient.Enter(ctx);
|
||||||
|
Assert.That(BattleManagerBase.GetIns(), Is.SameAs(fakeMgr));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetIns_OutsideScope_FallsBackToStatic()
|
||||||
|
{
|
||||||
|
Assert.That(BattleAmbient.Current, Is.Null);
|
||||||
|
var v = BattleManagerBase.GetIns();
|
||||||
|
Assert.Pass($"GetIns()={(v is null ? "null" : v.GetType().Name)}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ BattleFinishToOpponentDisConnectChecker.cs BattleFinishToOpponentDisConnectCheck
|
|||||||
BattleKeywordInfoListMgr.cs BattleKeywordInfoListMgr.cs a014170d0b3f5499635bcc2e29755dc2f3125d5a5a28b1741a4abc74b4abcf86 0
|
BattleKeywordInfoListMgr.cs BattleKeywordInfoListMgr.cs a014170d0b3f5499635bcc2e29755dc2f3125d5a5a28b1741a4abc74b4abcf86 0
|
||||||
BattleLifeTimeSharedObject.cs BattleLifeTimeSharedObject.cs ab8bc3703d268752a1de56ab5d3e9ebd276980c20076eb0ca300838b3db13d5f 0
|
BattleLifeTimeSharedObject.cs BattleLifeTimeSharedObject.cs ab8bc3703d268752a1de56ab5d3e9ebd276980c20076eb0ca300838b3db13d5f 0
|
||||||
BattleLogTextBuilderAttachSkill.cs BattleLogTextBuilderAttachSkill.cs 11c585ae931fa3dc734bb231d6da61df3b51b803516ca2c5d88a0c78bc7c0104 0
|
BattleLogTextBuilderAttachSkill.cs BattleLogTextBuilderAttachSkill.cs 11c585ae931fa3dc734bb231d6da61df3b51b803516ca2c5d88a0c78bc7c0104 0
|
||||||
BattleManagerBase.cs BattleManagerBase.cs 6e537b57a66d16c056f62ed3d00c1727d08adab098e90b4f1373c987a2da8a35 1
|
BattleManagerBase.cs BattleManagerBase.cs d12aed345f596e068bfb130a247e280457cf5160a76f8bfef4a1dda1c561d196 1
|
||||||
BattleMenuMgr.cs BattleMenuMgr.cs 7418699063e01641d0df1ed16773a9ac9418f418cc047fc18c5892eb7971d361 0
|
BattleMenuMgr.cs BattleMenuMgr.cs 7418699063e01641d0df1ed16773a9ac9418f418cc047fc18c5892eb7971d361 0
|
||||||
BattlePlayer.cs BattlePlayer.cs 001409844b46ddaf0a5edbce4e015749ece61053adf725a978987d7063a02632 0
|
BattlePlayer.cs BattlePlayer.cs 001409844b46ddaf0a5edbce4e015749ece61053adf725a978987d7063a02632 0
|
||||||
BattlePlayerBase.cs BattlePlayerBase.cs 9d3a665158706460a52900008dcfcdf575dbe08cb6d3cc05e63e718b2885b51b 0
|
BattlePlayerBase.cs BattlePlayerBase.cs 9d3a665158706460a52900008dcfcdf575dbe08cb6d3cc05e63e718b2885b51b 0
|
||||||
|
|||||||
|
@@ -410,7 +410,7 @@ public class BattleManagerBase
|
|||||||
|
|
||||||
private NetworkTouchControl _networkTouchControl;
|
private NetworkTouchControl _networkTouchControl;
|
||||||
|
|
||||||
private static BattleManagerBase main;
|
private static BattleManagerBase _mainFallback;
|
||||||
|
|
||||||
private static bool _isRandomDrawFallback = false;
|
private static bool _isRandomDrawFallback = false;
|
||||||
public static bool IsRandomDraw {
|
public static bool IsRandomDraw {
|
||||||
@@ -724,12 +724,12 @@ public class BattleManagerBase
|
|||||||
|
|
||||||
public static BattleManagerBase GetIns()
|
public static BattleManagerBase GetIns()
|
||||||
{
|
{
|
||||||
return main;
|
return SVSim.BattleEngine.Ambient.BattleAmbient.Current?.Mgr ?? _mainFallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BattleManagerBase(IBattleMgrContentsCreator contentsCreator)
|
protected BattleManagerBase(IBattleMgrContentsCreator contentsCreator)
|
||||||
{
|
{
|
||||||
main = this;
|
_mainFallback = this;
|
||||||
BattleLifeTimeSharedObject = new BattleLifeTimeSharedObject();
|
BattleLifeTimeSharedObject = new BattleLifeTimeSharedObject();
|
||||||
PublishedSkillList = new List<SkillBase>();
|
PublishedSkillList = new List<SkillBase>();
|
||||||
_contentsCreator = contentsCreator;
|
_contentsCreator = contentsCreator;
|
||||||
@@ -1488,7 +1488,7 @@ public class BattleManagerBase
|
|||||||
GameMgr.GetIns().GetPrefabMgr().DisposeAllClonedObject();
|
GameMgr.GetIns().GetPrefabMgr().DisposeAllClonedObject();
|
||||||
GameMgr.GetIns().GetGameObjMgr().DisposeUIGameObj();
|
GameMgr.GetIns().GetGameObjMgr().DisposeUIGameObj();
|
||||||
GameMgr.GetIns().GetPrefabMgr().AllUnLoad();
|
GameMgr.GetIns().GetPrefabMgr().AllUnLoad();
|
||||||
main = null;
|
_mainFallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeBattleGameObj_DestroyImmediate(GameObject obj)
|
private void DisposeBattleGameObj_DestroyImmediate(GameObject obj)
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
Multi-instancing migration (Step 3): convert the dominant per-battle singleton seam — the
|
||||||
|
static `main` backing field and the `GetIns()` accessor — to read through BattleAmbient.Current
|
||||||
|
first, falling back to a renamed `_mainFallback` static when no scope is active. The legacy
|
||||||
|
field is kept (renamed) so unwrapped callers (SingleBattleMgr today, in-process tests that
|
||||||
|
don't yet wrap in BattleAmbient.Enter) keep working with zero behavioral change; scoped
|
||||||
|
callers get per-AsyncLocal isolation so sibling battles in the same process don't clobber
|
||||||
|
each other's "current manager" (design 2026-06-07-engine-multi-instancing, Task 3).
|
||||||
|
|
||||||
|
GetIns() is the canonical accessor used by ~hundreds of engine call sites; routing it through
|
||||||
|
ambient is what makes the rest of the migration value-adding. Direct cross-file reads of
|
||||||
|
`BattleManagerBase.main` were already absent (the field was private; only an in-comment
|
||||||
|
reference in Shim/BattleAmbientContext.cs exists), so no external callers needed updating.
|
||||||
|
|
||||||
|
In-file references (4 total) handled as follows:
|
||||||
|
- line 413 declaration → renamed to `_mainFallback`
|
||||||
|
- line 725 GetIns body → ambient-first via Current?.Mgr ?? _mainFallback
|
||||||
|
- line 730 ctor `main = this` → `_mainFallback = this`
|
||||||
|
- line 1491 dispose `main=null` → `_mainFallback = null`
|
||||||
|
|
||||||
|
--- Engine/BattleManagerBase.cs (~line 413)
|
||||||
|
- private static BattleManagerBase main;
|
||||||
|
+ private static BattleManagerBase _mainFallback;
|
||||||
|
|
||||||
|
--- Engine/BattleManagerBase.cs (~line 725)
|
||||||
|
public static BattleManagerBase GetIns()
|
||||||
|
{
|
||||||
|
- return main;
|
||||||
|
+ return SVSim.BattleEngine.Ambient.BattleAmbient.Current?.Mgr ?? _mainFallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Engine/BattleManagerBase.cs (~line 730)
|
||||||
|
protected BattleManagerBase(IBattleMgrContentsCreator contentsCreator)
|
||||||
|
{
|
||||||
|
- main = this;
|
||||||
|
+ _mainFallback = this;
|
||||||
|
|
||||||
|
--- Engine/BattleManagerBase.cs (~line 1491)
|
||||||
|
- main = null;
|
||||||
|
+ _mainFallback = null;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user