video and difficulty based sorting fixes

This commit is contained in:
Savya Bikram Shah
2026-07-06 14:37:59 +05:45
parent 7b90efca98
commit dfd76d187f
4 changed files with 102 additions and 25 deletions

View File

@@ -1,3 +1,4 @@
using System;
using System.Threading; using System.Threading;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using Darkmatter.Core.Contracts.Features.Progression; using Darkmatter.Core.Contracts.Features.Progression;
@@ -14,6 +15,10 @@ namespace Darkmatter.Features.AppBoot.Flow
{ {
public class AppBootFlow : IAsyncStartable public class AppBootFlow : IAsyncStartable
{ {
private const int IntroPrepareTimeoutMs = 3000;
private const float IntroMinimumFallbackSeconds = 6f;
private const float IntroFallbackPaddingSeconds = 2f;
private readonly AppBootSceneRefs _sceneRefs; private readonly AppBootSceneRefs _sceneRefs;
private readonly ISceneService _sceneService; private readonly ISceneService _sceneService;
private readonly IEventBus _eventBus; private readonly IEventBus _eventBus;
@@ -42,30 +47,84 @@ namespace Darkmatter.Features.AppBoot.Flow
Screen.sleepTimeout = SleepTimeout.NeverSleep; Screen.sleepTimeout = SleepTimeout.NeverSleep;
await _progression.LoadAsync(); await _progression.LoadAsync();
var tcs = new UniTaskCompletionSource();
var player = _sceneRefs.IntroVideoPlayer; var player = _sceneRefs.IntroVideoPlayer;
var introTask = PlayIntroAsync(player, cancellation);
void OnDone(VideoPlayer vp)
{
vp.loopPointReached -= OnDone;
tcs.TrySetResult();
}
player.loopPointReached += OnDone;
player.Play();
_eventBus.Publish(new IntroStartedSignal());
await _sceneService.LoadSceneAsync(nameof(GameScene.MainMenu), null, cancellation); await _sceneService.LoadSceneAsync(nameof(GameScene.MainMenu), null, cancellation);
await tcs.Task.AttachExternalCancellation(cancellation); await introTask.AttachExternalCancellation(cancellation);
CleanupIntro(player);
if (_sceneRefs.IntroCanvas != null)
UnityEngine.Object.Destroy(_sceneRefs.IntroCanvas.gameObject);
_eventBus.Publish(new IntroCompletedSignal());
}
private async UniTask PlayIntroAsync(VideoPlayer player, CancellationToken cancellation)
{
if (player == null)
return;
var prepared = new UniTaskCompletionSource();
var completed = new UniTaskCompletionSource();
void OnPrepared(VideoPlayer vp) => prepared.TrySetResult();
void OnDone(VideoPlayer vp) => completed.TrySetResult();
void OnError(VideoPlayer vp, string message)
{
Debug.LogWarning($"[AppBootFlow] Intro video error: {message}");
completed.TrySetResult();
prepared.TrySetResult();
}
player.prepareCompleted += OnPrepared;
player.loopPointReached += OnDone;
player.errorReceived += OnError;
try
{
if (!player.isPrepared)
{
player.Prepare();
await UniTask.WhenAny(
prepared.Task,
UniTask.Delay(IntroPrepareTimeoutMs, cancellationToken: cancellation));
}
player.Play();
_eventBus.Publish(new IntroStartedSignal());
await UniTask.WhenAny(
completed.Task,
UniTask.Delay(GetIntroFallbackTimeout(player), cancellationToken: cancellation));
}
finally
{
player.prepareCompleted -= OnPrepared;
player.loopPointReached -= OnDone;
player.errorReceived -= OnError;
}
}
private static TimeSpan GetIntroFallbackTimeout(VideoPlayer player)
{
var length = player != null && player.length > 0d
? (float)player.length
: IntroMinimumFallbackSeconds;
return TimeSpan.FromSeconds(Mathf.Max(IntroMinimumFallbackSeconds, length + IntroFallbackPaddingSeconds));
}
private static void CleanupIntro(VideoPlayer player)
{
if (player == null)
return;
player.Stop(); player.Stop();
var rt = player.targetTexture; var rt = player.targetTexture;
if (rt != null) rt.Release(); if (rt != null) rt.Release();
UnityEngine.Object.Destroy(player.gameObject);
if (_sceneRefs.IntroCanvas != null)
Object.Destroy(_sceneRefs.IntroCanvas.gameObject);
Object.Destroy(player.gameObject);
_eventBus.Publish(new IntroCompletedSignal());
} }
} }
} }

View File

@@ -13,8 +13,8 @@ namespace Darkmatter.Features.DrawingCatalog
{ {
Id = id; Id = id;
thumbnail.sprite = thumbnailSprite; thumbnail.sprite = thumbnailSprite;
button.onClick.RemoveAllListeners();
button.onClick.AddListener(onClick); button.onClick.AddListener(onClick);
} }
} }
} }

View File

@@ -15,6 +15,7 @@ namespace Darkmatter.Features.DrawingCatalog
private int _currentPage = 0; private int _currentPage = 0;
private int _totalPages = 1; private int _totalPages = 1;
private const int RowCount = 2;
private const int ItemPerPage = 8; //2 rows x 4 columns private const int ItemPerPage = 8; //2 rows x 4 columns
private readonly DrawingCatalogView _view; private readonly DrawingCatalogView _view;
@@ -108,7 +109,7 @@ namespace Darkmatter.Features.DrawingCatalog
private async UniTask RefreshAsync(CancellationToken ct) private async UniTask RefreshAsync(CancellationToken ct)
{ {
var ids = _controller.VisibleIds; var ids = ToFixedRowGridOrder(_controller.VisibleIds);
var vms = new List<CatalogItemVM>(ids.Count); var vms = new List<CatalogItemVM>(ids.Count);
_totalPages = (int)Math.Ceiling(ids.Count / (float)ItemPerPage); _totalPages = (int)Math.Ceiling(ids.Count / (float)ItemPerPage);
@@ -133,6 +134,19 @@ namespace Darkmatter.Features.DrawingCatalog
_eventBus.Publish(new DrawingCatalogReadySignal()); _eventBus.Publish(new DrawingCatalogReadySignal());
} }
private static List<string> ToFixedRowGridOrder(IReadOnlyList<string> ids)
{
var ordered = new List<string>(ids.Count);
for (var row = 0; row < RowCount; row++)
{
for (var index = row; index < ids.Count; index += RowCount)
ordered.Add(ids[index]);
}
return ordered;
}
public void Dispose() public void Dispose()
{ {
_view.OnItemClicked -= OnItemClicked; _view.OnItemClicked -= OnItemClicked;

View File

@@ -62,9 +62,6 @@ namespace Darkmatter.Features.DrawingCatalog
while (_buttons.Count < items.Count) while (_buttons.Count < items.Count)
{ {
var button = Instantiate(buttonPrefab, content); var button = Instantiate(buttonPrefab, content);
var item = items[_buttons.Count];
button.Initialize(item.Id, item.Thumbnail,
() => { OnItemClicked?.Invoke(item.Id); });
_buttons.Add(button); _buttons.Add(button);
} }
@@ -75,6 +72,13 @@ namespace Darkmatter.Features.DrawingCatalog
Destroy(last.gameObject); Destroy(last.gameObject);
} }
for (var i = 0; i < items.Count; i++)
{
var item = items[i];
_buttons[i].Initialize(item.Id, item.Thumbnail,
() => { OnItemClicked?.Invoke(item.Id); });
}
LayoutRebuilder.ForceRebuildLayoutImmediate(content); LayoutRebuilder.ForceRebuildLayoutImmediate(content);
} }