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.
117 lines
3.0 KiB
117 lines
3.0 KiB
package network.StreamRelated;
|
|
|
|
|
|
import network.Exceptions.InvalidMessageException;
|
|
import network.MessageEncoders.RaceVisionByteEncoder;
|
|
import network.Messages.AC35Data;
|
|
import shared.model.RunnableWithFramePeriod;
|
|
|
|
import java.io.DataOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.concurrent.BlockingQueue;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
/**
|
|
* This class is responsible for writing a queue of {@link network.Messages.AC35Data} messages to an output stream.
|
|
*/
|
|
public class MessageSerialiser implements RunnableWithFramePeriod {
|
|
|
|
|
|
/**
|
|
* The stream we're writing to.
|
|
*/
|
|
private DataOutputStream outputStream;
|
|
|
|
/**
|
|
* The messages we're writing to the stream.
|
|
*/
|
|
private BlockingQueue<AC35Data> messagesToSend;
|
|
|
|
|
|
/**
|
|
* Ack numbers used in messages.
|
|
*/
|
|
private int ackNumber = 1;
|
|
|
|
/**
|
|
* Determines whether or not this runnable is currently running.
|
|
*/
|
|
private boolean isRunning;
|
|
|
|
|
|
|
|
/**
|
|
* Constructs a new MessageSerialiser to write a queue of messages to a given stream.
|
|
* @param outputStream The stream to write to.
|
|
* @param messagesToSend The messages to send.
|
|
*/
|
|
public MessageSerialiser(OutputStream outputStream, BlockingQueue<AC35Data> messagesToSend) {
|
|
this.outputStream = new DataOutputStream(outputStream);
|
|
this.messagesToSend = messagesToSend;
|
|
}
|
|
|
|
|
|
/**
|
|
* Increments the ackNumber value, and returns it.
|
|
* @return Incremented ackNumber.
|
|
*/
|
|
private int getNextAckNumber(){
|
|
this.ackNumber++;
|
|
|
|
return this.ackNumber;
|
|
}
|
|
|
|
/**
|
|
* Determines whether or not this runnable is running.
|
|
* @return True means that it is still running, false means that it has stopped.
|
|
*/
|
|
public boolean isRunning() {
|
|
return isRunning;
|
|
}
|
|
|
|
|
|
@Override
|
|
public void run() {
|
|
|
|
long previousFrameTime = System.currentTimeMillis();
|
|
|
|
isRunning = true;
|
|
|
|
while (isRunning) {
|
|
|
|
|
|
long currentFrameTime = System.currentTimeMillis();
|
|
waitForFramePeriod(previousFrameTime, currentFrameTime, 16);
|
|
previousFrameTime = currentFrameTime;
|
|
|
|
|
|
//Send the messages.
|
|
List<AC35Data> messages = new ArrayList<>();
|
|
messagesToSend.drainTo(messages);
|
|
|
|
for (AC35Data message : messages) {
|
|
try {
|
|
byte[] messageBytes = RaceVisionByteEncoder.encodeBinaryMessage(message, getNextAckNumber());
|
|
|
|
outputStream.write(messageBytes);
|
|
|
|
|
|
} catch (InvalidMessageException e) {
|
|
Logger.getGlobal().log(Level.WARNING, "Could not encode message: " + message, e);
|
|
|
|
} catch (IOException e) {
|
|
Logger.getGlobal().log(Level.WARNING, "Could not write message to outputStream: " + outputStream, e);
|
|
isRunning = false;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|