import 'dart:developer'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:mchess/chess_bloc/chess_bloc.dart'; import 'package:mchess/chess_bloc/chess_events.dart'; import 'package:mchess/chess_bloc/promotion_bloc.dart'; import 'package:mchess/utils/chess_utils.dart'; class TapBloc extends Bloc { static final TapBloc _instance = TapBloc._internal(); static TapBloc getInstance() { return _instance; } factory TapBloc() { return _instance; } TapBloc._internal() : super(TapState.init()) { on(handleTap); on(cancelTap); } void handleTap(SquareTappedEvent event, Emitter emit) { ChessCoordinate? firstTappedSquare, secondTappedSquare; ChessPiece? piece; if (ChessBloc.myColor != ChessBloc.turnColor) return; if (state.firstSquareTapped == null) { //first tap if (event.pieceOnSquare == null) return; if (event.pieceOnSquare != null && ChessBloc.myColor != event.pieceOnSquare!.color) return; firstTappedSquare = event.tapped; piece = event.pieceOnSquare; } else { //second tap if (event.pieceOnSquare?.color == ChessBloc.myColor) { emit(TapState( firstSquareTapped: event.tapped, pieceOnFirstTappedSquare: event.pieceOnSquare, secondSquareTapped: null)); return; } secondTappedSquare = event.tapped; } if (state.firstSquareTapped != null && state.firstSquareTapped != event.tapped) { if (isPromotionMove( state.pieceOnFirstTappedSquare!.pieceClass, ChessBloc.myColor!, event.tapped, )) { PromotionBloc().add(PawnMovedToPromotionField( move: ChessMove(from: state.firstSquareTapped!, to: event.tapped), colorMoved: ChessBloc.myColor!)); emit(TapState.init()); return; } else { ChessBloc().add(OwnPieceMoved( startSquare: state.firstSquareTapped!, endSquare: event.tapped)); emit(TapState.init()); return; } } log("handleTap() in TapBloc is called"); emit(TapState( firstSquareTapped: firstTappedSquare, pieceOnFirstTappedSquare: piece, secondSquareTapped: secondTappedSquare)); } void cancelTap(CancelTapEvent event, Emitter emit) { emit(TapState.init()); } } abstract class TapEvent {} class SquareTappedEvent extends TapEvent { ChessCoordinate tapped; ChessPiece? pieceOnSquare; SquareTappedEvent({required this.tapped, required this.pieceOnSquare}); } class CancelTapEvent extends TapEvent {} class TapState { ChessCoordinate? firstSquareTapped; ChessPiece? pieceOnFirstTappedSquare; ChessCoordinate? secondSquareTapped; TapState( {required this.firstSquareTapped, required this.pieceOnFirstTappedSquare, required this.secondSquareTapped}); factory TapState.init() { return TapState( firstSquareTapped: null, pieceOnFirstTappedSquare: null, secondSquareTapped: null); } }