Skip to content

Commit e302cdc

Browse files
committed
Merge chore/clean-ui-loading-robustness (QA combined)
2 parents 8e14c36 + 0ba54cc commit e302cdc

13 files changed

Lines changed: 60 additions & 23 deletions

File tree

Explorer/Assets/DCL/Character/CharacterCamera/Systems/ControlCinemachineVirtualCameraSystem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ private void HandleOffset([Data] float dt, ref CameraComponent cameraComponent,
117117
{
118118
ThirdPersonCameraShoulder.Right => ThirdPersonCameraShoulder.Left,
119119
ThirdPersonCameraShoulder.Left => ThirdPersonCameraShoulder.Right,
120+
ThirdPersonCameraShoulder.Center => ThirdPersonCameraShoulder.Right,
120121
};
121122

122123
ThirdPersonCameraShoulder thirdPersonCameraShoulder = cameraComponent.Shoulder;

Explorer/Assets/DCL/Character/CharacterPreview/CharacterPreviewAvatarContainer.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public class CharacterPreviewAvatarContainer : MonoBehaviour, IDisposable
2525
private bool isFOVTransitioning;
2626

2727
[field: SerializeField] internal Vector3 previewPositionInScene { get; private set; }
28-
[field: SerializeField] internal Transform avatarParent { get; private set; }
29-
[field: SerializeField] internal Camera camera { get; private set; }
30-
[field: SerializeField] internal Transform cameraTarget { get; private set; }
31-
[field: SerializeField] internal Transform rotationTarget { get; private set; }
32-
[field: SerializeField] internal CinemachineFreeLook freeLookCamera { get; private set; }
33-
[field: SerializeField] internal GameObject previewPlatform { get; private set; }
34-
[field: SerializeField] internal AvatarPreviewHeadIKSettings headIKSettings { get; private set; }
28+
[field: SerializeField] internal Transform avatarParent { get; private set; } = null!;
29+
[field: SerializeField] internal new Camera camera { get; private set; } = null!;
30+
[field: SerializeField] internal Transform cameraTarget { get; private set; } = null!;
31+
[field: SerializeField] internal Transform rotationTarget { get; private set; } = null!;
32+
[field: SerializeField] internal CinemachineFreeLook freeLookCamera { get; private set; } = null!;
33+
[field: SerializeField] internal GameObject previewPlatform { get; private set; } = null!;
34+
[field: SerializeField] internal AvatarPreviewHeadIKSettings headIKSettings { get; private set; } = null!;
3535

3636
internal float TargetFOV { get; set; }
3737
internal float RotationModifier { get; set; }

Explorer/Assets/DCL/Friends/UI/FriendPanel/Sections/FriendPanelSectionControllerBase.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public abstract class FriendPanelSectionControllerBase<T, U> : IDisposable
1919
protected readonly U requestManager;
2020

2121
private CancellationTokenSource friendListInitCts = new ();
22+
private bool disposed;
2223

2324
protected UniTaskCompletionSource? panelLifecycleTask { get; private set; }
2425

@@ -40,6 +41,7 @@ public virtual void Dispose()
4041
view.Disable -= Disable;
4142
requestManager.Dispose();
4243
friendListInitCts.SafeCancelAndDispose();
44+
disposed = true;
4345
}
4446

4547
public async UniTask InitAsync(CancellationToken ct)
@@ -53,6 +55,9 @@ public async UniTask InitAsync(CancellationToken ct)
5355
if (!result.Success)
5456
return;
5557

58+
if (ct.IsCancellationRequested)
59+
return;
60+
5661
view.SetLoadingState(false);
5762

5863
bool showScrollView = ShouldShowScrollView();
@@ -73,6 +78,9 @@ public virtual void Reset() =>
7378

7479
protected void CheckShouldInit()
7580
{
81+
if (disposed)
82+
return;
83+
7684
if (!requestManager.WasInitialised)
7785
InitAsync(friendListInitCts.Token).Forget();
7886
}

Explorer/Assets/DCL/Friends/UI/FriendPanel/Sections/SectionLoadingView.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,28 @@ public class SectionLoadingView : MonoBehaviour
1010
[field: SerializeField] public LoadingBrightView LoadingBright { get; private set; }
1111
[field: SerializeField] public float FadeDuration { get; private set; } = 0.3f;
1212

13+
private Tweener? fadeTween;
14+
1315
public void Show()
1416
{
17+
fadeTween?.Kill();
1518
CanvasGroup.alpha = 1;
1619
CanvasGroup.blocksRaycasts = true;
1720
LoadingBright.StartLoadingAnimation(null);
1821
}
1922

2023
public void Hide()
2124
{
22-
CanvasGroup.DOFade(0, FadeDuration).OnComplete(() => CanvasGroup.blocksRaycasts = false);
25+
fadeTween?.Kill();
26+
fadeTween = CanvasGroup.DOFade(0, FadeDuration).OnComplete(() => CanvasGroup.blocksRaycasts = false);
2327
LoadingBright.FinishLoadingAnimation(null);
2428
}
29+
30+
private void OnDestroy()
31+
{
32+
// Without this the fade outlives panel teardown and DOTween keeps driving the destroyed CanvasGroup.
33+
fadeTween?.Kill();
34+
fadeTween = null;
35+
}
2536
}
2637
}

Explorer/Assets/DCL/PerformanceAndDiagnostics/DebugUtilities/UIBindings/ElementBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace DCL.DebugUtilities.UIBindings
88
/// </summary>
99
public class ElementBinding<T> : IElementBinding<T>
1010
{
11-
private T tempValue;
11+
private T tempValue = default!;
1212

1313
private bool tempValueIsDirty;
1414

Explorer/Assets/DCL/PerformanceAndDiagnostics/DebugUtilities/Views/DebugElementBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace DCL.DebugUtilities.Views
55
{
66
public abstract class DebugElementBase<TElement, TDef> : VisualElement where TElement: DebugElementBase<TElement, TDef> where TDef: IDebugElementDef
77
{
8-
protected TDef definition { get; private set; }
8+
protected TDef definition { get; private set; } = default!;
99

1010
public void Initialize(TDef definition)
1111
{

Explorer/Assets/DCL/RealmNavigation/LoadingOperation/SequentialLoadingOperation.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,26 @@ public virtual async UniTask<EnumResult<TaskError>> ExecuteAsync(string processN
5555

5656
if (!lastOpResult.Success)
5757
{
58-
ReportHub.LogError(
59-
reportData,
60-
$"Operation failed on {processName} attempt {attempt + 1}/{attemptsCount}: {lastOpResult.AsResult().ErrorMessage}"
61-
);
58+
// Do not log cancellation as an error (CLAUDE.md §9): on shutdown the inner op
59+
// converts its OperationCanceledException into a TaskError.Cancelled result.
60+
if (!ct.IsCancellationRequested && lastOpResult.Error?.State != TaskError.Cancelled)
61+
ReportHub.LogError(
62+
reportData,
63+
$"Operation failed on {processName} attempt {attempt + 1}/{attemptsCount}: {lastOpResult.AsResult().ErrorMessage}"
64+
);
6265

6366
break;
6467
}
6568
}
69+
catch (OperationCanceledException) when (ct.IsCancellationRequested)
70+
{
71+
// Cancellation of the outer flow is not an error: convert to a cancelled result
72+
// (the check below exits the attempt loop). An OperationCanceledException from an
73+
// operation's internal token is NOT ours to absorb - it propagates as before, so
74+
// the attempt loop cannot re-run the whole chain on an inner timeout.
75+
lastOpResult = EnumResult<TaskError>.CancelledResult(TaskError.Cancelled);
76+
break;
77+
}
6678
catch (Exception e)
6779
{
6880
lastOpResult = EnumResult<TaskError>.ErrorResult(TaskError.UnexpectedException, $"Unhandled exception on {processName} attempt {attempt + 1}/{attemptsCount}: {e}");

Explorer/Assets/DCL/SceneLoadingScreens/LoadingScreen/LoadingScreen.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,12 @@ async UniTask<EnumResult<TaskError>> ExecuteLoadingScreenAsync()
102102
SceneLoadingScreenController.IssueCommand(new SceneLoadingScreenController.Params(loadReport)), ct)
103103
.SuppressToResultAsync(ReportCategory.SCENE_LOADING);
104104

105-
if (loadReport.GetStatus().TaskStatus == UniTaskStatus.Pending)
105+
// Both logs below are pure cancellation artifacts on ExitPlayMode (the outer ct cancels ShowAsync,
106+
// leaving loadReport Pending and result as TaskError.Cancelled). Only log when not cancelled (CLAUDE.md §9).
107+
if (!ct.IsCancellationRequested && loadReport.GetStatus().TaskStatus == UniTaskStatus.Pending)
106108
ReportHub.LogError(ReportCategory.SCENE_LOADING, "Loading screen finished unexpectedly, but the loading process continues");
107109

108-
if (finalResult.HasValue && !result.Success)
110+
if (!ct.IsCancellationRequested && finalResult.HasValue && !result.Success)
109111
ReportHub.LogError(ReportCategory.SCENE_LOADING, $"Loading screen finished with an error after the flow has finished: {result.Error.AsMessage()}");
110112

111113
return result;

Explorer/Assets/DCL/SceneLoadingScreens/SceneLoadingScreenView.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ private void Awake()
7272

7373
public void ClearTips()
7474
{
75+
// Application/view teardown can destroy the tip objects (children of this view) before
76+
// ClearTips runs; skip the already-destroyed entries.
7577
foreach (TipView tip in tips)
76-
Destroy(tip.gameObject);
78+
if (tip != null) Destroy(tip.gameObject);
7779

7880
foreach (TipBreadcrumb? breadcrumb in tipsBreadcrumbs)
79-
Destroy(breadcrumb.gameObject);
81+
if (breadcrumb != null) Destroy(breadcrumb.gameObject);
8082

8183
tips.Clear();
8284
tipsBreadcrumbs.Clear();

Explorer/Assets/DCL/SceneLoadingScreens/UnityLocalizationSceneTipsProvider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public async UniTask InitializeAsync(CancellationToken ct)
4646
fallbackTips = Get(tipsTable, imagesTable, ct);
4747
}
4848

49-
public async UniTask<SceneTips> GetAsync(CancellationToken ct) =>
49+
public UniTask<SceneTips> GetAsync(CancellationToken ct) =>
5050

5151
// TODO: we will need specific scene tips in the future, but its disabled at the moment
5252
/*StringTable tipsTable = await tipsDatabase.GetTableAsync($"LoadingSceneTips-{parcelCoord.x},{parcelCoord.y}").Task
@@ -60,7 +60,7 @@ public async UniTask<SceneTips> GetAsync(CancellationToken ct) =>
6060
ct.ThrowIfCancellationRequested();
6161
6262
return await Get(tipsTable, imagesTable, ct);*/
63-
fallbackTips;
63+
UniTask.FromResult(fallbackTips);
6464

6565
private SceneTips Get(StringTable tipsTable, AssetTable? imagesTable, CancellationToken ct)
6666
{

0 commit comments

Comments
 (0)