Coverage Summary for Class: GUISocketListener (it.polimi.ingsw.Client.GUI.Listeners)
Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
GUISocketListener |
0%
(0/1)
|
0%
(0/5)
|
0%
(0/18)
|
0%
(0/43)
|
1 package it.polimi.ingsw.Client.GUI.Listeners;
2
3 import it.polimi.ingsw.Client.GUI.Context;
4 import it.polimi.ingsw.Client.GUI.Panels.GameInProgressPanel;
5 import it.polimi.ingsw.Client.GUI.Panels.StartPanel;
6 import it.polimi.ingsw.Controller.Actions.EndTurnOfActionPhase;
7 import it.polimi.ingsw.Controller.Actions.PlayerAction;
8 import it.polimi.ingsw.Misc.Pair;
9 import it.polimi.ingsw.Network.SocketWrapper;
10 import it.polimi.ingsw.Server.Messages.Message;
11 import it.polimi.ingsw.Server.Messages.ServerResponses.*;
12 import it.polimi.ingsw.Server.Messages.ServerResponses.SupportStructures.StatusCode;
13
14 import javax.swing.*;
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.List;
18
19 /**
20 * Handles messages received from server and keep a record of current player's actions executed during its turn
21 */
22 public class GUISocketListener implements Runnable {
23 /**
24 * List of actions executed by current player and their feedbacks
25 */
26 private final List<Pair<PlayerAction, PlayerActionFeedback>> requestAndFeedback = new ArrayList<>();
27 /**
28 * Context received from GameInProgressPanel
29 */
30 private final Context ctx;
31 /**
32 * SocketWrapper used to communicate with Server
33 */
34 private final SocketWrapper sw;
35 /**
36 * JTabbedPane containing all others JPanels
37 */
38 private GameInProgressPanel gameInProgressPanel;
39 /**
40 * Last player's request sent to Server
41 */
42 private PlayerAction playerActionRequest;
43
44
45 /**
46 * Create a new GUIReader
47 *
48 * @param ctx Context containing socket and GUI's window
49 */
50 public GUISocketListener(Context ctx) {
51 this.gameInProgressPanel = null;
52 this.playerActionRequest = null;
53 this.sw = ctx.getSocketWrapper();
54 this.ctx = ctx;
55 }
56
57 /**
58 * Listen for Server's responses and updated window basing on responses
59 */
60 @Override
61 public void run() {
62 while (true) {
63 try {
64 //wait server's response
65 Message input = sw.awaitMessage();
66 switch (input) {
67 case LobbyClosed ignored -> {
68 JOptionPane.showMessageDialog(null, "Lobby was closed by the server.\n" +
69 "Client is disconnecting from the server.", "Lobby closed", JOptionPane.INFORMATION_MESSAGE);
70 //close socket and return to StartPanel
71 sw.close();
72 ctx.getWindow().changeView(new StartPanel(ctx));
73 return;
74 }
75 case ClientDisconnected clientDisconnected ->
76 JOptionPane.showMessageDialog(null, "Client " + clientDisconnected.getLastDisconnectedNickname() +
77 " just disconnected.", "Client disconnected", JOptionPane.INFORMATION_MESSAGE);
78 case ModelUpdated modelUpdated -> {
79 //create a new GameInProgressPanel with updated model
80 this.gameInProgressPanel = new GameInProgressPanel(ctx, modelUpdated.getModel(), this, gameInProgressPanel);
81 ctx.getWindow().changeView(this.gameInProgressPanel);
82 return;
83 }
84 case PlayerActionFeedback playerActionFeedback -> {
85 //create a new Pair with saved player's request and feedback received
86 requestAndFeedback.add(new Pair<>(this.playerActionRequest, playerActionFeedback));
87 //show eventual fail report
88 if (playerActionFeedback.getStatusCode() == StatusCode.Fail)
89 JOptionPane.showMessageDialog(null, playerActionFeedback.getReport());
90 //clear history when endTurn action has been performed by user
91 if (playerActionRequest.getClass().equals(EndTurnOfActionPhase.class) && playerActionFeedback.getStatusCode() == StatusCode.Success) {
92 requestAndFeedback.clear();
93 }
94 playerActionRequest = null;
95 }
96 case GameOver ignored -> {
97 return;
98 }
99 case InvalidRequest ignored ->
100 JOptionPane.showMessageDialog(null, "Your request has not been executed, probably you are trying to play out of turn",
101 "Warning", JOptionPane.INFORMATION_MESSAGE);
102 default -> throw new IllegalStateException("Unexpected value: " + input.getClass());
103 }
104 } catch (Exception e) {
105 JOptionPane.showMessageDialog(null, "Error in the connection with the server", "Error", JOptionPane.INFORMATION_MESSAGE);
106 try {
107 sw.close();
108 } catch (IOException ex) {
109 throw new RuntimeException(ex);
110 }
111 ctx.getWindow().changeView(new StartPanel(ctx));
112 return;
113 }
114 }
115 }
116
117 /**
118 * Save user's request that will be added in history after receiving its feedback
119 *
120 * @param playerActionRequest playerActionRequest to save
121 */
122 public void savePlayerActionRequest(PlayerAction playerActionRequest) {
123 if (this.playerActionRequest == null) {
124 this.playerActionRequest = playerActionRequest;
125 }
126 }
127
128 /**
129 * Check to see if a new {@link it.polimi.ingsw.Server.Messages.Events.Requests.PlayerActionRequest} can be sent to the server
130 * or if the gui should wait before allowing any more actions to be sent
131 *
132 * @return true if the listener is polling for a feedback to a previous player's action, false otherwise
133 */
134 public boolean awaitingPlayerActionFeedback() {
135 return playerActionRequest != null;
136 }
137
138 /**
139 * Count PlayerActions that have received a successful response from Server
140 *
141 * @param playerActionClass PlayerAction's class that will be counted
142 * @return PlayerAction amount that received a successful response from Server
143 */
144 public int getSuccessfulRequestsByType(Class<?> playerActionClass) {
145 List<PlayerActionFeedback> actions = requestAndFeedback.stream().
146 filter(pair -> pair.first().getClass().equals(playerActionClass)).map(Pair::second).toList();
147
148 return (int) actions.stream().filter(playerActionFeedback -> playerActionFeedback.getStatusCode() == StatusCode.Success).count();
149 }
150 }