Back button bug fix

This commit is contained in:
Savya Bikram Shah
2026-07-07 15:53:13 +05:45
parent e167af11fd
commit df43824fb1
4 changed files with 1987 additions and 77 deletions

View File

@@ -46,6 +46,7 @@ namespace Darkmatter.Features.GameplayFlow.Systems
private string _templateId;
private DrawingPhase _phase = DrawingPhase.ShapeBuilding;
private bool _allContentReported;
private bool _navigating;
private float _lastThumbnailTime = float.NegativeInfinity;
private IDisposable _assembledSub;
@@ -166,12 +167,24 @@ namespace Darkmatter.Features.GameplayFlow.Systems
public async UniTask BackAsync(CancellationToken ct)
{
await SaveCurrentAsync(CancellationToken.None);
_loadingScreen.Show();
_shapeBuilder.Clear();
_coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: ct);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: ct);
// A second navigation while one runs (e.g. Back pressed during the completion
// animation inside NextAsync) would interleave two saves and two Colorbook loads,
// and Clear() would rip the celebration apart mid-flight. First navigation wins.
if (_navigating) return;
_navigating = true;
try
{
await SaveCurrentAsync(CancellationToken.None);
_loadingScreen.Show();
_shapeBuilder.Clear();
_coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: ct);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: ct);
}
finally
{
_navigating = false;
}
}
public async UniTask SaveAsync(CancellationToken ct)
@@ -184,48 +197,48 @@ namespace Darkmatter.Features.GameplayFlow.Systems
public async UniTask NextAsync(CancellationToken ct)
{
// Drop any debounced autosave so it can't fire during/after the completion
// animation and capture the animation (or an empty paper) into the thumbnail.
_autosaveCts?.Cancel();
_autosaveCts?.Dispose();
_autosaveCts = null;
await SaveCurrentAsync(ct);
_refs.Confetti.Play();
_sfx.Play(SfxId.FireWorkLaunch);
_sfx.Play(SfxId.LevelComplete);
await _coloring.PlayCompletionAnimationAsync(ct);
_progression.MarkCompleted(_templateId);
var progressAfter = _progression.GetProgress(_templateId);
_bus.Publish(new DrawingCompletedSignal(_templateId, progressAfter?.completionCount ?? 1));
// Player has cleared the whole catalog → surface the "ran out of content" milestone. Guarded
// per session here; analytics dedupes it to once-ever.
if (!_allContentReported &&
_catalog.AllTemplateIds.Count > 0 &&
_progression.CompletedTemplateIds.Count >= _catalog.AllTemplateIds.Count)
if (_navigating) return;
_navigating = true;
try
{
_allContentReported = true;
_bus.Publish(new AllContentCompletedSignal(_progression.CompletedTemplateIds.Count));
}
// Drop any debounced autosave so it can't fire during/after the completion
// animation and capture the animation (or an empty paper) into the thumbnail.
_autosaveCts?.Cancel();
_autosaveCts?.Dispose();
_autosaveCts = null;
var nextId = _catalog.GetNextTemplate(_templateId);
if (string.IsNullOrEmpty(nextId))
{
await SaveCurrentAsync(ct);
_refs.Confetti.Play();
_sfx.Play(SfxId.FireWorkLaunch);
_sfx.Play(SfxId.LevelComplete);
await _coloring.PlayCompletionAnimationAsync(ct);
_progression.MarkCompleted(_templateId);
var progressAfter = _progression.GetProgress(_templateId);
_bus.Publish(new DrawingCompletedSignal(_templateId, progressAfter?.completionCount ?? 1));
// Player has cleared the whole catalog → surface the "ran out of content" milestone. Guarded
// per session here; analytics dedupes it to once-ever.
if (!_allContentReported &&
_catalog.AllTemplateIds.Count > 0 &&
_progression.CompletedTemplateIds.Count >= _catalog.AllTemplateIds.Count)
{
_allContentReported = true;
_bus.Publish(new AllContentCompletedSignal(_progression.CompletedTemplateIds.Count));
}
var nextId = _catalog.GetNextTemplate(_templateId);
_loadingScreen.Show();
_shapeBuilder.Clear();
_coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: default);
return;
if (!string.IsNullOrEmpty(nextId))
_bus.Publish(new DrawingSelectedSignal(nextId));
}
finally
{
_navigating = false;
}
_loadingScreen.Show();
_shapeBuilder.Clear();
_coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: default);
_bus.Publish(new DrawingSelectedSignal(nextId));
}
@@ -270,13 +283,22 @@ namespace Darkmatter.Features.GameplayFlow.Systems
private async UniTaskVoid EditAsync(string newTemplateId)
{
await SaveCurrentAsync(CancellationToken.None);
_loadingScreen.Show();
_shapeBuilder.Clear();
_coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: default);
_bus.Publish(new DrawingSelectedSignal(newTemplateId));
if (_navigating) return;
_navigating = true;
try
{
await SaveCurrentAsync(CancellationToken.None);
_loadingScreen.Show();
_shapeBuilder.Clear();
_coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: default);
_bus.Publish(new DrawingSelectedSignal(newTemplateId));
}
finally
{
_navigating = false;
}
}
private async UniTaskVoid DebouncedAutosaveAsync(CancellationToken ct)