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:
@@ -1,6 +1,11 @@
|
||||
package visualiser.model;
|
||||
|
||||
import mock.exceptions.CommandConstructionException;
|
||||
import mock.model.commandFactory.Command;
|
||||
import mock.model.commandFactory.CompositeCommand;
|
||||
import network.Messages.*;
|
||||
import shared.model.RunnableWithFramePeriod;
|
||||
import visualiser.Commands.VisualiserRaceCommands.VisualiserRaceCommandFactory;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.logging.Level;
|
||||
@@ -8,8 +13,7 @@ import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* TCP client which receives packets/messages from a race data source
|
||||
* (e.g., mock source, official source), and exposes them to any observers.
|
||||
* The controller for race related messages, coming from the server to the client.
|
||||
*/
|
||||
public class VisualiserRaceController implements RunnableWithFramePeriod {
|
||||
|
||||
@@ -21,31 +25,29 @@ public class VisualiserRaceController implements RunnableWithFramePeriod {
|
||||
|
||||
|
||||
/**
|
||||
* An object containing the set of latest messages to write to.
|
||||
* Every server frame, VisualiserInput reads messages from its incomingMessages, and write them to this.
|
||||
* Commands are placed in here, and executed by visualiserRace.
|
||||
*/
|
||||
private LatestMessages latestMessages;
|
||||
private CompositeCommand compositeRaceCommand;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a visualiserInput to convert an incoming stream of messages into LatestMessages.
|
||||
*
|
||||
* @param latestMessages Object to place messages in.
|
||||
* The context that created commands operate on.
|
||||
*/
|
||||
private VisualiserRaceState visualiserRace;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a visualiserInput to convert an incoming stream of messages into commands.
|
||||
* @param incomingMessages The incoming queue of messages.
|
||||
* @param visualiserRace The context to for commands to operate on.
|
||||
* @param compositeRaceCommand The composite command to place command in.
|
||||
*/
|
||||
public VisualiserRaceController(LatestMessages latestMessages, BlockingQueue<AC35Data> incomingMessages) {
|
||||
this.latestMessages = latestMessages;
|
||||
public VisualiserRaceController(BlockingQueue<AC35Data> incomingMessages, VisualiserRaceState visualiserRace, CompositeCommand compositeRaceCommand) {
|
||||
this.incomingMessages = incomingMessages;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the LatestMessages object, which can be queried for any received race related messages.
|
||||
*
|
||||
* @return The LatestMessages object.
|
||||
*/
|
||||
public LatestMessages getLatestMessages() {
|
||||
return latestMessages;
|
||||
this.compositeRaceCommand = compositeRaceCommand;
|
||||
this.visualiserRace = visualiserRace;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,157 +58,21 @@ public class VisualiserRaceController implements RunnableWithFramePeriod {
|
||||
|
||||
while (!Thread.interrupted()) {
|
||||
|
||||
AC35Data message = null;
|
||||
try {
|
||||
message = incomingMessages.take();
|
||||
AC35Data message = incomingMessages.take();
|
||||
|
||||
Command command = VisualiserRaceCommandFactory.create(message, visualiserRace);
|
||||
compositeRaceCommand.addCommand(command);
|
||||
|
||||
} catch (CommandConstructionException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "VisualiserRaceController could not create a command for incoming message.");
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Logger.getGlobal().log(Level.SEVERE, "VisualiserInput was interrupted on thread: " + Thread.currentThread() + " while waiting for messages.");
|
||||
Logger.getGlobal().log(Level.SEVERE, "VisualiserRaceController was interrupted on thread: " + Thread.currentThread() + " while waiting for messages.");
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//TODO refactor below
|
||||
|
||||
//Checks which message is being received and does what is needed for that message.
|
||||
switch (message.getType()) {
|
||||
|
||||
|
||||
//RaceStatus.
|
||||
case RACESTATUS: {
|
||||
RaceStatus raceStatus = (RaceStatus) message;
|
||||
|
||||
//System.out.println("Race Status Message");
|
||||
this.latestMessages.setRaceStatus(raceStatus);
|
||||
|
||||
for (BoatStatus boatStatus : raceStatus.getBoatStatuses()) {
|
||||
this.latestMessages.setBoatStatus(boatStatus);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//DisplayTextMessage.
|
||||
case DISPLAYTEXTMESSAGE: {
|
||||
//System.out.println("Display Text Message");
|
||||
//No decoder for this.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//XMLMessage.
|
||||
case XMLMESSAGE: {
|
||||
XMLMessage xmlMessage = (XMLMessage) message;
|
||||
|
||||
//System.out.println("XML Message!");
|
||||
|
||||
this.latestMessages.setXMLMessage(xmlMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//RaceStartStatus.
|
||||
case RACESTARTSTATUS: {
|
||||
|
||||
//System.out.println("Race Start Status Message");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//YachtEventCode.
|
||||
case YACHTEVENTCODE: {
|
||||
//YachtEventCode yachtEventCode = (YachtEventCode) message;
|
||||
|
||||
//System.out.println("Yacht Event Code!");
|
||||
//No decoder for this.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//YachtActionCode.
|
||||
case YACHTACTIONCODE: {
|
||||
//YachtActionCode yachtActionCode = (YachtActionCode) message;
|
||||
|
||||
//System.out.println("Yacht Action Code!");
|
||||
// No decoder for this.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//ChatterText.
|
||||
case CHATTERTEXT: {
|
||||
//ChatterText chatterText = (ChatterText) message;
|
||||
|
||||
//System.out.println("Chatter Text Message!");
|
||||
//No decoder for this.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//BoatLocation.
|
||||
case BOATLOCATION: {
|
||||
BoatLocation boatLocation = (BoatLocation) message;
|
||||
|
||||
//System.out.println("Boat Location!");
|
||||
|
||||
BoatLocation existingBoatLocation = this.latestMessages.getBoatLocationMap().get(boatLocation.getSourceID());
|
||||
if (existingBoatLocation != null) {
|
||||
//If our boatlocation map already contains a boat location message for this boat, check that the new message is actually for a later timestamp (i.e., newer).
|
||||
if (boatLocation.getTime() > existingBoatLocation.getTime()) {
|
||||
//If it is, replace the old message.
|
||||
this.latestMessages.setBoatLocation(boatLocation);
|
||||
}
|
||||
} else {
|
||||
//If the map _doesn't_ already contain a message for this boat, insert the message.
|
||||
this.latestMessages.setBoatLocation(boatLocation);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//MarkRounding.
|
||||
case MARKROUNDING: {
|
||||
MarkRounding markRounding = (MarkRounding) message;
|
||||
|
||||
//System.out.println("Mark Rounding Message!");
|
||||
|
||||
MarkRounding existingMarkRounding = this.latestMessages.getMarkRoundingMap().get(markRounding.getSourceID());
|
||||
if (existingMarkRounding != null) {
|
||||
|
||||
//If our markRoundingMap already contains a mark rounding message for this boat, check that the new message is actually for a later timestamp (i.e., newer).
|
||||
if (markRounding.getTime() > existingMarkRounding.getTime()) {
|
||||
//If it is, replace the old message.
|
||||
this.latestMessages.setMarkRounding(markRounding);
|
||||
}
|
||||
|
||||
} else {
|
||||
//If the map _doesn't_ already contain a message for this boat, insert the message.
|
||||
this.latestMessages.setMarkRounding(markRounding);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//CourseWinds.
|
||||
case COURSEWIND: {
|
||||
|
||||
//System.out.println("Course Wind Message!");
|
||||
CourseWinds courseWinds = (CourseWinds) message;
|
||||
|
||||
this.latestMessages.setCourseWinds(courseWinds);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Main loop.
|
||||
// take message
|
||||
// create command
|
||||
// place in command queue
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user