210 lines
6.9 KiB
C#
210 lines
6.9 KiB
C#
using Minesweeper.Commands;
|
|
using Minesweeper.Core;
|
|
using Minesweeper.Presentation.Factories;
|
|
using Minesweeper.Presentation.ReadModels;
|
|
using Minesweeper.Presentation.Views;
|
|
|
|
namespace Minesweeper.Presentation.Presenters
|
|
{
|
|
public sealed class GamePresenter : IPresenter
|
|
{
|
|
private readonly IGameCommandDispatcher commandDispatcher;
|
|
private readonly ICellViewFactory cellViewFactory;
|
|
private readonly IGamePauseService pauseService;
|
|
private readonly IGameReadModel readModel;
|
|
private readonly IGameStateService gameStateService;
|
|
private readonly TopPanelPresenter topPanelPresenter;
|
|
private readonly IBoardView boardView;
|
|
private readonly IPauseView pauseView;
|
|
private readonly IResultView resultView;
|
|
private bool boardBuilt;
|
|
|
|
public GamePresenter(IGameCommandDispatcher commandDispatcher, ICellViewFactory cellViewFactory, IGamePauseService pauseService, IGameReadModel readModel, IGameStateService gameStateService, TopPanelPresenter topPanelPresenter, IBoardView boardView, IPauseView pauseView, IResultView resultView)
|
|
{
|
|
this.commandDispatcher = commandDispatcher;
|
|
this.cellViewFactory = cellViewFactory;
|
|
this.pauseService = pauseService;
|
|
this.readModel = readModel;
|
|
this.gameStateService = gameStateService;
|
|
this.topPanelPresenter = topPanelPresenter;
|
|
this.boardView = boardView;
|
|
this.pauseView = pauseView;
|
|
this.resultView = resultView;
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
boardView.CellPressStarted += OnCellPressStarted;
|
|
boardView.CellPressEnded += OnCellPressEnded;
|
|
boardView.PauseRequested += OnPauseRequested;
|
|
boardView.CellOpenRequested += OnCellOpenRequested;
|
|
boardView.CellFlagRequested += OnCellFlagRequested;
|
|
pauseView.RestartRequested += OnRestartRequested;
|
|
pauseView.ResumeRequested += OnResumeRequested;
|
|
pauseView.GoToMenuRequested += OnGoToMenuRequested;
|
|
resultView.RestartRequested += OnRestartRequested;
|
|
resultView.GoToMenuRequested += OnGoToMenuRequested;
|
|
gameStateService.StateChanged += OnStateChanged;
|
|
pauseService.PauseChanged += OnPauseChanged;
|
|
OnStateChanged(gameStateService.Current);
|
|
OnPauseChanged(pauseService.IsPaused);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
boardView.CellPressStarted -= OnCellPressStarted;
|
|
boardView.CellPressEnded -= OnCellPressEnded;
|
|
boardView.PauseRequested -= OnPauseRequested;
|
|
boardView.CellOpenRequested -= OnCellOpenRequested;
|
|
boardView.CellFlagRequested -= OnCellFlagRequested;
|
|
pauseView.RestartRequested -= OnRestartRequested;
|
|
pauseView.ResumeRequested -= OnResumeRequested;
|
|
pauseView.GoToMenuRequested -= OnGoToMenuRequested;
|
|
resultView.RestartRequested -= OnRestartRequested;
|
|
resultView.GoToMenuRequested -= OnGoToMenuRequested;
|
|
gameStateService.StateChanged -= OnStateChanged;
|
|
pauseService.PauseChanged -= OnPauseChanged;
|
|
}
|
|
|
|
private void OnCellOpenRequested(int x, int y)
|
|
{
|
|
topPanelPresenter.SetCellPressActive(false);
|
|
commandDispatcher.Dispatch(new OpenCellCommand(x, y));
|
|
RefreshChangedCellsOrBoard();
|
|
topPanelPresenter.RefreshCounters();
|
|
UpdateBoardInput();
|
|
}
|
|
|
|
private void OnCellFlagRequested(int x, int y)
|
|
{
|
|
commandDispatcher.Dispatch(new ToggleFlagCommand(x, y));
|
|
RefreshChangedCellsOrBoard();
|
|
topPanelPresenter.RefreshCounters();
|
|
UpdateBoardInput();
|
|
}
|
|
|
|
private void OnCellPressStarted()
|
|
{
|
|
topPanelPresenter.SetCellPressActive(true);
|
|
}
|
|
|
|
private void OnCellPressEnded()
|
|
{
|
|
topPanelPresenter.SetCellPressActive(false);
|
|
}
|
|
|
|
private void OnStateChanged(GameState state)
|
|
{
|
|
if (state == GameState.FieldSelection)
|
|
{
|
|
boardBuilt = false;
|
|
boardView.Hide();
|
|
pauseView.Hide();
|
|
resultView.Hide();
|
|
return;
|
|
}
|
|
|
|
boardView.Show();
|
|
|
|
if (state == GameState.Won || state == GameState.Lost)
|
|
{
|
|
pauseView.Hide();
|
|
resultView.Show(state);
|
|
}
|
|
else
|
|
{
|
|
resultView.Hide();
|
|
}
|
|
|
|
if (!boardBuilt || state == GameState.Preparing)
|
|
{
|
|
RebuildBoard();
|
|
}
|
|
else
|
|
{
|
|
RefreshBoard();
|
|
}
|
|
|
|
UpdateBoardInput();
|
|
}
|
|
|
|
private void OnPauseChanged(bool isPaused)
|
|
{
|
|
if (isPaused && CanPause(gameStateService.Current))
|
|
{
|
|
pauseView.Show();
|
|
}
|
|
else
|
|
{
|
|
pauseView.Hide();
|
|
}
|
|
|
|
UpdateBoardInput();
|
|
}
|
|
|
|
private void RebuildBoard()
|
|
{
|
|
var cells = readModel.GetCells();
|
|
boardView.Rebuild(cells, readModel.Width, readModel.Height, cellViewFactory, IsFinalState());
|
|
boardBuilt = true;
|
|
topPanelPresenter.RefreshCounters();
|
|
UpdateBoardInput();
|
|
}
|
|
|
|
private void RefreshBoard()
|
|
{
|
|
boardView.Refresh(readModel.GetCells(), IsFinalState());
|
|
}
|
|
|
|
private void RefreshChangedCellsOrBoard()
|
|
{
|
|
if (IsFinalState())
|
|
{
|
|
RefreshBoard();
|
|
return;
|
|
}
|
|
|
|
boardView.RefreshCells(readModel.GetChangedCells(), false);
|
|
}
|
|
|
|
private bool IsFinalState()
|
|
{
|
|
var state = gameStateService.Current;
|
|
return state == GameState.Lost || state == GameState.Won;
|
|
}
|
|
|
|
private void UpdateBoardInput()
|
|
{
|
|
var state = gameStateService.Current;
|
|
boardView.SetInputEnabled(!pauseService.IsPaused && (state == GameState.Preparing || state == GameState.Playing));
|
|
}
|
|
|
|
private void OnRestartRequested()
|
|
{
|
|
commandDispatcher.Dispatch(new RestartCommand());
|
|
RebuildBoard();
|
|
topPanelPresenter.RefreshCounters();
|
|
}
|
|
|
|
private void OnGoToMenuRequested()
|
|
{
|
|
commandDispatcher.Dispatch(new GoToMenuCommand());
|
|
}
|
|
|
|
private void OnResumeRequested()
|
|
{
|
|
commandDispatcher.Dispatch(new ResumeCommand());
|
|
}
|
|
|
|
private void OnPauseRequested()
|
|
{
|
|
commandDispatcher.Dispatch(new PauseCommand());
|
|
}
|
|
|
|
private static bool CanPause(GameState state)
|
|
{
|
|
return state == GameState.Preparing || state == GameState.Playing;
|
|
}
|
|
}
|
|
}
|