You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.2 KiB
103 lines
3.2 KiB
package network.MessageEncoders;
|
|
|
|
|
|
import network.Exceptions.InvalidMessageException;
|
|
import network.Messages.AC35Data;
|
|
import network.Messages.BoatStatus;
|
|
import network.Messages.RaceStatus;
|
|
import network.Utils.AC35UnitConverter;
|
|
import shared.model.Bearing;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.util.List;
|
|
|
|
import static network.Utils.ByteConverter.bytesToInt;
|
|
import static network.Utils.ByteConverter.intToBytes;
|
|
import static network.Utils.ByteConverter.longToBytes;
|
|
|
|
/**
|
|
* This encoder can encode a {@link RaceStatus} message.
|
|
*/
|
|
public class RaceStatusEncoder implements MessageEncoder {
|
|
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public RaceStatusEncoder() {
|
|
}
|
|
|
|
|
|
@Override
|
|
public byte[] encode(AC35Data message) throws InvalidMessageException {
|
|
|
|
try {
|
|
|
|
//Downcast.
|
|
RaceStatus raceStatus = (RaceStatus) message;
|
|
|
|
|
|
List<BoatStatus> boatStatuses = raceStatus.getBoatStatuses();
|
|
|
|
//24 byte header, plus 20 bytes per boat status.
|
|
ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20 * boatStatuses.size());
|
|
|
|
//Version Number 1 bytes. this changes with the pdf. (2)
|
|
byte versionNum = 0b10;
|
|
|
|
//time (6 bytes)
|
|
byte[] timeBytes = longToBytes(raceStatus.getCurrentTime(), 6);
|
|
|
|
//race identifier in case multiple races are going at once.
|
|
byte[] raceID = intToBytes(raceStatus.getRaceID());
|
|
|
|
//race status 0 - 10
|
|
byte[] raceStatusByte = intToBytes(raceStatus.getRaceStatus().getValue(), 1);
|
|
|
|
//number of milliseconds from Jan 1, 1970 for when the data is valid
|
|
byte[] expectedStart = longToBytes(raceStatus.getExpectedStartTime(), 6);
|
|
|
|
//North = 0x0000 East = 0x4000 South = 0x8000.
|
|
int windDirectionInt = AC35UnitConverter.packHeading(raceStatus.getWindDirection().degrees());
|
|
byte[] raceWind = intToBytes(windDirectionInt, 2);
|
|
|
|
//mm/sec
|
|
int windSpeedInt = AC35UnitConverter.packKnotsToMMperSec(raceStatus.getWindSpeed());
|
|
byte[] windSpeed = intToBytes(windSpeedInt, 2);
|
|
|
|
|
|
byte[] numBoats = intToBytes(boatStatuses.size(), 1);
|
|
|
|
//1 match race, 2 fleet race
|
|
byte[] bytesRaceType = intToBytes(raceStatus.getRaceType().getValue(), 1);
|
|
|
|
|
|
raceStatusMessage.put(versionNum);
|
|
raceStatusMessage.put(timeBytes);
|
|
raceStatusMessage.put(raceID);
|
|
raceStatusMessage.put(raceStatusByte);
|
|
raceStatusMessage.put(expectedStart);
|
|
raceStatusMessage.put(raceWind);
|
|
raceStatusMessage.put(windSpeed);
|
|
raceStatusMessage.put(numBoats);
|
|
raceStatusMessage.put(bytesRaceType);
|
|
|
|
//Encode each BoatStatus.
|
|
for (BoatStatus boatStatus : boatStatuses) {
|
|
|
|
BoatStatusEncoder boatStatusEncoder = new BoatStatusEncoder();
|
|
|
|
byte[] boatStatusEncoded = boatStatusEncoder.encode(boatStatus);
|
|
|
|
raceStatusMessage.put(boatStatusEncoded);
|
|
}
|
|
|
|
return raceStatusMessage.array();
|
|
|
|
} catch (Exception e) {
|
|
throw new InvalidMessageException("Could not encode RaceStatus message.", e);
|
|
}
|
|
|
|
}
|
|
}
|