diff --git a/libraries/metavoxels/src/DatagramSequencer.cpp b/libraries/metavoxels/src/DatagramSequencer.cpp index af271d97ba..9c300113c6 100644 --- a/libraries/metavoxels/src/DatagramSequencer.cpp +++ b/libraries/metavoxels/src/DatagramSequencer.cpp @@ -195,7 +195,7 @@ void DatagramSequencer::receivedDatagram(const QByteArray& datagram) { for (int i = 0; i < reliableChannels; i++) { quint32 channelIndex; _incomingPacketStream >> channelIndex; - getReliableOutputChannel(channelIndex)->readData(_incomingPacketStream); + getReliableInputChannel(channelIndex)->readData(_incomingPacketStream); } _incomingPacketStream.device()->seek(0); @@ -369,7 +369,7 @@ int SpanList::set(int offset, int length) { int SpanList::setSpans(QList::iterator it, int length) { int remainingLength = length; int totalRemoved = 0; - for (; it != _spans.end(); it++) { + for (; it != _spans.end(); it = _spans.erase(it)) { if (remainingLength < it->unset) { it->unset -= remainingLength; totalRemoved += remainingLength; @@ -378,7 +378,6 @@ int SpanList::setSpans(QList::iterator it, int length) { int combined = it->unset + it->set; remainingLength = qMax(remainingLength - combined, 0); totalRemoved += combined; - it = _spans.erase(it); _totalSet -= it->set; } return qMax(length, totalRemoved); diff --git a/libraries/metavoxels/src/DatagramSequencer.h b/libraries/metavoxels/src/DatagramSequencer.h index 44d3c83116..0d9fc0d2b7 100644 --- a/libraries/metavoxels/src/DatagramSequencer.h +++ b/libraries/metavoxels/src/DatagramSequencer.h @@ -58,7 +58,7 @@ public: /// Returns the output channel at the specified index, creating it if necessary. ReliableChannel* getReliableOutputChannel(int index = 0); - /// Returns the intput channel at the + /// Returns the intput channel at the specified index, creating it if necessary. ReliableChannel* getReliableInputChannel(int index = 0); /// Starts a new packet for transmission. @@ -208,6 +208,7 @@ public: int getIndex() const { return _index; } + QBuffer& getBuffer() { return _buffer; } QDataStream& getDataStream() { return _dataStream; } Bitstream& getBitstream() { return _bitstream; } diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index ec8b474f33..edfc45ac0d 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -17,9 +17,13 @@ MetavoxelTests::MetavoxelTests(int& argc, char** argv) : QCoreApplication(argc, argv) { } +static int datagramsSent = 0; +static int datagramsReceived = 0; static int highPriorityMessagesSent = 0; static int unreliableMessagesSent = 0; static int unreliableMessagesReceived = 0; +static int streamedBytesSent = 0; +static int lowPriorityStreamedBytesSent = 0; bool MetavoxelTests::run() { @@ -43,15 +47,31 @@ bool MetavoxelTests::run() { } } - qDebug() << "Sent " << highPriorityMessagesSent << " high priority messages"; - - qDebug() << "Sent " << unreliableMessagesSent << " unreliable messages, received " << unreliableMessagesReceived; + qDebug() << "Sent" << highPriorityMessagesSent << "high priority messages"; + qDebug() << "Sent" << unreliableMessagesSent << "unreliable messages, received" << unreliableMessagesReceived; + qDebug() << "Sent" << streamedBytesSent << "streamed bytes"; + qDebug() << "Sent" << lowPriorityStreamedBytesSent << "low-priority streamed bytes"; + qDebug() << "Sent" << datagramsSent << "datagrams, received" << datagramsReceived; qDebug() << "All tests passed!"; return false; } +static QByteArray createRandomBytes(int minimumSize, int maximumSize) { + QByteArray bytes(randIntInRange(minimumSize, maximumSize), 0); + for (int i = 0; i < bytes.size(); i++) { + bytes[i] = rand(); + } + return bytes; +} + +static QByteArray createRandomBytes() { + const int MIN_BYTES = 4; + const int MAX_BYTES = 16; + return createRandomBytes(MIN_BYTES, MAX_BYTES); +} + Endpoint::Endpoint(const QByteArray& datagramHeader) : _sequencer(new DatagramSequencer(datagramHeader)), _highPriorityMessagesToSend(0.0f) { @@ -60,16 +80,17 @@ Endpoint::Endpoint(const QByteArray& datagramHeader) : connect(_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readMessage(Bitstream&))); connect(_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleHighPriorityMessage(const QVariant&))); -} - -static QByteArray createRandomBytes() { - const int MIN_BYTES = 4; - const int MAX_BYTES = 16; - QByteArray bytes(randIntInRange(MIN_BYTES, MAX_BYTES), 0); - for (int i = 0; i < bytes.size(); i++) { - bytes[i] = rand(); - } - return bytes; + connect(&_sequencer->getReliableInputChannel()->getBuffer(), SIGNAL(readyRead()), SLOT(readReliableChannel())); + connect(&_sequencer->getReliableInputChannel(1)->getBuffer(), SIGNAL(readyRead()), SLOT(readLowPriorityReliableChannel())); + + // enqueue a large amount of data in a low-priority channel + ReliableChannel* output = _sequencer->getReliableOutputChannel(1); + output->setPriority(0.25f); + const int MIN_LOW_PRIORITY_DATA = 100000; + const int MAX_LOW_PRIORITY_DATA = 200000; + _lowPriorityDataStreamed = createRandomBytes(MIN_LOW_PRIORITY_DATA, MAX_LOW_PRIORITY_DATA); + output->getBuffer().write(_lowPriorityDataStreamed); + lowPriorityStreamedBytesSent += _lowPriorityDataStreamed.size(); } static QVariant createRandomMessage() { @@ -123,6 +144,14 @@ bool Endpoint::simulate(int iterationNumber) { _highPriorityMessagesToSend -= 1.0f; } + // stream some random data + const int MIN_BYTES_TO_STREAM = 10; + const int MAX_BYTES_TO_STREAM = 100; + QByteArray bytes = createRandomBytes(MIN_BYTES_TO_STREAM, MAX_BYTES_TO_STREAM); + _dataStreamed.append(bytes); + streamedBytesSent += bytes.size(); + _sequencer->getReliableOutputChannel()->getDataStream().writeRawData(bytes.constData(), bytes.size()); + // send a packet try { Bitstream& out = _sequencer->startPacket(); @@ -141,12 +170,15 @@ bool Endpoint::simulate(int iterationNumber) { } void Endpoint::sendDatagram(const QByteArray& datagram) { + datagramsSent++; + // some datagrams are dropped const float DROP_PROBABILITY = 0.1f; if (randFloat() < DROP_PROBABILITY) { return; } _other->_sequencer->receivedDatagram(datagram); + datagramsReceived++; } void Endpoint::handleHighPriorityMessage(const QVariant& message) { @@ -176,3 +208,29 @@ void Endpoint::readMessage(Bitstream& in) { } throw QString("Received unsent/already sent unreliable message."); } + +void Endpoint::readReliableChannel() { + QByteArray bytes = _sequencer->getReliableInputChannel()->getBuffer().readAll(); + if (_other->_dataStreamed.size() < bytes.size()) { + throw QString("Received unsent/already sent streamed data."); + } + QByteArray compare = _other->_dataStreamed; + _other->_dataStreamed = _other->_dataStreamed.mid(bytes.size()); + compare.truncate(bytes.size()); + if (compare != bytes) { + throw QString("Sent/received streamed data mismatch."); + } +} + +void Endpoint::readLowPriorityReliableChannel() { + QByteArray bytes = _sequencer->getReliableInputChannel(1)->getBuffer().readAll(); + if (_other->_lowPriorityDataStreamed.size() < bytes.size()) { + throw QString("Received unsent/already sent low-priority streamed data."); + } + QByteArray compare = _other->_lowPriorityDataStreamed; + _other->_lowPriorityDataStreamed = _other->_lowPriorityDataStreamed.mid(bytes.size()); + compare.truncate(bytes.size()); + if (compare != bytes) { + throw QString("Sent/received low-priority streamed data mismatch."); + } +} diff --git a/tests/metavoxels/src/MetavoxelTests.h b/tests/metavoxels/src/MetavoxelTests.h index fb47d9f463..7c2bd29b2f 100644 --- a/tests/metavoxels/src/MetavoxelTests.h +++ b/tests/metavoxels/src/MetavoxelTests.h @@ -49,6 +49,8 @@ private slots: void sendDatagram(const QByteArray& datagram); void handleHighPriorityMessage(const QVariant& message); void readMessage(Bitstream& in); + void readReliableChannel(); + void readLowPriorityReliableChannel(); private: @@ -57,6 +59,8 @@ private: float _highPriorityMessagesToSend; QVariantList _highPriorityMessagesSent; QList _unreliableMessagesSent; + QByteArray _dataStreamed; + QByteArray _lowPriorityDataStreamed; }; /// A simple test message.