Last active
March 28, 2016 18:01
-
-
Save kierdavis/4c6cac5189ec402f52c3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// All possible types of packet. Packet types are 8-bit integers. | |
typedef enum { | |
// Packet type 0x00 is reserved in case we need some form of "null packet"/"absence of a packet" | |
// Move the cursor position to new coordinates. | |
// Payload is two 16-bit integers, which are the x and y coordinates to move to. | |
PACKET_TYPE_MOVE_TO = 0x01; | |
// Draw a line from the cursor position to the given coordinates, then update | |
// the cursor position to these new coordinates. | |
// Payload is two 16-bit integers, which are the x and y coordinates to draw a line to. | |
PACKET_TYPE_LINE_TO = 0x02; | |
// Set the colour used for drawing future lines. | |
// Payload is three 8-bit integers forming a 24-bit RGB colour. | |
PACKET_TYPE_SET_COLOUR = 0x03; | |
// Set the line width used for drawing future lines. | |
// Payload is an 8-bit integer, which is piped straight into Qt's line | |
// drawing function and follows whatever specification that is. | |
PACKET_TYPE_SET_WIDTH = 0x04; | |
// There may also be some other packets for communication control (e.g. | |
// handshaking) used purely inside the Transmitter and Receiver | |
// implementations. These should be given packet types counting down from | |
// 0xFF, so as not to intefere with the packet types listed above (which | |
// count up from 0x00). | |
} PacketType; | |
// Implements a single piece of information to be transmitted. | |
class Packet { | |
public: | |
// The packet type (one of the PACKET_TYPE_* constants). | |
PacketType type; | |
// The payload (a sequence of bytes). | |
vector<uint8_t> payload; | |
// Calculate the checksum that should be transmitted along with the packet. | |
uint16_t checksum(); | |
// Encode the packet into a stream of bytes containing the packet type, | |
// payload length, payload, and checksum. | |
vector<uint8_t> encode(); | |
// Decode a packet from a stream of bytes, returning true if successful or | |
// false if there was a parse error. This method also checks the | |
// received checksum with the one computed from the rest of the received | |
// data. | |
static bool decode(vector<uint8_t> bytes, Packet &dest); | |
}; | |
// Implements a thread-safe queue of packets. | |
// (actually, why reinvent the wheel? there are some tried-and-tested | |
// thread-safe queue implementations available, e.g. boost::lockfree::queue in | |
// the Boost utility library). | |
class PacketQueue { | |
public: | |
void push(Packet &packet); | |
Packet pop(); | |
unsigned int size(); // number of packets in the queue | |
}; | |
// Implements some kind of data-sending system. We don't care how it works so | |
// long as the data comes out of a Receiver at the other end. | |
class Transmitter { | |
public: | |
// The constructor of this class is left unspecified and should accept any | |
// configuration parameters (e.g. which GPIO pins to use), but should not | |
// start transmitting. | |
// Run the transmitter, which should take packets out of the given queue | |
// when necessary and send them on the communication medium. The GUI code | |
// should put packets into this queue when it wants data to be sent. | |
// This method should not return until communication has ended, and so will | |
// normally be started in a background thread. | |
virtual void run(PacketQueue &queue) = 0; | |
}; | |
// Implements some kind of data-receiving system. We don't care how it works so | |
// long it picks up the data sent by a Transmitter running at the other end. | |
class Receiver { | |
// The constructor of this class is left unspecified and should accept any | |
// configuration parameters (e.g. which GPIO pins to use), but should not | |
// start receiving. | |
// Run the receiver, which should listen for incoming packets on the | |
// communication medium and insert them into the given queue. The GUI code | |
// should poll this queue for packets and process them when appropriate. | |
// This method should not return until communication has ended, and so will | |
// normally be started in a background thread. | |
virtual void run(PacketQueue &queue) = 0; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment