Commit 4fa42886 authored by ElderLich's avatar ElderLich

Bug Fix: Fix deck selector CancellationTokenSource disposed exception on tab switch

Updated SelectionButton_DeckSelector cancellation lifecycle to safely cancel/dispose refresh tokens, prevent reuse of disposed CTS, and handle expected async cancellation during rapid Online toggle/page disable flows.
parent c62b4d2b
...@@ -2,6 +2,7 @@ using Cysharp.Threading.Tasks; ...@@ -2,6 +2,7 @@ using Cysharp.Threading.Tasks;
using DG.Tweening; using DG.Tweening;
using MDPro3.Duel.YGOSharp; using MDPro3.Duel.YGOSharp;
using MDPro3.Utility; using MDPro3.Utility;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
...@@ -101,8 +102,7 @@ namespace MDPro3.UI ...@@ -101,8 +102,7 @@ namespace MDPro3.UI
protected override void OnDisable() protected override void OnDisable()
{ {
base.OnDisable(); base.OnDisable();
cts?.Cancel(); DisposeRefreshCts();
cts?.Dispose();
} }
public void SetConfigDeck(string hint) public void SetConfigDeck(string hint)
...@@ -147,55 +147,104 @@ namespace MDPro3.UI ...@@ -147,55 +147,104 @@ namespace MDPro3.UI
{ {
refreshed = false; refreshed = false;
cts = new(); DisposeRefreshCts();
await UniTask.WaitUntil(() => Items.initialized, cancellationToken : cts.Token); var refreshCts = new CancellationTokenSource();
await UniTask.WaitWhile(() => TextureManager.container == null, cancellationToken: cts.Token); cts = refreshCts;
var token = refreshCts.Token;
ImageDeck.color = Color.clear; try
ImageCard0.color =Color.clear;
ImageCard1.color = Color.clear;
ImageCard2.color = Color.clear;
ImageDeck.sprite = await Program.items.LoadDeckCaseIconAsync(deckCase, "_L_SD");
ImageDeck.color = Color.white;
if (card0 == 0)
{ {
ImageCard0.texture = null; await UniTask.WaitUntil(() => Items.initialized, cancellationToken: token);
ImageCard0.material = await ABLoader.LoadProtectorMaterial(protector.ToString(), cts.Token); await UniTask.WaitWhile(() => TextureManager.container == null, cancellationToken: token);
ImageDeck.color = Color.clear;
ImageCard0.color =Color.clear;
ImageCard1.color = Color.clear;
ImageCard2.color = Color.clear;
ImageDeck.sprite = await Program.items.LoadDeckCaseIconAsync(deckCase, "_L_SD");
ImageDeck.color = Color.white;
if (card0 == 0)
{
ImageCard0.texture = null;
ImageCard0.material = await ABLoader.LoadProtectorMaterial(protector.ToString(), token);
}
else
{
ImageCard0.material = MaterialLoader.GetCardMaterial(card0);
ImageCard0.texture = await CardImageLoader.LoadCardAsync(card0, true);
}
ImageCard0.color = Color.white;
if (card1 == 0)
{
ImageCard1.texture = null;
ImageCard1.material = await ABLoader.LoadProtectorMaterial(protector.ToString(), token);
}
else
{
ImageCard1.material = MaterialLoader.GetCardMaterial(card1);
ImageCard1.texture = await CardImageLoader.LoadCardAsync(card1, true);
}
ImageCard1.color = Color.white;
if (card2 == 0)
{
ImageCard2.texture = null;
ImageCard2.material = await ABLoader.LoadProtectorMaterial(protector.ToString(), token);
}
else
{
ImageCard2.material = MaterialLoader.GetCardMaterial(card2);
ImageCard2.texture = await CardImageLoader.LoadCardAsync(card2, true);
}
ImageCard2.color = Color.white;
refreshed = true;
} }
else catch (OperationCanceledException)
{ {
ImageCard0.material = MaterialLoader.GetCardMaterial(card0);
ImageCard0.texture = await CardImageLoader.LoadCardAsync(card0, true);
} }
ImageCard0.color = Color.white; finally
{
if (ReferenceEquals(cts, refreshCts))
{
cts = null;
try
{
refreshCts.Dispose();
}
catch (ObjectDisposedException)
{
}
}
}
}
if (card1 == 0) private void DisposeRefreshCts()
{
var refreshCts = cts;
if (refreshCts == null)
return;
cts = null;
try
{ {
ImageCard1.texture = null; refreshCts.Cancel();
ImageCard1.material = await ABLoader.LoadProtectorMaterial(protector.ToString(), cts.Token);
} }
else catch (ObjectDisposedException)
{ {
ImageCard1.material = MaterialLoader.GetCardMaterial(card1);
ImageCard1.texture = await CardImageLoader.LoadCardAsync(card1, true);
} }
ImageCard1.color = Color.white;
if (card2 == 0) try
{ {
ImageCard2.texture = null; refreshCts.Dispose();
ImageCard2.material = await ABLoader.LoadProtectorMaterial(protector.ToString(), cts.Token);
} }
else catch (ObjectDisposedException)
{ {
ImageCard2.material = MaterialLoader.GetCardMaterial(card2);
ImageCard2.texture = await CardImageLoader.LoadCardAsync(card2, true);
} }
ImageCard2.color = Color.white;
refreshed = true;
} }
protected override void CallHoverOnEvent() protected override void CallHoverOnEvent()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment