package chess.controller.event; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; import chess.controller.commands.PromoteCommand.PromoteType; import chess.model.Color; import chess.model.Coordinate; import chess.model.Move; /** * Create a thread in which the notifications such as Move Not Allowed, Check, Checkmate, Promotion, Surrender, etc. will be sent to update the players. */ public class AsyncGameDispatcher extends GameDispatcher { private final List listeners; private final ExecutorService executor; public AsyncGameDispatcher() { this.listeners = new ArrayList<>(); this.executor = Executors.newSingleThreadExecutor(); } @Override public void addListener(GameListener listener) { this.listeners.add(listener); } private void asyncForEachCall(Consumer func) { this.executor.execute(() -> this.listeners.forEach(func)); } @Override public void onPlayerTurn(Color color, boolean undone) { asyncForEachCall((l) -> l.onPlayerTurn(color, undone)); } @Override public void onWin(Color color) { asyncForEachCall((l) -> l.onWin(color)); } @Override public void onKingInCheck() { asyncForEachCall((l) -> l.onKingInCheck()); } @Override public void onKingInMat() { asyncForEachCall((l) -> l.onKingInMat()); } @Override public void onPatSituation() { asyncForEachCall((l) -> l.onPatSituation()); } @Override public void onSurrender(Color color) { asyncForEachCall((l) -> l.onSurrender(color)); } @Override public void onGameStart() { asyncForEachCall((l) -> l.onGameStart()); } @Override public void onPromotePawn(Coordinate pieceCoords) { asyncForEachCall((l) -> l.onPromotePawn(pieceCoords)); } @Override public void onBoardUpdate() { asyncForEachCall((l) -> l.onBoardUpdate()); } @Override public void onGameEnd() { asyncForEachCall((l) -> l.onGameEnd()); } @Override public void onMove(Move move, boolean captured) { asyncForEachCall((l) -> l.onMove(move, captured)); } @Override public void onMoveNotAllowed(Move move) { asyncForEachCall((l) -> l.onMoveNotAllowed(move)); } @Override public void onDraw() { asyncForEachCall((l) -> l.onDraw()); } @Override public void onCastling(boolean bigCastling, Move kingMove, Move rookMove) { asyncForEachCall((l) -> l.onCastling(bigCastling, kingMove, rookMove)); } @Override public void onPawnPromoted(PromoteType promotion, Coordinate coordinate) { asyncForEachCall((l) -> l.onPawnPromoted(promotion, coordinate)); } @Override public void close() { this.executor.shutdown(); } }