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:
@@ -17,23 +17,17 @@ public class UIScrollView : MonoBehaviour
|
||||
public enum DragEffect
|
||||
{
|
||||
None,
|
||||
Momentum,
|
||||
MomentumAndSpring
|
||||
}
|
||||
|
||||
public enum ShowCondition
|
||||
{
|
||||
Always,
|
||||
OnlyIfNeeded,
|
||||
WhenDragging
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void OnDragNotification();
|
||||
|
||||
public static BetterList<UIScrollView> list = new BetterList<UIScrollView>();
|
||||
|
||||
public bool IsScrollYAxisOnly;
|
||||
|
||||
public Movement movement;
|
||||
|
||||
public DragEffect dragEffect = DragEffect.MomentumAndSpring;
|
||||
@@ -44,20 +38,12 @@ public class UIScrollView : MonoBehaviour
|
||||
|
||||
public bool smoothDragStart = true;
|
||||
|
||||
public bool iOSDragEmulation = true;
|
||||
|
||||
public float scrollWheelFactor = 0.25f;
|
||||
|
||||
public float momentumAmount = 35f;
|
||||
|
||||
public float dampenStrength = 9f;
|
||||
|
||||
public UIProgressBar horizontalScrollBar;
|
||||
|
||||
public UIProgressBar verticalScrollBar;
|
||||
|
||||
public ShowCondition showScrollBars = ShowCondition.OnlyIfNeeded;
|
||||
|
||||
public Vector2 customMovement = new Vector2(1f, 0f);
|
||||
|
||||
public UIWidget.Pivot contentPivot;
|
||||
@@ -66,8 +52,6 @@ public class UIScrollView : MonoBehaviour
|
||||
|
||||
public OnDragNotification onDragFinished;
|
||||
|
||||
public OnDragNotification onMomentumMove;
|
||||
|
||||
public OnDragNotification onStoppedMoving;
|
||||
|
||||
[HideInInspector]
|
||||
@@ -108,11 +92,6 @@ public class UIScrollView : MonoBehaviour
|
||||
|
||||
protected bool mDragStarted;
|
||||
|
||||
public const float WIN_SCROLL_FACTOR = 10f;
|
||||
|
||||
[NonSerialized]
|
||||
private bool mStarted;
|
||||
|
||||
[HideInInspector]
|
||||
public UICenterOnChild centerOnChild;
|
||||
|
||||
@@ -176,19 +155,6 @@ public class UIScrollView : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool shouldMoveHorizontally
|
||||
{
|
||||
get
|
||||
{
|
||||
float num = bounds.size.x;
|
||||
if (mPanel.clipping == UIDrawCall.Clipping.SoftClip)
|
||||
{
|
||||
num += mPanel.clipSoftness.x * 2f;
|
||||
}
|
||||
return Mathf.RoundToInt(num - mPanel.width) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool shouldMoveVertically
|
||||
{
|
||||
get
|
||||
@@ -262,22 +228,6 @@ public class UIScrollView : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public float CurrentScroll
|
||||
{
|
||||
set
|
||||
{
|
||||
mScroll = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool NeedsCalculateBounds
|
||||
{
|
||||
set
|
||||
{
|
||||
mCalculatedBounds = !value;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
mTrans = base.transform;
|
||||
@@ -315,45 +265,6 @@ public class UIScrollView : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
list.Add(this);
|
||||
if (mStarted && Application.isPlaying)
|
||||
{
|
||||
CheckScrollbars();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
mStarted = true;
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
CheckScrollbars();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckScrollbars()
|
||||
{
|
||||
if (horizontalScrollBar != null)
|
||||
{
|
||||
EventDelegate.Add(horizontalScrollBar.onChange, OnScrollBar);
|
||||
horizontalScrollBar.BroadcastMessage("CacheDefaultColor", SendMessageOptions.DontRequireReceiver);
|
||||
horizontalScrollBar.alpha = ((showScrollBars == ShowCondition.Always || shouldMoveHorizontally) ? 1f : 0f);
|
||||
}
|
||||
if (verticalScrollBar != null)
|
||||
{
|
||||
EventDelegate.Add(verticalScrollBar.onChange, OnScrollBar);
|
||||
verticalScrollBar.BroadcastMessage("CacheDefaultColor", SendMessageOptions.DontRequireReceiver);
|
||||
verticalScrollBar.alpha = ((showScrollBars == ShowCondition.Always || shouldMoveVertically) ? 1f : 0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
list.Remove(this);
|
||||
}
|
||||
|
||||
public bool RestrictWithinBounds(bool instant)
|
||||
{
|
||||
return RestrictWithinBounds(instant, horizontal: true, vertical: true);
|
||||
@@ -584,11 +495,6 @@ public class UIScrollView : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public void InvalidateBounds()
|
||||
{
|
||||
mCalculatedBounds = false;
|
||||
}
|
||||
|
||||
[ContextMenu("Reset Clipping Position")]
|
||||
public void ResetPosition()
|
||||
{
|
||||
@@ -617,18 +523,6 @@ public class UIScrollView : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public void OnScrollBar()
|
||||
{
|
||||
if (!mIgnoreCallbacks)
|
||||
{
|
||||
mIgnoreCallbacks = true;
|
||||
float x = ((horizontalScrollBar != null) ? horizontalScrollBar.value : 0f);
|
||||
float y = ((verticalScrollBar != null) ? verticalScrollBar.value : 0f);
|
||||
SetDragAmount(x, y, updateScrollbars: false);
|
||||
mIgnoreCallbacks = false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void MoveRelative(Vector3 relative)
|
||||
{
|
||||
mTrans.localPosition += relative;
|
||||
@@ -639,13 +533,6 @@ public class UIScrollView : MonoBehaviour
|
||||
UpdateScrollbars(recalculateBounds: false);
|
||||
}
|
||||
|
||||
public void MoveAbsolute(Vector3 absolute)
|
||||
{
|
||||
Vector3 vector = mTrans.InverseTransformPoint(absolute);
|
||||
Vector3 vector2 = mTrans.InverseTransformPoint(Vector3.zero);
|
||||
MoveRelative(vector - vector2);
|
||||
}
|
||||
|
||||
public void Press(bool pressed)
|
||||
{
|
||||
if (UICamera.currentScheme == UICamera.ControlScheme.Controller)
|
||||
@@ -717,230 +604,4 @@ public class UIScrollView : MonoBehaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Drag()
|
||||
{
|
||||
if (UICamera.currentScheme == UICamera.ControlScheme.Controller || !base.enabled || !NGUITools.GetActive(base.gameObject) || !mShouldMove)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mDragID == -10)
|
||||
{
|
||||
mDragID = UICamera.currentTouchID;
|
||||
}
|
||||
UICamera.currentTouch.clickNotification = UICamera.ClickNotification.BasedOnDelta;
|
||||
if (smoothDragStart && !mDragStarted)
|
||||
{
|
||||
mDragStarted = true;
|
||||
mDragStartOffset = UICamera.currentTouch.totalDelta;
|
||||
if (onDragStarted != null)
|
||||
{
|
||||
onDragStarted();
|
||||
}
|
||||
}
|
||||
Ray ray = (smoothDragStart ? UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos - mDragStartOffset) : UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos));
|
||||
float enter = 0f;
|
||||
if (!mPlane.Raycast(ray, out enter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Vector3 point = ray.GetPoint(enter);
|
||||
Vector3 vector = point - mLastPos;
|
||||
mLastPos = point;
|
||||
if (vector.x != 0f || vector.y != 0f || vector.z != 0f)
|
||||
{
|
||||
vector = mTrans.InverseTransformDirection(vector);
|
||||
if (movement == Movement.Horizontal)
|
||||
{
|
||||
vector.y = 0f;
|
||||
vector.z = 0f;
|
||||
}
|
||||
else if (movement == Movement.Vertical)
|
||||
{
|
||||
vector.x = 0f;
|
||||
vector.z = 0f;
|
||||
}
|
||||
else if (movement == Movement.Unrestricted)
|
||||
{
|
||||
vector.z = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector.Scale(customMovement);
|
||||
}
|
||||
vector = mTrans.TransformDirection(vector);
|
||||
}
|
||||
if (dragEffect == DragEffect.None)
|
||||
{
|
||||
mMomentum = Vector3.zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMomentum = Vector3.Lerp(mMomentum, mMomentum + vector * (0.01f * momentumAmount), 0.67f);
|
||||
}
|
||||
if (!iOSDragEmulation || dragEffect != DragEffect.MomentumAndSpring)
|
||||
{
|
||||
MoveAbsolute(vector);
|
||||
}
|
||||
else if (mPanel.CalculateConstrainOffset(bounds.min, bounds.max).magnitude > 1f)
|
||||
{
|
||||
MoveAbsolute(vector * 0.5f);
|
||||
mMomentum *= 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveAbsolute(vector);
|
||||
}
|
||||
if (restrictWithinPanel && mPanel.clipping != UIDrawCall.Clipping.None && dragEffect != DragEffect.MomentumAndSpring)
|
||||
{
|
||||
RestrictWithinBounds(instant: true, canMoveHorizontally, canMoveVertically);
|
||||
}
|
||||
}
|
||||
|
||||
public void Scroll(float delta)
|
||||
{
|
||||
if (base.enabled && NGUITools.GetActive(base.gameObject) && scrollWheelFactor != 0f)
|
||||
{
|
||||
mCalculatedBounds = false;
|
||||
DisableSpring();
|
||||
mShouldMove |= shouldMove;
|
||||
if (Mathf.Sign(mScroll) != Mathf.Sign(delta))
|
||||
{
|
||||
mScroll = 0f;
|
||||
}
|
||||
mScroll += delta * scrollWheelFactor * 10f;
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float deltaTime = RealTime.deltaTime;
|
||||
if (showScrollBars != ShowCondition.Always && ((bool)verticalScrollBar || (bool)horizontalScrollBar))
|
||||
{
|
||||
bool flag = false;
|
||||
bool flag2 = false;
|
||||
if (showScrollBars != ShowCondition.WhenDragging || mDragID != -10 || mMomentum.magnitude > 0.01f)
|
||||
{
|
||||
flag = shouldMoveVertically;
|
||||
flag2 = shouldMoveHorizontally;
|
||||
}
|
||||
if ((bool)verticalScrollBar)
|
||||
{
|
||||
float alpha = verticalScrollBar.alpha;
|
||||
alpha += (flag ? (deltaTime * 6f) : ((0f - deltaTime) * 3f));
|
||||
alpha = Mathf.Clamp01(alpha);
|
||||
if (verticalScrollBar.alpha != alpha)
|
||||
{
|
||||
verticalScrollBar.alpha = alpha;
|
||||
}
|
||||
}
|
||||
if ((bool)horizontalScrollBar)
|
||||
{
|
||||
float alpha2 = horizontalScrollBar.alpha;
|
||||
alpha2 += (flag2 ? (deltaTime * 6f) : ((0f - deltaTime) * 3f));
|
||||
alpha2 = Mathf.Clamp01(alpha2);
|
||||
if (horizontalScrollBar.alpha != alpha2)
|
||||
{
|
||||
horizontalScrollBar.alpha = alpha2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mShouldMove)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!mPressed)
|
||||
{
|
||||
if (mMomentum.magnitude > 0.0001f || Mathf.Abs(mScroll) > 0.0001f)
|
||||
{
|
||||
if (movement == Movement.Horizontal)
|
||||
{
|
||||
mMomentum -= mTrans.TransformDirection(new Vector3((0f - mScroll) * 0.05f, 0f, 0f));
|
||||
}
|
||||
else if (movement == Movement.Vertical || (movement == Movement.Unrestricted && IsScrollYAxisOnly))
|
||||
{
|
||||
mMomentum -= mTrans.TransformDirection(new Vector3(0f, mScroll * 0.05f, 0f));
|
||||
}
|
||||
else if (movement == Movement.Unrestricted)
|
||||
{
|
||||
mMomentum -= mTrans.TransformDirection(new Vector3((0f - mScroll) * 0.05f, mScroll * 0.05f, 0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
mMomentum -= mTrans.TransformDirection(new Vector3((0f - mScroll) * customMovement.x * 0.05f, mScroll * customMovement.y * 0.05f, 0f));
|
||||
}
|
||||
mScroll = NGUIMath.SpringLerp(mScroll, 0f, 20f, deltaTime);
|
||||
Vector3 absolute = NGUIMath.SpringDampen(ref mMomentum, dampenStrength, deltaTime);
|
||||
MoveAbsolute(absolute);
|
||||
if (restrictWithinPanel && mPanel.clipping != UIDrawCall.Clipping.None)
|
||||
{
|
||||
if (NGUITools.GetActive(centerOnChild))
|
||||
{
|
||||
RestrictWithinBounds(instant: false, canMoveHorizontally, canMoveVertically);
|
||||
if (centerOnChild.nextPageThreshold != 0f)
|
||||
{
|
||||
mMomentum = Vector3.zero;
|
||||
mScroll = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
centerOnChild.Recenter();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RestrictWithinBounds(instant: false, canMoveHorizontally, canMoveVertically);
|
||||
}
|
||||
}
|
||||
if (onMomentumMove != null)
|
||||
{
|
||||
onMomentumMove();
|
||||
}
|
||||
return;
|
||||
}
|
||||
mScroll = 0f;
|
||||
mMomentum = Vector3.zero;
|
||||
SpringPanel component = GetComponent<SpringPanel>();
|
||||
if (!(component != null) || !component.enabled)
|
||||
{
|
||||
mShouldMove = false;
|
||||
if (onStoppedMoving != null)
|
||||
{
|
||||
onStoppedMoving();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mScroll = 0f;
|
||||
NGUIMath.SpringDampen(ref mMomentum, 9f, deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPan(Vector2 delta)
|
||||
{
|
||||
if (horizontalScrollBar != null)
|
||||
{
|
||||
horizontalScrollBar.OnPan(delta);
|
||||
}
|
||||
if (verticalScrollBar != null)
|
||||
{
|
||||
verticalScrollBar.OnPan(delta);
|
||||
}
|
||||
if (horizontalScrollBar == null && verticalScrollBar == null)
|
||||
{
|
||||
if (scale.x != 0f)
|
||||
{
|
||||
Scroll(delta.x);
|
||||
}
|
||||
else if (scale.y != 0f)
|
||||
{
|
||||
Scroll(delta.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user