engine cleanup passes 4-7 + multi-instancing ambient rip
Squashes 146 commits from battle-engine-extraction. Net: 2,045 files changed, +11,896 / -158,687 lines. Ships engine passes 4-7 (dead-code cull, view-layer stub, receive-path shrink) plus the Phase-5 AsyncLocal ambient deletion that turns concurrent battles into a type-system property rather than a scope contract. ## What landed **Passes 4-7 (chunks 1-34):** Extended the Phase-4 const-false collapse into a cascading cull across the skill graph, view layer, and receive-path periphery. Six mode flags (IsWatchBattle/IsReplayBattle/IsAdmin/IsAdminWatch/IsPuzzleQuest/ IsAINetwork) became `const false`, every guarded block deleted. Field*.cs subclass ctors + BackGroundBase + ObjectChecker culled to no-ops. Mulligan family reworked to take a mgr param through IMulliganMgr.InitMulligan. Emotion/Recovery/Resource clusters null-stubbed. Prediction/OperationSimulator/ skill filters converted from static ambient reads to per-mgr reads via SkillPrm.ownerCard.SelfBattlePlayer.BattleMgr / ins.BattleMgr / this.BattleMgr. **Phase-5 ambient rip (chunks 35-47):** Deleted BattleAmbient / BattleAmbient- Context / TestBattleScope in full. Every per-battle mutable slot now lives on the mgr instance itself: mgr.InstanceIsForecast / InstanceIsRandomDraw / InstanceRecoveryInfo / InstanceViewerId / InstanceNetworkAgent / GameMgr BattleManagerBase.GetIns() returns null unconditionally; the residual static flags + 3 façades (Certification.ViewerId, Data.BattleRecoveryInfo, ToolboxGame.RealTimeNetworkAgent) are null-tolerant defaults kept for the handful of engine-internal readers that still reference their types. Zero BattleAmbient references anywhere in engine + node + tests. Added pre-seeded GameMgr ctor overload threaded through the mgr chain (BattleManagerBase → SingleBattleMgr / NetworkBattleManagerBase → NetworkStandard- BattleMgr → HeadlessBattleMgr / HeadlessNetworkBattleMgr). Fixtures build a GameMgr, seed it via HeadlessEngineEnv.SeedCharaIds/SeedNetUser, and pass it to the mgr's ctor — no ambient reach. Node side (SVSim.BattleNode/SessionBattleEngine): _ctx replaced with a plain GameMgr field; 34 `using var _ambient = BattleAmbient.Enter(_ctx)` scope wraps ripped from every accessor and mutator; EngineGlobalInit.WirePerSessionGameMgr takes GameMgr as a param and runs from SessionBattleEngine.SetupInternal BEFORE mgr construction. Test side: TestBattleScope deleted; 18 fixture [SetUp]s migrated to `HeadlessEngineEnv.EnsureProcessGlobals()`; MultiInstanceEngineTests rewritten around per-mgr construction (GetIns() → null is the pinned invariant). ## Regression fixes - **chunk-48** (MulliganCtrl): chunk-35's `= null` stubs on card lookups broke the live receive-driven Deal path (BattlePlayerBase.DrawCard NRE'd downstream of NetworkPlayerMulliganCtrl.StartMulliganVfx). Restored the three lookups via `_battlePlayer.BattleMgr.GetBattleCardIdx`. Engine tests were satisfied by the WireMulliganPhase seam; unit tests exposed the live-path gap. ## Ship state - SVSim.BattleEngine.Tests: 56/56 pass, 2 skip - SVSim.UnitTests: 1554/1554 pass (was 1523/31-fail before chunk 48) - Solution build: 0 source warnings (40 pre-existing NU1902 MessagePack CVEs in SVSim.EmulatedEntrypoint, unrelated) - Sequential PVP smoke: verified live (two back-to-back battles, no regression on cleanup/spinup) - Concurrent PVP smoke: verified live Adds tools/engine-port/ClosureAnalyzer/ — the Roslyn transitive-type-closure analyzer needed to make future cascade cleanup safe (per feedback memory "Engine cleanup needs closure tool" from the 2026-06-28 pass-3 failure). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,6 @@ public class UILabel : UIWidget
|
||||
public enum Effect
|
||||
{
|
||||
None,
|
||||
Shadow,
|
||||
Outline,
|
||||
Outline8
|
||||
}
|
||||
@@ -26,12 +25,7 @@ public class UILabel : UIWidget
|
||||
|
||||
public enum Crispness
|
||||
{
|
||||
Never,
|
||||
OnDesktop,
|
||||
Always
|
||||
}
|
||||
|
||||
public Crispness keepCrispWhenShrunk = Crispness.OnDesktop;
|
||||
}
|
||||
|
||||
private static bool OnFontChangedFlg = false;
|
||||
|
||||
@@ -210,8 +204,6 @@ public class UILabel : UIWidget
|
||||
|
||||
private string _originalText;
|
||||
|
||||
public Action OnWindowResize;
|
||||
|
||||
private static BetterList<UILabel> mList = new BetterList<UILabel>();
|
||||
|
||||
private static Dictionary<UnityEngine.Font, int> mFontUsage = new Dictionary<UnityEngine.Font, int>();
|
||||
@@ -234,18 +226,6 @@ public class UILabel : UIWidget
|
||||
|
||||
public float DotMargin => m_WizardDotMargin;
|
||||
|
||||
public int finalFontSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((bool)trueTypeFont)
|
||||
{
|
||||
return Mathf.RoundToInt(mScale * (float)mFinalFontSize);
|
||||
}
|
||||
return Mathf.RoundToInt((float)mFinalFontSize * mScale);
|
||||
}
|
||||
}
|
||||
|
||||
private bool shouldBeProcessed
|
||||
{
|
||||
get
|
||||
@@ -319,19 +299,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use UILabel.bitmapFont instead")]
|
||||
public UIFont font
|
||||
{
|
||||
get
|
||||
{
|
||||
return bitmapFont;
|
||||
}
|
||||
set
|
||||
{
|
||||
bitmapFont = value;
|
||||
}
|
||||
}
|
||||
|
||||
public UIFont bitmapFont
|
||||
{
|
||||
get
|
||||
@@ -471,23 +438,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
public FontStyle fontStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFontStyle;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (mFontStyle != value)
|
||||
{
|
||||
mFontStyle = value;
|
||||
shouldBeProcessed = true;
|
||||
ProcessAndRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NGUIText.Alignment alignment
|
||||
{
|
||||
get
|
||||
@@ -570,22 +520,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
public int spacingX
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSpacingX;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (mSpacingX != value)
|
||||
{
|
||||
mSpacingX = value;
|
||||
MarkAsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int spacingY
|
||||
{
|
||||
get
|
||||
@@ -602,54 +536,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
public bool useFloatSpacing
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUseFloatSpacing;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (mUseFloatSpacing != value)
|
||||
{
|
||||
mUseFloatSpacing = value;
|
||||
shouldBeProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float floatSpacingX
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFloatSpacingX;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!Mathf.Approximately(mFloatSpacingX, value))
|
||||
{
|
||||
mFloatSpacingX = value;
|
||||
MarkAsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float floatSpacingY
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFloatSpacingY;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!Mathf.Approximately(mFloatSpacingY, value))
|
||||
{
|
||||
mFloatSpacingY = value;
|
||||
MarkAsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float effectiveSpacingY
|
||||
{
|
||||
get
|
||||
@@ -708,22 +594,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
public NGUIText.SymbolStyle symbolStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSymbols;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (mSymbols != value)
|
||||
{
|
||||
mSymbols = value;
|
||||
shouldBeProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Overflow overflowMethod
|
||||
{
|
||||
get
|
||||
@@ -740,32 +610,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use 'width' instead")]
|
||||
public int lineWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.width;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.width = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use 'height' instead")]
|
||||
public int lineHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.height;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.height = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool multiLine
|
||||
{
|
||||
get
|
||||
@@ -889,22 +733,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use 'overflowMethod == UILabel.Overflow.ShrinkContent' instead")]
|
||||
public bool shrinkToFit
|
||||
{
|
||||
get
|
||||
{
|
||||
return mOverflow == Overflow.ShrinkContent;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
overflowMethod = Overflow.ShrinkContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string processedText
|
||||
{
|
||||
get
|
||||
@@ -965,18 +793,6 @@ public class UILabel : UIWidget
|
||||
text = Global.GetConvertWrapText(this, s);
|
||||
}
|
||||
|
||||
public void WrapOnResize()
|
||||
{
|
||||
if (_originalText != null)
|
||||
{
|
||||
text = Global.GetConvertWrapText(this, _originalText);
|
||||
}
|
||||
if (OnWindowResize != null)
|
||||
{
|
||||
OnWindowResize();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInit()
|
||||
{
|
||||
base.OnInit();
|
||||
@@ -1131,17 +947,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshCustom()
|
||||
{
|
||||
SetActiveFont(null);
|
||||
mList.Remove(this);
|
||||
RemoveFromPanel();
|
||||
if (base.isActiveAndEnabled)
|
||||
{
|
||||
base.OnEnable();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
@@ -1310,12 +1115,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator FontRefreshCoroutine()
|
||||
{
|
||||
yield return null;
|
||||
Invalidate(includeChildren: false);
|
||||
}
|
||||
|
||||
private static void FontReflash(UnityEngine.Font font)
|
||||
{
|
||||
OnFontChangedFlg = false;
|
||||
@@ -1420,46 +1219,6 @@ public class UILabel : UIWidget
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use UILabel.GetCharacterAtPosition instead")]
|
||||
public int GetCharacterIndex(Vector3 worldPos)
|
||||
{
|
||||
return GetCharacterIndexAtPosition(worldPos, precise: false);
|
||||
}
|
||||
|
||||
[Obsolete("Use UILabel.GetCharacterAtPosition instead")]
|
||||
public int GetCharacterIndex(Vector2 localPos)
|
||||
{
|
||||
return GetCharacterIndexAtPosition(localPos, precise: false);
|
||||
}
|
||||
|
||||
public int GetCharacterIndexAtPositionRangeSpecification(Vector3 worldPos, List<int[]> rangeList)
|
||||
{
|
||||
if (isValid)
|
||||
{
|
||||
Vector2 pos = base.cachedTransform.InverseTransformPoint(worldPos);
|
||||
string value = processedText;
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
UpdateNGUIText();
|
||||
NGUIText.PrintApproximateCharacterPositions(value, mTempVerts, mTempIndices);
|
||||
if (mTempVerts.size > 0)
|
||||
{
|
||||
ApplyOffset(mTempVerts, 0);
|
||||
int nearCharacterIndex = NGUIText.GetNearCharacterIndex(mTempVerts, mTempIndices, pos, rangeList);
|
||||
mTempVerts.Clear();
|
||||
mTempIndices.Clear();
|
||||
NGUIText.bitmapFont = null;
|
||||
NGUIText.dynamicFont = null;
|
||||
return nearCharacterIndex;
|
||||
}
|
||||
NGUIText.bitmapFont = null;
|
||||
NGUIText.dynamicFont = null;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetCharacterIndexAtPosition(Vector3 worldPos, bool precise)
|
||||
{
|
||||
Vector2 localPos = base.cachedTransform.InverseTransformPoint(worldPos);
|
||||
@@ -1500,137 +1259,6 @@ public class UILabel : UIWidget
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string GetWordAtPosition(Vector3 worldPos)
|
||||
{
|
||||
int characterIndexAtPosition = GetCharacterIndexAtPosition(worldPos, precise: true);
|
||||
return GetWordAtCharacterIndex(characterIndexAtPosition);
|
||||
}
|
||||
|
||||
public string GetWordAtPosition(Vector2 localPos)
|
||||
{
|
||||
int characterIndexAtPosition = GetCharacterIndexAtPosition(localPos, precise: true);
|
||||
return GetWordAtCharacterIndex(characterIndexAtPosition);
|
||||
}
|
||||
|
||||
public string GetWordAtCharacterIndex(int characterIndex)
|
||||
{
|
||||
if (characterIndex != -1 && characterIndex < mText.Length)
|
||||
{
|
||||
int num = mText.LastIndexOfAny(new char[2] { ' ', '\n' }, characterIndex) + 1;
|
||||
int num2 = mText.IndexOfAny(new char[4] { ' ', '\n', ',', '.' }, characterIndex);
|
||||
if (num2 == -1)
|
||||
{
|
||||
num2 = mText.Length;
|
||||
}
|
||||
if (num != num2)
|
||||
{
|
||||
int num3 = num2 - num;
|
||||
if (num3 > 0)
|
||||
{
|
||||
return NGUIText.StripSymbols(mText.Substring(num, num3));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetUrlAtPosition(Vector3 worldPos)
|
||||
{
|
||||
return GetUrlAtCharacterIndex(GetCharacterIndexAtPosition(worldPos, precise: true));
|
||||
}
|
||||
|
||||
public string GetUrlAtPosition(Vector2 localPos)
|
||||
{
|
||||
return GetUrlAtCharacterIndex(GetCharacterIndexAtPosition(localPos, precise: true));
|
||||
}
|
||||
|
||||
public string GetUrlAtCharacterIndex(int characterIndex)
|
||||
{
|
||||
if (characterIndex != -1 && characterIndex < mText.Length - 6)
|
||||
{
|
||||
int num = ((mText[characterIndex] != '[' || mText[characterIndex + 1] != 'u' || mText[characterIndex + 2] != 'r' || mText[characterIndex + 3] != 'l' || mText[characterIndex + 4] != '=') ? mText.LastIndexOf("[url=", characterIndex) : characterIndex);
|
||||
if (num == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
num += 5;
|
||||
int num2 = mText.IndexOf("]", num);
|
||||
if (num2 == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int num3 = mText.IndexOf("[/url]", num2);
|
||||
if (num3 == -1 || characterIndex <= num3)
|
||||
{
|
||||
return mText.Substring(num, num2 - num);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int GetCharacterIndex(int currentIndex, KeyCode key)
|
||||
{
|
||||
if (isValid)
|
||||
{
|
||||
string text = processedText;
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int num = defaultFontSize;
|
||||
UpdateNGUIText();
|
||||
NGUIText.PrintApproximateCharacterPositions(text, mTempVerts, mTempIndices);
|
||||
if (mTempVerts.size > 0)
|
||||
{
|
||||
ApplyOffset(mTempVerts, 0);
|
||||
for (int i = 0; i < mTempIndices.size; i++)
|
||||
{
|
||||
if (mTempIndices[i] == currentIndex)
|
||||
{
|
||||
Vector2 pos = mTempVerts[i];
|
||||
switch (key)
|
||||
{
|
||||
case KeyCode.UpArrow:
|
||||
pos.y += (float)num + effectiveSpacingY;
|
||||
break;
|
||||
case KeyCode.DownArrow:
|
||||
pos.y -= (float)num + effectiveSpacingY;
|
||||
break;
|
||||
case KeyCode.Home:
|
||||
pos.x -= 1000f;
|
||||
break;
|
||||
case KeyCode.End:
|
||||
pos.x += 1000f;
|
||||
break;
|
||||
}
|
||||
int approximateCharacterIndex = NGUIText.GetApproximateCharacterIndex(mTempVerts, mTempIndices, pos);
|
||||
if (approximateCharacterIndex == currentIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
mTempVerts.Clear();
|
||||
mTempIndices.Clear();
|
||||
return approximateCharacterIndex;
|
||||
}
|
||||
}
|
||||
mTempVerts.Clear();
|
||||
mTempIndices.Clear();
|
||||
}
|
||||
NGUIText.bitmapFont = null;
|
||||
NGUIText.dynamicFont = null;
|
||||
switch (key)
|
||||
{
|
||||
case KeyCode.UpArrow:
|
||||
case KeyCode.Home:
|
||||
return 0;
|
||||
case KeyCode.DownArrow:
|
||||
case KeyCode.End:
|
||||
return text.Length;
|
||||
}
|
||||
}
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
public void PrintOverlay(int start, int end, UIGeometry caret, UIGeometry highlight, Color caretColor, Color highlightColor)
|
||||
{
|
||||
caret?.Clear();
|
||||
@@ -1798,30 +1426,6 @@ public class UILabel : UIWidget
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetCurrentProgress()
|
||||
{
|
||||
if (UIProgressBar.current != null)
|
||||
{
|
||||
text = UIProgressBar.current.value.ToString("F");
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCurrentPercent()
|
||||
{
|
||||
if (UIProgressBar.current != null)
|
||||
{
|
||||
text = Mathf.RoundToInt(UIProgressBar.current.value * 100f) + "%";
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCurrentSelection()
|
||||
{
|
||||
if (UIPopupList.current != null)
|
||||
{
|
||||
text = (UIPopupList.current.isLocalized ? Localization.Get(UIPopupList.current.value) : UIPopupList.current.value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Wrap(string text, out string final)
|
||||
{
|
||||
return Wrap(text, out final, 1000000);
|
||||
@@ -1930,12 +1534,4 @@ public class UILabel : UIWidget
|
||||
}
|
||||
NGUIText.Update(base.rawPivot);
|
||||
}
|
||||
|
||||
private void OnApplicationPause(bool paused)
|
||||
{
|
||||
if (!paused && mTrueTypeFont != null)
|
||||
{
|
||||
Invalidate(includeChildren: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user