class DDaqReceiverJob
{
private:
/* data */
public:
DDaqReceiverJob(/* args */);
~DDaqReceiverJob();
/// the ip address and port of the receiver
std::string ipAddress;
int port;
// the mode of this job: 1. blob mode, when the whole blob is received, then shift the blob head to the latest sample position
// 2. stream mode, when new samples are received, the blob head is shifted to the latest sample position
// 3. reflect memory mode, never shift blob head, replace sample in the blob with the new sample at specified position
int mode;
// the id of this job, must match the id of the sender job
int jobId;
// the reference to the blob object
DDaqBlob *blob;
// when the blob is updated(mode 1,2 head shifted, mode 3 the blob is changed), fire this event
event void onBlobUpdated(DDaqBlob *blob)
{
// do something with the blob
}
// when the sender explicitly send event with a message, fire this event, only work in mode 3
event void onMessageReceived(std::string message)
{
// do something with the message
}
}
// the blob object, it is a container for the data
class DDaqBlob
{
// only the job can access the blob, the blob is created by the job, and the buffer is allocated in the job
friend class DDaqReceiverJob;
friend class DDaqSenderJob;
// auto flush是否必要
// write data to the blob, only the job can do this, called when the data have been received or the data has been sent
// only call this in mode 3
// do not block reading, the data is written to the buffer,
// and the blob is updated by shifting the head of the ping-pong buffer
void writeData(int channelStart, int channelCount,
int sampleStart, int sampleCount,
char *dataBuffer);
// 接收和发送的场景都使用这个函数吗?
// only call this in mode 1,2, called when the data have been received or the data has been sent
// no need to block reading, since the data is appended to ahead of the blob head
// always append with all the channels, sample count may vary
// the sample may not be received in order, so the sample index is used to specify the sample number in the blob.
// the index is a cycle, when it reaches the end of the blob, it will start from the 0 again
// for missing samples, when the the sample which is X (a config of the job) sample later than the missing sample has been received,
// the missing sample is considered as lost forever, and filled with 0 or samples of the same index from the last blob.
void appendData(int sampleCount, int sampleIndex, char *dataBuffer);
// lock reading, update the read head of the blob
// in mode 3, just flip the ping-pong buffer
// in mode 1,2, shift to the latest sample position
void updateBlobHead();
private:
/* data */
// the buffer for the data, it's larger than the actual blob size
// the actual blob size is channel * sampleSize,
// the buffer size is channel * (sampleSize + additionalSize)
// the additional size is used for:
// in mode 1: for the next incoming blob
// in mode 2: for the incoming samples, for both mode 1,2, the additional is reserved for noCopy read
// in mode 3: the additional size is sampleSize, for the reflect memory mode, ping-pong buffer
// for sender the buffer is the same as the blob size, the additional size is not used
char *buffer;
public:
// specify the channel and sample size, receiver or sender
// the blob is created by the job, and the buffer is allocated in the job
DDaqBlob(int channel, int sampleSize, int additionalSize, bool isSender = false);
~DDaqBlob();
// read the data from the buffer, with copy
void readData(int channelStart, int channelCount,
int sampleStart, int sampleCount,
char *dataBuffer);
// read the data from the buffer, with no copy, just a pointer to the buffer
// must call finishReadNoCopy to finish the read, and release the buffer pointer
// although the reader specifies the channel and sample start and size, the tail point only move on the sample axis not the channel axis.
char *readDataNoCopy(int channelStart, int channelCount,
int sampleStart, int sampleCount);
// finished the blob with no copy
void finishReadNoCopy(char *reaBbuffer);
}
// the sender job, it is the sender of the data
class DDaqSenderJob
{
private:
/* data */
public:
DDaqSenderJob(/* args */);
~DDaqSenderJob();
// the ip address and port of the sender
std::string ipAddress;
int port;
// for sender job, there is no different between blob and stream mode,
// it just stream samples to the receiver.
int mode;
// the id of this job, must match the id of the receiver job
int jobId;
// Mode3下一定要有?
// if true, the blob is mirrored
// if not this job does not need a blob object, just send and forget
bool isMirrorBlob;
// 需要有一个blob?
// send samples to the receiver, only call this in mode 1,2
// data are always sent with all the channels, sample count may vary
// construct slice in this function,
// slice will have a sample index number to specify the number of sample in the blob.
// update the blob in sender after sent when the blob is mirrored
void sendData(int sampleCount, char *dataBuffer);
// call this in mode
// update the blob in sender after sent when the blob is mirrored
void writeData(int channelStart, int channelCount,
int sampleStart, int sampleCount,
char *dataBuffer);
}
本文章使用limfx的vscode插件快速发布