Compare commits

...

1 Commits

Author SHA1 Message Date
Savya Bikram Shah
df43824fb1 Back button bug fix 2026-07-07 15:53:13 +05:45
4 changed files with 1987 additions and 77 deletions

View File

@@ -46,6 +46,7 @@ namespace Darkmatter.Features.GameplayFlow.Systems
private string _templateId; private string _templateId;
private DrawingPhase _phase = DrawingPhase.ShapeBuilding; private DrawingPhase _phase = DrawingPhase.ShapeBuilding;
private bool _allContentReported; private bool _allContentReported;
private bool _navigating;
private float _lastThumbnailTime = float.NegativeInfinity; private float _lastThumbnailTime = float.NegativeInfinity;
private IDisposable _assembledSub; private IDisposable _assembledSub;
@@ -166,12 +167,24 @@ namespace Darkmatter.Features.GameplayFlow.Systems
public async UniTask BackAsync(CancellationToken ct) public async UniTask BackAsync(CancellationToken ct)
{ {
await SaveCurrentAsync(CancellationToken.None); // A second navigation while one runs (e.g. Back pressed during the completion
_loadingScreen.Show(); // animation inside NextAsync) would interleave two saves and two Colorbook loads,
_shapeBuilder.Clear(); // and Clear() would rip the celebration apart mid-flight. First navigation wins.
_coloring.Clear(); if (_navigating) return;
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: ct); _navigating = true;
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: ct); 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) public async UniTask SaveAsync(CancellationToken ct)
@@ -184,48 +197,48 @@ namespace Darkmatter.Features.GameplayFlow.Systems
public async UniTask NextAsync(CancellationToken ct) public async UniTask NextAsync(CancellationToken ct)
{ {
// Drop any debounced autosave so it can't fire during/after the completion if (_navigating) return;
// animation and capture the animation (or an empty paper) into the thumbnail. _navigating = true;
_autosaveCts?.Cancel(); try
_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)
{ {
_allContentReported = true; // Drop any debounced autosave so it can't fire during/after the completion
_bus.Publish(new AllContentCompletedSignal(_progression.CompletedTemplateIds.Count)); // animation and capture the animation (or an empty paper) into the thumbnail.
} _autosaveCts?.Cancel();
_autosaveCts?.Dispose();
_autosaveCts = null;
var nextId = _catalog.GetNextTemplate(_templateId); await SaveCurrentAsync(ct);
if (string.IsNullOrEmpty(nextId)) _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(); _loadingScreen.Show();
_shapeBuilder.Clear(); _shapeBuilder.Clear();
_coloring.Clear(); _coloring.Clear();
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default); await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), 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) private async UniTaskVoid EditAsync(string newTemplateId)
{ {
await SaveCurrentAsync(CancellationToken.None); if (_navigating) return;
_loadingScreen.Show(); _navigating = true;
_shapeBuilder.Clear(); try
_coloring.Clear(); {
await _scenes.LoadSceneAsync(nameof(GameScene.Colorbook), progress: null, cancellationToken: default); await SaveCurrentAsync(CancellationToken.None);
await _scenes.UnloadSceneAsync(nameof(GameScene.Gameplay), progress: null, cancellationToken: default); _loadingScreen.Show();
_bus.Publish(new DrawingSelectedSignal(newTemplateId)); _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) private async UniTaskVoid DebouncedAutosaveAsync(CancellationToken ct)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long