Added empty data sources, to be used by VisualiserRace.
Created FrameRateTracker which can be used to track framerate. Updated RequestToJoinEnum and JoinAcceptanceEnum to match the agreed connection API. Added AssignPlayerBoat message, which is used internally on the client to assign the player a source ID once they have connected. Fixed some race conditions in the MessageRouter. Updated ConnectionAcceptor.CheckClientConnection to wait slightly longer before removing connection (there was a slight race condition before). Race no longer has a reference to LatestMessages. LatestMessages no longer has specific messages types in it. Created RaceState class, which contains the state that is shared between VisualiserRaceState and MockRaceState (currently only used on visualiser). Split VisualiserRace into VisualiserRaceState and VisualiserRaceService. Added the VisualiserRace commands (BoatLocatonCommand, RaceStatusCommand, etc...). Slightly increased the preferred width of race.fxml table columns. issues #27 #37 #35 #story[1095]
This commit is contained in:
@@ -147,11 +147,27 @@ public class ConnectionToServer implements RunnableWithFramePeriod {
|
||||
//Send them the source ID.
|
||||
RequestToJoin requestToJoin = new RequestToJoin(requestType);
|
||||
|
||||
outgoingMessages.put(requestToJoin);
|
||||
send(requestToJoin);
|
||||
|
||||
connectionState = ConnectionToServerState.REQUEST_SENT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a given message to the server, via the {@link #outgoingMessages} queue.
|
||||
* @param message Message to send.
|
||||
* @throws InterruptedException Thrown if thread is interrupted while sending message.
|
||||
*/
|
||||
public void send(AC35Data message) throws InterruptedException {
|
||||
outgoingMessages.put(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type of join request that was made.
|
||||
* @return Type of join request made.
|
||||
*/
|
||||
public RequestToJoinEnum getRequestType() {
|
||||
return requestType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,20 @@ package visualiser.network;
|
||||
|
||||
|
||||
import mock.model.commandFactory.Command;
|
||||
import mock.model.commandFactory.CompositeCommand;
|
||||
import network.MessageRouters.MessageRouter;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.MessageType;
|
||||
import network.Messages.Enums.RequestToJoinEnum;
|
||||
import network.Messages.JoinAcceptance;
|
||||
import network.Messages.LatestMessages;
|
||||
import network.StreamRelated.MessageDeserialiser;
|
||||
import network.StreamRelated.MessageSerialiser;
|
||||
import shared.model.RunnableWithFramePeriod;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
import visualiser.model.VisualiserRaceController;
|
||||
import visualiser.enums.ConnectionToServerState;
|
||||
import visualiser.gameController.ControllerClient;
|
||||
import visualiser.model.VisualiserRaceState;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
@@ -23,7 +25,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This class handles the client-server connection handshake, and creation of VisualiserInput and ControllerClient.
|
||||
* This class handles the client-server connection handshake.
|
||||
*/
|
||||
public class ServerConnection implements RunnableWithFramePeriod {
|
||||
|
||||
@@ -32,16 +34,8 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
*/
|
||||
private Socket socket;
|
||||
|
||||
/**
|
||||
* The source ID that has been allocated to the client.
|
||||
*/
|
||||
private int allocatedSourceID = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Latest snapshot of the race, received from the server.
|
||||
*/
|
||||
private LatestMessages latestMessages;
|
||||
|
||||
|
||||
/**
|
||||
@@ -122,6 +116,16 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
private Thread heartBeatControllerThread;
|
||||
|
||||
|
||||
/**
|
||||
* This is the race we are modelling.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRaceState;
|
||||
|
||||
/**
|
||||
* The CompositeCommand to place race commands in.
|
||||
*/
|
||||
private CompositeCommand raceCommands;
|
||||
|
||||
|
||||
/**
|
||||
* Used to convert incoming messages into a race snapshot.
|
||||
@@ -130,7 +134,7 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
/**
|
||||
* The thread {@link #visualiserRaceController} runs on.
|
||||
*/
|
||||
private Thread visualiserInputThread;
|
||||
private Thread visualiserRaceControllerThread;
|
||||
|
||||
|
||||
|
||||
@@ -138,13 +142,15 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
/**
|
||||
* Creates a server connection, using a given socket.
|
||||
* @param socket The socket which connects to the client.
|
||||
* @param latestMessages Latest race snapshot to send to client.
|
||||
* @param visualiserRaceState The race for the {@link VisualiserRaceController} to send commands to.
|
||||
* @param raceCommands The CompositeCommand to place race commands in.
|
||||
* @param requestType The type of join request to make.
|
||||
* @throws IOException Thrown if there is a problem with the client socket.
|
||||
*/
|
||||
public ServerConnection(Socket socket, LatestMessages latestMessages, RequestToJoinEnum requestType) throws IOException {
|
||||
public ServerConnection(Socket socket, VisualiserRaceState visualiserRaceState, CompositeCommand raceCommands, RequestToJoinEnum requestType) throws IOException {
|
||||
this.socket = socket;
|
||||
this.latestMessages = latestMessages;
|
||||
this.visualiserRaceState = visualiserRaceState;
|
||||
this.raceCommands = raceCommands;
|
||||
|
||||
createMessageSerialiser(socket);
|
||||
createMessageDeserialiser(socket);
|
||||
@@ -205,6 +211,15 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
this.connectionToServerControllerThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes connection message related routes from the router.
|
||||
* This is called after the client-server connection is properly established, so that any future (erroneous) connection messages get ignored.
|
||||
*/
|
||||
private void removeConnectionRoutes() {
|
||||
this.messageRouter.removeRoute(MessageType.JOIN_ACCEPTANCE);
|
||||
this.messageRouter.removeRoute(MessageType.REQUEST_TO_JOIN);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the {@link #messageSerialiser} and starts its thread.
|
||||
@@ -234,7 +249,7 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
|
||||
|
||||
/**
|
||||
* Creates the {@link #heartBeatService} and {@link #heartBeatController} and starts its thread.
|
||||
* Creates the {@link #heartBeatService} and {@link #heartBeatController} and starts their threads.
|
||||
*/
|
||||
private void createHeartBeatService() {
|
||||
|
||||
@@ -260,14 +275,16 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the {@link #visualiserRaceController} and starts its thread.
|
||||
*/
|
||||
private void createVisualiserRaceController() {
|
||||
|
||||
private void createVisualiserRace() {
|
||||
|
||||
//VisualiserRaceController receives messages, and places commands on the race's command queue.
|
||||
BlockingQueue<AC35Data> incomingMessages = new LinkedBlockingQueue<>();
|
||||
this.visualiserRaceController = new VisualiserRaceController(incomingMessages, visualiserRaceState, raceCommands);
|
||||
|
||||
this.visualiserRaceController = new VisualiserRaceController(latestMessages, incomingMessages);
|
||||
this.visualiserInputThread = new Thread(visualiserRaceController, "ServerConnection()->VisualiserInput thread " + visualiserRaceController);
|
||||
this.visualiserInputThread.start();
|
||||
|
||||
//Routes.
|
||||
this.messageRouter.addRoute(MessageType.BOATLOCATION, incomingMessages);
|
||||
@@ -281,15 +298,19 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
this.messageRouter.addRoute(MessageType.YACHTEVENTCODE, incomingMessages);
|
||||
this.messageRouter.addRoute(MessageType.MARKROUNDING, incomingMessages);
|
||||
this.messageRouter.addRoute(MessageType.XMLMESSAGE, incomingMessages);
|
||||
this.messageRouter.removeDefaultRoute();
|
||||
this.messageRouter.addRoute(MessageType.ASSIGN_PLAYER_BOAT, incomingMessages);
|
||||
this.messageRouter.removeDefaultRoute(); //We no longer want to keep un-routed messages.
|
||||
|
||||
//TODO create VisualiserRace here or somewhere else?
|
||||
|
||||
//Start the above on a new thread.
|
||||
|
||||
this.visualiserRaceControllerThread = new Thread(visualiserRaceController, "ServerConnection()->VisualiserRaceController thread " + visualiserRaceController);
|
||||
this.visualiserRaceControllerThread.start();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO create input controller here. RaceController should query for it, if it exists.
|
||||
private void createPlayerInputController() {
|
||||
|
||||
this.messageRouter.addRoute(MessageType.BOATACTION, messageSerialiser.getMessagesToSend());
|
||||
@@ -342,16 +363,17 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
*/
|
||||
private void connected() {
|
||||
|
||||
JoinAcceptance joinAcceptance = connectionToServer.getJoinAcceptance();
|
||||
|
||||
allocatedSourceID = joinAcceptance.getSourceID();
|
||||
|
||||
|
||||
createHeartBeatService();
|
||||
|
||||
createVisualiserRace();
|
||||
createVisualiserRaceController();
|
||||
|
||||
createPlayerInputController();
|
||||
if (connectionToServer.getRequestType() == RequestToJoinEnum.PARTICIPANT) {
|
||||
createPlayerInputController();
|
||||
}
|
||||
|
||||
|
||||
//We no longer want connection messages to be accepted.
|
||||
removeConnectionRoutes();
|
||||
|
||||
|
||||
//We interrupt as this thread's run() isn't needed anymore.
|
||||
@@ -403,13 +425,7 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
return controllerClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source ID that has been allocated to the client.
|
||||
* @return Source ID allocated to the client. 0 if it hasn't been allocated.
|
||||
*/
|
||||
public int getAllocatedSourceID() {
|
||||
return allocatedSourceID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -447,10 +463,12 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
||||
}
|
||||
|
||||
|
||||
if (this.visualiserInputThread != null) {
|
||||
this.visualiserInputThread.interrupt();
|
||||
if (this.visualiserRaceControllerThread != null) {
|
||||
this.visualiserRaceControllerThread.interrupt();
|
||||
}
|
||||
//TODO visualiser race?
|
||||
|
||||
|
||||
|
||||
//TODO input controller?
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user