Added MarkRoundingEncoder.
Refactored MarkRoundingDecoder - it now implements MessageDecoder. Tidied up MarkRounding - it is now documented and has getters. Also Created MarkRoundingBoatStatusEnum, MarkRoundingIDEnum, MarkRoundingSideEnum, MarkRoundingTypeEnum. Added MarkRoundingDecoderTest. issue #35 #36 #story[1095]
This commit is contained in:
@@ -189,8 +189,8 @@ public class BinaryMessageDecoder {
|
|||||||
|
|
||||||
case MARKROUNDING:
|
case MARKROUNDING:
|
||||||
//System.out.println("Mark Rounding Message!");
|
//System.out.println("Mark Rounding Message!");
|
||||||
MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder(messageBody);
|
MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder();
|
||||||
return mrDecoder.getMarkRounding();
|
return mrDecoder.decode(messageBody);
|
||||||
|
|
||||||
case COURSEWIND:
|
case COURSEWIND:
|
||||||
//System.out.println("Course Wind Message!");
|
//System.out.println("Course Wind Message!");
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class DecoderFactory {
|
|||||||
|
|
||||||
case BOATLOCATION: return new BoatLocationDecoder();
|
case BOATLOCATION: return new BoatLocationDecoder();
|
||||||
|
|
||||||
//case MARKROUNDING: return new MarkRoundingDecoder()//TODO;
|
case MARKROUNDING: return new MarkRoundingDecoder();
|
||||||
|
|
||||||
case COURSEWIND: return new CourseWindsDecoder();
|
case COURSEWIND: return new CourseWindsDecoder();
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +1,90 @@
|
|||||||
package network.MessageDecoders;
|
package network.MessageDecoders;
|
||||||
|
|
||||||
|
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.Enums.MarkRoundingBoatStatusEnum;
|
||||||
|
import network.Messages.Enums.MarkRoundingSideEnum;
|
||||||
|
import network.Messages.Enums.MarkRoundingTypeEnum;
|
||||||
import network.Messages.MarkRounding;
|
import network.Messages.MarkRounding;
|
||||||
import network.Utils.ByteConverter;
|
import network.Utils.ByteConverter;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hba56 on 23/04/17.
|
* Decoder for {@link MarkRounding} messages.
|
||||||
*/
|
*/
|
||||||
public class MarkRoundingDecoder {
|
public class MarkRoundingDecoder implements MessageDecoder {
|
||||||
byte messageVersionNumber;
|
|
||||||
byte[] byteTime;
|
|
||||||
byte[] byteAck;
|
|
||||||
byte[] byteRaceID;
|
|
||||||
byte[] byteSourceID;
|
|
||||||
byte byteBoatStatus;
|
|
||||||
byte byteRoundingSide;
|
|
||||||
byte byteMarkType;
|
|
||||||
byte byteMarkID;
|
|
||||||
|
|
||||||
MarkRounding markRounding;
|
/**
|
||||||
|
* The encoded message.
|
||||||
|
*/
|
||||||
|
private byte[] encodedMessage;
|
||||||
|
|
||||||
public MarkRoundingDecoder(byte[] encodedMarkRounding) {
|
/**
|
||||||
messageVersionNumber = encodedMarkRounding[0];
|
* The decoded message.
|
||||||
byteTime = Arrays.copyOfRange(encodedMarkRounding, 1, 7);
|
*/
|
||||||
byteAck = Arrays.copyOfRange(encodedMarkRounding, 7, 9);
|
private MarkRounding message;
|
||||||
byteRaceID = Arrays.copyOfRange(encodedMarkRounding, 9, 13);
|
|
||||||
byteSourceID = Arrays.copyOfRange(encodedMarkRounding, 13, 17);
|
|
||||||
byteBoatStatus = encodedMarkRounding[17];
|
|
||||||
byteRoundingSide = encodedMarkRounding[18];
|
|
||||||
byteMarkType = encodedMarkRounding[19];
|
|
||||||
byteMarkID = encodedMarkRounding[20];
|
|
||||||
|
|
||||||
int intMsgVer = ByteConverter.bytesToInt(messageVersionNumber);
|
|
||||||
long lngTime = ByteConverter.bytesToLong(byteTime);
|
|
||||||
int intAck = ByteConverter.bytesToInt(byteAck);
|
|
||||||
int intRaceID = ByteConverter.bytesToInt(byteRaceID);
|
|
||||||
int intSourceID = ByteConverter.bytesToInt(byteSourceID);
|
|
||||||
int intBoatState = ByteConverter.bytesToInt(byteBoatStatus);
|
|
||||||
int intRoundingSide = ByteConverter.bytesToInt(byteRoundingSide);
|
|
||||||
int intMarkType = ByteConverter.bytesToInt(byteMarkType);
|
|
||||||
int intMarkID = ByteConverter.bytesToInt(byteMarkID);
|
|
||||||
|
|
||||||
markRounding = new MarkRounding(intMsgVer, lngTime, intAck, intRaceID, intSourceID, intBoatState, intRoundingSide, intMarkType, intMarkID);
|
/**
|
||||||
|
* Constructs a decoder to decode a given message.
|
||||||
|
*/
|
||||||
|
public MarkRoundingDecoder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MarkRounding getMarkRounding() {
|
@Override
|
||||||
return markRounding;
|
public AC35Data decode(byte[] encodedMessage) {
|
||||||
|
this.encodedMessage = encodedMessage;
|
||||||
|
|
||||||
|
byte messageVersionNumber = encodedMessage[0];
|
||||||
|
|
||||||
|
byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||||
|
long time = ByteConverter.bytesToLong(byteTime);
|
||||||
|
|
||||||
|
byte[] byteAck = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||||
|
int ackNumber = ByteConverter.bytesToInt(byteAck);
|
||||||
|
|
||||||
|
byte[] byteRaceID = Arrays.copyOfRange(encodedMessage, 9, 13);
|
||||||
|
int raceID = ByteConverter.bytesToInt(byteRaceID);
|
||||||
|
|
||||||
|
byte[] byteSourceID = Arrays.copyOfRange(encodedMessage, 13, 17);
|
||||||
|
int sourceID = ByteConverter.bytesToInt(byteSourceID);
|
||||||
|
|
||||||
|
byte byteBoatStatus = encodedMessage[17];
|
||||||
|
MarkRoundingBoatStatusEnum boatStatus = MarkRoundingBoatStatusEnum.fromByte(byteBoatStatus);
|
||||||
|
|
||||||
|
byte byteRoundingSide = encodedMessage[18];
|
||||||
|
MarkRoundingSideEnum roundingSide = MarkRoundingSideEnum.fromByte(byteRoundingSide);
|
||||||
|
|
||||||
|
byte byteMarkType = encodedMessage[19];
|
||||||
|
MarkRoundingTypeEnum markType = MarkRoundingTypeEnum.fromByte(byteMarkType);
|
||||||
|
|
||||||
|
byte byteMarkID = encodedMessage[20];
|
||||||
|
|
||||||
|
|
||||||
|
message = new MarkRounding(
|
||||||
|
messageVersionNumber,
|
||||||
|
time,
|
||||||
|
ackNumber,
|
||||||
|
raceID,
|
||||||
|
sourceID,
|
||||||
|
boatStatus,
|
||||||
|
roundingSide,
|
||||||
|
markType,
|
||||||
|
byteMarkID);
|
||||||
|
|
||||||
|
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the decoded message.
|
||||||
|
*
|
||||||
|
* @return The decoded message.
|
||||||
|
*/
|
||||||
|
public MarkRounding getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class EncoderFactory {
|
|||||||
|
|
||||||
case BOATLOCATION: return new BoatLocationEncoder();
|
case BOATLOCATION: return new BoatLocationEncoder();
|
||||||
|
|
||||||
//case MARKROUNDING: return new MarkRoundingEncoder();//TODO
|
case MARKROUNDING: return new MarkRoundingEncoder();
|
||||||
|
|
||||||
case COURSEWIND: return new CourseWindsEncoder();
|
case COURSEWIND: return new CourseWindsEncoder();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package network.MessageEncoders;
|
||||||
|
|
||||||
|
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.MarkRounding;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static network.Utils.ByteConverter.intToBytes;
|
||||||
|
import static network.Utils.ByteConverter.longToBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This encoder can encode a {@link MarkRounding} message.
|
||||||
|
*/
|
||||||
|
public class MarkRoundingEncoder implements MessageEncoder {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public MarkRoundingEncoder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] encode(AC35Data message) {
|
||||||
|
|
||||||
|
//Downcast.
|
||||||
|
MarkRounding markRounding = (MarkRounding) message;
|
||||||
|
|
||||||
|
byte messageVersionNumber = markRounding.getMessageVersionNumber();
|
||||||
|
byte[] byteTime = longToBytes(markRounding.getTime(), 6);
|
||||||
|
byte[] byteAck = intToBytes(markRounding.getAckNum(), 2);
|
||||||
|
byte[] byteRaceID = intToBytes(markRounding.getRaceID(), 4);
|
||||||
|
byte[] byteSourceID = intToBytes(markRounding.getSourceID(), 4);
|
||||||
|
byte[] byteBoatStatus = intToBytes(markRounding.getBoatStatus().getValue(), 1);
|
||||||
|
byte[] byteRoundingSide = intToBytes(markRounding.getRoundingSide().getValue(), 1);
|
||||||
|
byte[] byteMarkType = intToBytes(markRounding.getMarkType().getValue(), 1);
|
||||||
|
byte[] byteMarkID = intToBytes(markRounding.getMarkID(), 1);
|
||||||
|
|
||||||
|
|
||||||
|
ByteBuffer result = ByteBuffer.allocate(21);
|
||||||
|
|
||||||
|
result.put(messageVersionNumber);
|
||||||
|
result.put(byteTime);
|
||||||
|
result.put(byteAck);
|
||||||
|
result.put(byteRaceID);
|
||||||
|
result.put(byteSourceID);
|
||||||
|
result.put(byteBoatStatus);
|
||||||
|
result.put(byteRoundingSide);
|
||||||
|
result.put(byteMarkType);
|
||||||
|
result.put(byteMarkID);
|
||||||
|
|
||||||
|
return result.array();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,30 +100,6 @@ public class RaceVisionByteEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
|
|
||||||
int messageVersionNumber = 0b1;
|
|
||||||
byte[] byteTime = longToBytes(time, 6);
|
|
||||||
byte[] byteAck = intToBytes(ackNumber, 2);
|
|
||||||
byte[] byteRaceID = intToBytes(raceID, 4);
|
|
||||||
byte[] byteSourceID = intToBytes(sourceID, 4);
|
|
||||||
byte[] byteBoatStatus = intToBytes(boatStatus, 1);
|
|
||||||
byte[] byteRoundingSide = intToBytes(roundingSide, 1);
|
|
||||||
byte[] byteMarkType = intToBytes(markType, 1);
|
|
||||||
byte[] byteMarkID = intToBytes(markID, 1);
|
|
||||||
|
|
||||||
ByteBuffer result = ByteBuffer.allocate(21);
|
|
||||||
result.put(intToBytes(messageVersionNumber, 1));
|
|
||||||
result.put(byteTime);
|
|
||||||
result.put(byteAck);
|
|
||||||
result.put(byteRaceID);
|
|
||||||
result.put(byteSourceID);
|
|
||||||
result.put(byteBoatStatus);
|
|
||||||
result.put(byteRoundingSide);
|
|
||||||
result.put(byteMarkType);
|
|
||||||
result.put(byteMarkID);
|
|
||||||
return result.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package network.Messages.Enums;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration that encapsulates the various statuses a boat can have when rounding a mark.
|
||||||
|
*/
|
||||||
|
public enum MarkRoundingBoatStatusEnum {
|
||||||
|
|
||||||
|
UNKNOWN(0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boat is actively racing.
|
||||||
|
*/
|
||||||
|
RACING(1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boat has been disqualified.
|
||||||
|
*/
|
||||||
|
DSQ(2),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The boat has withdrawn from the race.
|
||||||
|
*/
|
||||||
|
WITHDRAWN(3),
|
||||||
|
|
||||||
|
NOT_A_STATUS(-1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ctor. Creates a {@link MarkRoundingBoatStatusEnum} from a given primitive integer value, cast to a byte.
|
||||||
|
* @param value Integer, which is cast to byte, to construct from.
|
||||||
|
*/
|
||||||
|
private MarkRoundingBoatStatusEnum(int value) {
|
||||||
|
this.value = (byte)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the primitive value of the enum.
|
||||||
|
* @return Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
public byte getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///Stores a mapping between Byte values and MarkRoundingBoatStatusEnum values.
|
||||||
|
private static final Map<Byte, MarkRoundingBoatStatusEnum> byteToStatusMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Static initialization block. Initializes the byteToStatusMap.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
for (MarkRoundingBoatStatusEnum type : MarkRoundingBoatStatusEnum.values()) {
|
||||||
|
byteToStatusMap.put(type.value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enumeration value which corresponds to a given byte value.
|
||||||
|
* @param boatStatusByte Byte value to convert to a {@link MarkRoundingBoatStatusEnum} value.
|
||||||
|
* @return The {@link MarkRoundingBoatStatusEnum} value which corresponds to the given byte value.
|
||||||
|
*/
|
||||||
|
public static MarkRoundingBoatStatusEnum fromByte(byte boatStatusByte) {
|
||||||
|
//Gets the corresponding MarkRoundingBoatStatusEnum from the map.
|
||||||
|
MarkRoundingBoatStatusEnum type = byteToStatusMap.get(boatStatusByte);
|
||||||
|
|
||||||
|
if (type == null) {
|
||||||
|
//If the byte value wasn't found, return the NOT_A_STATUS MarkRoundingBoatStatusEnum.
|
||||||
|
return MarkRoundingBoatStatusEnum.NOT_A_STATUS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Otherwise, return the MarkRoundingBoatStatusEnum.
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package network.Messages.Enums;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration that encapsulates the various mark identities.
|
||||||
|
*/
|
||||||
|
public enum MarkRoundingIDEnum {
|
||||||
|
|
||||||
|
UNKNOWN(0),
|
||||||
|
|
||||||
|
|
||||||
|
ENTRY_LIMIT_LINE(100),
|
||||||
|
|
||||||
|
ENTRY_LINE(101),
|
||||||
|
|
||||||
|
START_LINE(102),
|
||||||
|
|
||||||
|
FINISH_LINE(103),
|
||||||
|
|
||||||
|
SPEED_TEST_START(104),
|
||||||
|
|
||||||
|
SPEED_TEST_FINISH(105),
|
||||||
|
|
||||||
|
CLEAR_START(106),
|
||||||
|
|
||||||
|
NOT_AN_ID(-1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ctor. Creates a {@link MarkRoundingIDEnum} from a given primitive integer value, cast to a byte.
|
||||||
|
* @param value Integer, which is cast to byte, to construct from.
|
||||||
|
*/
|
||||||
|
private MarkRoundingIDEnum(int value) {
|
||||||
|
this.value = (byte)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the primitive value of the enum.
|
||||||
|
* @return Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
public byte getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///Stores a mapping between Byte values and MarkRoundingIDEnum values.
|
||||||
|
private static final Map<Byte, MarkRoundingIDEnum> byteToIDMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Static initialization block. Initializes the byteToIDMap.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
for (MarkRoundingIDEnum type : MarkRoundingIDEnum.values()) {
|
||||||
|
byteToIDMap.put(type.value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enumeration value which corresponds to a given byte value.
|
||||||
|
* @param sideByte Byte value to convert to a {@link MarkRoundingIDEnum} value.
|
||||||
|
* @return The {@link MarkRoundingIDEnum} value which corresponds to the given byte value.
|
||||||
|
*/
|
||||||
|
public static MarkRoundingIDEnum fromByte(byte sideByte) {
|
||||||
|
//Gets the corresponding MarkRoundingIDEnum from the map.
|
||||||
|
MarkRoundingIDEnum type = byteToIDMap.get(sideByte);
|
||||||
|
|
||||||
|
if (type == null) {
|
||||||
|
//If the byte value wasn't found, return the NOT_AN_ID MarkRoundingIDEnum.
|
||||||
|
return MarkRoundingIDEnum.NOT_AN_ID;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Otherwise, return the MarkRoundingIDEnum.
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package network.Messages.Enums;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration that encapsulates the various sides around which a boat may pass a mark.
|
||||||
|
*/
|
||||||
|
public enum MarkRoundingSideEnum {
|
||||||
|
|
||||||
|
UNKNOWN(0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boat rounded around port side of mark.
|
||||||
|
*/
|
||||||
|
PORT(1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boat rounded around starboard side of mark.
|
||||||
|
*/
|
||||||
|
STARBOARD(2),
|
||||||
|
|
||||||
|
NOT_A_SIDE(-1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ctor. Creates a {@link MarkRoundingSideEnum} from a given primitive integer value, cast to a byte.
|
||||||
|
* @param value Integer, which is cast to byte, to construct from.
|
||||||
|
*/
|
||||||
|
private MarkRoundingSideEnum(int value) {
|
||||||
|
this.value = (byte)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the primitive value of the enum.
|
||||||
|
* @return Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
public byte getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///Stores a mapping between Byte values and MarkRoundingSideEnum values.
|
||||||
|
private static final Map<Byte, MarkRoundingSideEnum> byteToSideMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Static initialization block. Initializes the byteToSideMap.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
for (MarkRoundingSideEnum type : MarkRoundingSideEnum.values()) {
|
||||||
|
byteToSideMap.put(type.value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enumeration value which corresponds to a given byte value.
|
||||||
|
* @param sideByte Byte value to convert to a {@link MarkRoundingSideEnum} value.
|
||||||
|
* @return The {@link MarkRoundingSideEnum} value which corresponds to the given byte value.
|
||||||
|
*/
|
||||||
|
public static MarkRoundingSideEnum fromByte(byte sideByte) {
|
||||||
|
//Gets the corresponding MarkRoundingSideEnum from the map.
|
||||||
|
MarkRoundingSideEnum type = byteToSideMap.get(sideByte);
|
||||||
|
|
||||||
|
if (type == null) {
|
||||||
|
//If the byte value wasn't found, return the NOT_A_SIDE MarkRoundingSideEnum.
|
||||||
|
return MarkRoundingSideEnum.NOT_A_SIDE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Otherwise, return the MarkRoundingSideEnum.
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package network.Messages.Enums;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration that encapsulates the various types of marks that may be passed.
|
||||||
|
*/
|
||||||
|
public enum MarkRoundingTypeEnum {
|
||||||
|
|
||||||
|
UNKNOWN(0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mark is a singular mark.
|
||||||
|
*/
|
||||||
|
MARK(1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mark is a gate (windward, leeward, start, finish, etc...).
|
||||||
|
*/
|
||||||
|
GATE(2),
|
||||||
|
|
||||||
|
NOT_A_TYPE(-1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
private byte value;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ctor. Creates a {@link MarkRoundingTypeEnum} from a given primitive integer value, cast to a byte.
|
||||||
|
* @param value Integer, which is cast to byte, to construct from.
|
||||||
|
*/
|
||||||
|
private MarkRoundingTypeEnum(int value) {
|
||||||
|
this.value = (byte)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the primitive value of the enum.
|
||||||
|
* @return Primitive value of the enum.
|
||||||
|
*/
|
||||||
|
public byte getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///Stores a mapping between Byte values and MarkRoundingTypeEnum values.
|
||||||
|
private static final Map<Byte, MarkRoundingTypeEnum> byteToTypeMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Static initialization block. Initializes the byteToTypeMap.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
for (MarkRoundingTypeEnum type : MarkRoundingTypeEnum.values()) {
|
||||||
|
byteToTypeMap.put(type.value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enumeration value which corresponds to a given byte value.
|
||||||
|
* @param sideByte Byte value to convert to a {@link MarkRoundingTypeEnum} value.
|
||||||
|
* @return The {@link MarkRoundingTypeEnum} value which corresponds to the given byte value.
|
||||||
|
*/
|
||||||
|
public static MarkRoundingTypeEnum fromByte(byte sideByte) {
|
||||||
|
//Gets the corresponding MarkRoundingTypeEnum from the map.
|
||||||
|
MarkRoundingTypeEnum type = byteToTypeMap.get(sideByte);
|
||||||
|
|
||||||
|
if (type == null) {
|
||||||
|
//If the byte value wasn't found, return the NOT_A_TYPE MarkRoundingTypeEnum.
|
||||||
|
return MarkRoundingTypeEnum.NOT_A_TYPE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Otherwise, return the MarkRoundingTypeEnum.
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,47 +1,94 @@
|
|||||||
package network.Messages;
|
package network.Messages;
|
||||||
|
|
||||||
|
|
||||||
|
import network.Messages.Enums.MarkRoundingBoatStatusEnum;
|
||||||
|
import network.Messages.Enums.MarkRoundingSideEnum;
|
||||||
|
import network.Messages.Enums.MarkRoundingTypeEnum;
|
||||||
import network.Messages.Enums.MessageType;
|
import network.Messages.Enums.MessageType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by fwy13 on 25/04/17.
|
* Represents a MarkRound message (see AC35 spec, 4.10).
|
||||||
*/
|
*/
|
||||||
public class MarkRounding extends AC35Data {
|
public class MarkRounding extends AC35Data {
|
||||||
|
|
||||||
private int msgVerNum;
|
/**
|
||||||
|
* The current messageVersionNumber according to the API spec.
|
||||||
|
*/
|
||||||
|
public static final byte currentMessageVersionNumber = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version number of the message.
|
||||||
|
*/
|
||||||
|
private byte messageVersionNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time at which the mark was rounding. Milliseconds since unix epoch.
|
||||||
|
*/
|
||||||
private long time;
|
private long time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ack number of the message.
|
||||||
|
*/
|
||||||
private int ackNum;
|
private int ackNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The raceID this message relates to.
|
||||||
|
*/
|
||||||
private int raceID;
|
private int raceID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sourceID of the boat this message relates to.
|
||||||
|
*/
|
||||||
private int sourceID;
|
private int sourceID;
|
||||||
private int boatStatus;
|
|
||||||
private int roundingSide;
|
|
||||||
private int markType;
|
|
||||||
private int markID;
|
|
||||||
|
|
||||||
public static int BoatStatusUnknown = 0;
|
/**
|
||||||
public static int BoatStatusRacing = 1;
|
* The status of the boat.
|
||||||
public static int BoatStatusDSQ = 2;
|
*/
|
||||||
public static int BoatStatusWithdrawn = 3;
|
private MarkRoundingBoatStatusEnum boatStatus;
|
||||||
|
|
||||||
public static int RoundingSideUnknown = 0;
|
/**
|
||||||
public static int RoundingSidePort = 1;
|
* The side around which the boat rounded.
|
||||||
public static int RoundingSideStarboard = 2;
|
*/
|
||||||
|
private MarkRoundingSideEnum roundingSide;
|
||||||
|
|
||||||
public static int MarkTypeUnknown = 0;
|
/**
|
||||||
public static int MarkTypeRoundingMark = 1;
|
* The type of mark that was rounded.
|
||||||
public static int MarkTypeGate = 2;
|
*/
|
||||||
|
private MarkRoundingTypeEnum markType;
|
||||||
|
|
||||||
public static int MarkIDEntryLimitLine = 100;
|
/**
|
||||||
public static int MarkIDEntryLine = 101;
|
* The ID of the mark. This is not a source ID.
|
||||||
public static int MarkIDRaceStartStartline = 102;
|
*/
|
||||||
public static int MarkIDRaceFinishline = 103;
|
private byte markID;
|
||||||
public static int MarkIDSpeedTestStart = 104;
|
|
||||||
public static int MarkIDSpeedTestFinish = 105;
|
|
||||||
public static int MarkIDClearStart = 106;
|
/**
|
||||||
|
* Creates a MarkRounding message with the given parameters.
|
||||||
|
* @param messageVersionNumber The version number of the message.
|
||||||
|
* @param time The time at which the message was created.
|
||||||
|
* @param ackNum The ack number of the message.
|
||||||
|
* @param raceID The raceID this message relates to.
|
||||||
|
* @param sourceID The sourceID of the boat this message relates to.
|
||||||
|
* @param boatStatus The status of the boat as it rounded the mark.
|
||||||
|
* @param roundingSide The side around which the boat rounded.
|
||||||
|
* @param markType The type of mark that was rounded.
|
||||||
|
* @param markID The ID number of the mark. Not a sourceID. See {@link network.Messages.Enums.MarkRoundingIDEnum}.
|
||||||
|
*/
|
||||||
|
public MarkRounding(
|
||||||
|
byte messageVersionNumber,
|
||||||
|
long time,
|
||||||
|
int ackNum,
|
||||||
|
int raceID,
|
||||||
|
int sourceID,
|
||||||
|
MarkRoundingBoatStatusEnum boatStatus,
|
||||||
|
MarkRoundingSideEnum roundingSide,
|
||||||
|
MarkRoundingTypeEnum markType,
|
||||||
|
byte markID ) {
|
||||||
|
|
||||||
public MarkRounding(int msgVerNum, long time, int ackNum, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
|
|
||||||
super(MessageType.MARKROUNDING);
|
super(MessageType.MARKROUNDING);
|
||||||
this.msgVerNum = msgVerNum;
|
|
||||||
|
this.messageVersionNumber = messageVersionNumber;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.ackNum = ackNum;
|
this.ackNum = ackNum;
|
||||||
this.raceID = raceID;
|
this.raceID = raceID;
|
||||||
@@ -52,6 +99,40 @@ public class MarkRounding extends AC35Data {
|
|||||||
this.markID = markID;
|
this.markID = markID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version number of this message.
|
||||||
|
* @return Version number of this message.
|
||||||
|
*/
|
||||||
|
public byte getMessageVersionNumber() {
|
||||||
|
return messageVersionNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the timestamp for this message.
|
||||||
|
* @return Timestamp for this message.
|
||||||
|
*/
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ack number of this message.
|
||||||
|
* @return Ack number of this message.
|
||||||
|
*/
|
||||||
|
public int getAckNum() {
|
||||||
|
return ackNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raceID this message relates to.
|
||||||
|
* @return RaceID this message relates to.
|
||||||
|
*/
|
||||||
|
public int getRaceID() {
|
||||||
|
return raceID;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the boat (source) ID for this message.
|
* Returns the boat (source) ID for this message.
|
||||||
* @return Boat ID for this message.
|
* @return Boat ID for this message.
|
||||||
@@ -61,10 +142,34 @@ public class MarkRounding extends AC35Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the timestamp for this message.
|
* Returns the status of the boat as it rounded the mark.
|
||||||
* @return Timestamp for this message.
|
* @return Status of boat as it rounded mark.
|
||||||
*/
|
*/
|
||||||
public long getTime() {
|
public MarkRoundingBoatStatusEnum getBoatStatus() {
|
||||||
return time;
|
return boatStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the side to which the boat rounded the mark.
|
||||||
|
* @return Side to which boat rounded mark.
|
||||||
|
*/
|
||||||
|
public MarkRoundingSideEnum getRoundingSide() {
|
||||||
|
return roundingSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of mark that was rounded.
|
||||||
|
* @return The type of mark that was rounded.
|
||||||
|
*/
|
||||||
|
public MarkRoundingTypeEnum getMarkType() {
|
||||||
|
return markType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ID number of the mark. This is not a source ID. See {@link network.Messages.Enums.MarkRoundingIDEnum}.
|
||||||
|
* @return ID number of the mark.
|
||||||
|
*/
|
||||||
|
public byte getMarkID() {
|
||||||
|
return markID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package network.MessageDecoders;
|
||||||
|
|
||||||
|
import network.MessageEncoders.RaceVisionByteEncoder;
|
||||||
|
import network.Messages.Enums.MarkRoundingBoatStatusEnum;
|
||||||
|
import network.Messages.Enums.MarkRoundingSideEnum;
|
||||||
|
import network.Messages.Enums.MarkRoundingTypeEnum;
|
||||||
|
import network.Messages.MarkRounding;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the MarkRounding encoder and decoder
|
||||||
|
*/
|
||||||
|
public class MarkRoundingDecoderTest {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MarkRounding message, encodes it, decodes it, and checks that the result matches the starting message.
|
||||||
|
* @throws Exception if test fails.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void markRoundingEncodeDecodeTest() throws Exception {
|
||||||
|
|
||||||
|
MarkRounding markRounding = new MarkRounding(
|
||||||
|
MarkRounding.currentMessageVersionNumber,
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
567,
|
||||||
|
42,
|
||||||
|
125,
|
||||||
|
MarkRoundingBoatStatusEnum.RACING,
|
||||||
|
MarkRoundingSideEnum.PORT,
|
||||||
|
MarkRoundingTypeEnum.MARK,
|
||||||
|
(byte)45
|
||||||
|
);
|
||||||
|
|
||||||
|
byte[] encodedMessage = RaceVisionByteEncoder.encode(markRounding);
|
||||||
|
|
||||||
|
MarkRoundingDecoder markRoundingDecoder = new MarkRoundingDecoder();
|
||||||
|
markRoundingDecoder.decode(encodedMessage);
|
||||||
|
MarkRounding markRoundingDecoded = markRoundingDecoder.getMessage();
|
||||||
|
|
||||||
|
compareMarkRoundingMessages(markRounding, markRoundingDecoded);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two MarkRounding messages to check that they are equal.
|
||||||
|
* @param original The original MarkRounding message.
|
||||||
|
* @param decoded The decoded MarkRounding message.
|
||||||
|
*/
|
||||||
|
public static void compareMarkRoundingMessages(MarkRounding original, MarkRounding decoded) {
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(original.getMessageVersionNumber(), decoded.getMessageVersionNumber());
|
||||||
|
assertEquals(original.getTime(), decoded.getTime());
|
||||||
|
assertEquals(original.getAckNum(), decoded.getAckNum());
|
||||||
|
assertEquals(original.getRaceID(), decoded.getRaceID());
|
||||||
|
assertEquals(original.getSourceID(), decoded.getSourceID());
|
||||||
|
assertEquals(original.getBoatStatus(), decoded.getBoatStatus());
|
||||||
|
assertEquals(original.getRoundingSide(), decoded.getRoundingSide());
|
||||||
|
assertEquals(original.getMarkType(), decoded.getMarkType());
|
||||||
|
assertEquals(original.getMarkID(), decoded.getMarkID());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user