feat(task-0006): implement menu restart button and signal coordination
- Update MenuUIViewModel with IMenuRestartSignal dependency and Restart() method - Add RestartButton to MenuUIView with listener management in Initialize/Release - Connect MenuUIView click handler to ViewModel.Restart() callback - Fix race condition in MenuRestartSignal.RequestRestart() by nulling completion source first - Wrap MenuState.WaitAsync() in try-catch for proper view cleanup on cancellation - Update TASK-0006 status to Ready Выполнена задача TASK-0006: реализована кнопка Restart и координация сигналов - Обновлён MenuUIViewModel с зависимостью IMenuRestartSignal и методом Restart() - Добавлена кнопка RestartButton в MenuUIView с управлением слушателями в Initialize/Release - Подключен обработчик кликов MenuUIView к колбэку ViewModel.Restart() - Исправлено состояние гонки в MenuRestartSignal.RequestRestart() путем обнуления completion source - Обёрнут WaitAsync в MenuState в try-catch для корректной очистки view при отмене - Обновлён статус TASK-0006 до Ready
This commit is contained in:
@@ -17,7 +17,9 @@ namespace QuizPleaseTest.Boot.Flow
|
||||
|
||||
public void RequestRestart()
|
||||
{
|
||||
_restartCompletionSource?.TrySetResult();
|
||||
UniTaskCompletionSource restartCompletionSource = _restartCompletionSource;
|
||||
_restartCompletionSource = null;
|
||||
restartCompletionSource?.TrySetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using QuizPleaseTest.Boot.Flow;
|
||||
@@ -19,9 +20,18 @@ namespace QuizPleaseTest.Boot.States
|
||||
|
||||
public async UniTask EnterAsync(CancellationToken ct)
|
||||
{
|
||||
_view.Bind(new MenuUIViewModel());
|
||||
_view.Bind(new MenuUIViewModel(_restartSignal));
|
||||
_view.Initialize();
|
||||
await _restartSignal.WaitAsync(ct);
|
||||
|
||||
try
|
||||
{
|
||||
await _restartSignal.WaitAsync(ct);
|
||||
}
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested)
|
||||
{
|
||||
_view.Release();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask ExitAsync(CancellationToken ct)
|
||||
|
||||
@@ -1,8 +1,39 @@
|
||||
using QuizPleaseTest.Common.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace QuizPleaseTest.Boot.UI
|
||||
{
|
||||
public class MenuUIView : UIView<MenuUIViewModel>
|
||||
{
|
||||
[field: SerializeField] public Button RestartButton { get; private set; }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
if (RestartButton == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RestartButton.onClick.RemoveListener(OnRestartClicked);
|
||||
RestartButton.onClick.AddListener(OnRestartClicked);
|
||||
}
|
||||
|
||||
public override void Release()
|
||||
{
|
||||
if (RestartButton != null)
|
||||
{
|
||||
RestartButton.onClick.RemoveListener(OnRestartClicked);
|
||||
}
|
||||
|
||||
base.Release();
|
||||
}
|
||||
|
||||
private void OnRestartClicked()
|
||||
{
|
||||
ViewModel.Restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
using System;
|
||||
using QuizPleaseTest.Boot.Flow;
|
||||
using QuizPleaseTest.Common.UI;
|
||||
|
||||
namespace QuizPleaseTest.Boot.UI
|
||||
{
|
||||
public class MenuUIViewModel : IUIViewModel
|
||||
{
|
||||
private readonly IMenuRestartSignal _restartSignal;
|
||||
|
||||
public MenuUIViewModel(IMenuRestartSignal restartSignal)
|
||||
{
|
||||
_restartSignal = restartSignal ?? throw new ArgumentNullException(nameof(restartSignal));
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
_restartSignal.RequestRestart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user