6601c8ea22
- 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
40 lines
2.2 KiB
Markdown
40 lines
2.2 KiB
Markdown
# TASK-0006: MenuState и Restart
|
||
|
||
## Статус
|
||
|
||
Ready
|
||
|
||
## Цель
|
||
|
||
Реализовать меню с кнопкой `Restart`, которое завершает `MenuState` и возвращает flow к загрузке.
|
||
|
||
## Что сделать
|
||
|
||
- Реализовать `MenuState`.
|
||
- Реализовать `MenuUIView`.
|
||
- Реализовать `MenuUIViewModel` или аналогичный plain C# объект для restart-сигнала.
|
||
- В `MenuState.EnterAsync` показать menu View и ожидать restart.
|
||
- Ожидание restart реализовать через `UniTaskCompletionSource` или аналогичный UniTask-friendly механизм.
|
||
- По нажатию кнопки `Restart` завершать ожидание `MenuState.EnterAsync`.
|
||
- В `MenuState.ExitAsync` release-нуть menu View и очистить подписки/listeners.
|
||
|
||
## Технические требования
|
||
|
||
- Кнопку подключать через `Button.onClick.AddListener(...)`.
|
||
- В `Release()` снимать ровно тот же listener через `RemoveListener(...)`.
|
||
- Не использовать `RemoveAllListeners()` как основной способ очистки.
|
||
- Не использовать анонимную лямбду, которую невозможно симметрично снять.
|
||
- Не переводить state machine напрямую из `MenuUIView`.
|
||
- Restart-событие должно попадать во flow через ViewModel/state, а не через глобальное состояние.
|
||
|
||
## Критерии готовности
|
||
|
||
- `MenuState.EnterAsync` завершается после нажатия `Restart`.
|
||
- После завершения `MenuState` внешний `BootFlowService` запускает `LoadState`.
|
||
- Несколько циклов `Menu -> Restart -> Load -> Menu` не дублируют callbacks.
|
||
- Повторный `Release()` у `MenuUIView` не падает.
|
||
|
||
## Заметки
|
||
|
||
Для кнопки лучше использовать method group или заранее сохраненный delegate. Это упрощает симметричный `AddListener`/`RemoveListener` и снижает риск дублирующихся callbacks.
|