Modify tests to use Endpoint base class.

This commit is contained in:
Andrzej Kapolka 2014-06-27 12:34:56 -07:00
parent 61c2ea40ae
commit d4470c04d6
2 changed files with 156 additions and 149 deletions

View file

@ -440,6 +440,8 @@ static bool testSerialization(Bitstream::MetadataType metadataType) {
} }
bool MetavoxelTests::run() { bool MetavoxelTests::run() {
LimitedNodeList::createInstance();
// seed the random number generator so that our tests are reproducible // seed the random number generator so that our tests are reproducible
srand(0xBAAAAABE); srand(0xBAAAAABE);
@ -456,14 +458,13 @@ bool MetavoxelTests::run() {
} }
} }
QByteArray datagramHeader("testheader");
const int SIMULATION_ITERATIONS = 10000; const int SIMULATION_ITERATIONS = 10000;
if (test == 0 || test == 2) { if (test == 0 || test == 2) {
qDebug() << "Running transmission test..."; qDebug() << "Running transmission test...";
qDebug(); qDebug();
// create two endpoints with the same header // create two endpoints with the same header
TestEndpoint alice(datagramHeader), bob(datagramHeader); TestEndpoint alice, bob;
alice.setOther(&bob); alice.setOther(&bob);
bob.setOther(&alice); bob.setOther(&alice);
@ -497,7 +498,7 @@ bool MetavoxelTests::run() {
datagramsReceived = bytesReceived = maxDatagramsPerPacket = maxBytesPerPacket = 0; datagramsReceived = bytesReceived = maxDatagramsPerPacket = maxBytesPerPacket = 0;
// create two endpoints with the same header // create two endpoints with the same header
TestEndpoint alice(datagramHeader, TestEndpoint::CONGESTION_MODE), bob(datagramHeader, TestEndpoint::CONGESTION_MODE); TestEndpoint alice(TestEndpoint::CONGESTION_MODE), bob(TestEndpoint::CONGESTION_MODE);
alice.setOther(&bob); alice.setOther(&bob);
bob.setOther(&alice); bob.setOther(&alice);
@ -537,8 +538,8 @@ bool MetavoxelTests::run() {
datagramsSent = bytesSent = datagramsReceived = bytesReceived = maxDatagramsPerPacket = maxBytesPerPacket = 0; datagramsSent = bytesSent = datagramsReceived = bytesReceived = maxDatagramsPerPacket = maxBytesPerPacket = 0;
// create client and server endpoints // create client and server endpoints
TestEndpoint client(datagramHeader, TestEndpoint::METAVOXEL_CLIENT_MODE); TestEndpoint client(TestEndpoint::METAVOXEL_CLIENT_MODE);
TestEndpoint server(datagramHeader, TestEndpoint::METAVOXEL_SERVER_MODE); TestEndpoint server(TestEndpoint::METAVOXEL_SERVER_MODE);
client.setOther(&server); client.setOther(&server);
server.setOther(&client); server.setOther(&client);
@ -599,28 +600,57 @@ int RandomVisitor::visit(MetavoxelInfo& info) {
return STOP_RECURSION; return STOP_RECURSION;
} }
TestEndpoint::TestEndpoint(const QByteArray& datagramHeader, Mode mode) : class TestSendRecord : public PacketRecord {
public:
TestSendRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData(),
const SharedObjectPointer& localState = SharedObjectPointer(), int packetNumber = 0);
const SharedObjectPointer& getLocalState() const { return _localState; }
int getPacketNumber() const { return _packetNumber; }
private:
SharedObjectPointer _localState;
int _packetNumber;
};
TestSendRecord::TestSendRecord(const MetavoxelLOD& lod, const MetavoxelData& data,
const SharedObjectPointer& localState, int packetNumber) :
PacketRecord(lod, data),
_localState(localState),
_packetNumber(packetNumber) {
}
class TestReceiveRecord : public PacketRecord {
public:
TestReceiveRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData(),
const SharedObjectPointer& remoteState = SharedObjectPointer());
const SharedObjectPointer& getRemoteState() const { return _remoteState; }
private:
SharedObjectPointer _remoteState;
};
TestReceiveRecord::TestReceiveRecord(const MetavoxelLOD& lod,
const MetavoxelData& data, const SharedObjectPointer& remoteState) :
PacketRecord(lod, data),
_remoteState(remoteState) {
}
TestEndpoint::TestEndpoint(Mode mode) :
Endpoint(SharedNodePointer(), new TestSendRecord(), new TestReceiveRecord()),
_mode(mode), _mode(mode),
_sequencer(new DatagramSequencer(datagramHeader, this)),
_highPriorityMessagesToSend(0.0f), _highPriorityMessagesToSend(0.0f),
_reliableMessagesToSend(0.0f) { _reliableMessagesToSend(0.0f) {
connect(_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendDatagram(const QByteArray&))); connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)),
connect(_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readMessage(Bitstream&)));
connect(_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)),
SLOT(handleHighPriorityMessage(const QVariant&))); SLOT(handleHighPriorityMessage(const QVariant&)));
connect(_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int)));
connect(_sequencer, SIGNAL(receiveAcknowledged(int)), SLOT(clearReceiveRecordsBefore(int)));
// insert the baseline send record
SendRecord sendRecord = { 0 };
_sendRecords.append(sendRecord);
// insert the baseline receive record
ReceiveRecord receiveRecord = { 0 };
_receiveRecords.append(receiveRecord);
if (mode == METAVOXEL_CLIENT_MODE) { if (mode == METAVOXEL_CLIENT_MODE) {
_lod = MetavoxelLOD(glm::vec3(), 0.01f); _lod = MetavoxelLOD(glm::vec3(), 0.01f);
return; return;
@ -643,15 +673,15 @@ TestEndpoint::TestEndpoint(const QByteArray& datagramHeader, Mode mode) :
// create the object that represents out delta-encoded state // create the object that represents out delta-encoded state
_localState = new TestSharedObjectA(); _localState = new TestSharedObjectA();
connect(_sequencer->getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)), connect(_sequencer.getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)),
SLOT(handleReliableMessage(const QVariant&))); SLOT(handleReliableMessage(const QVariant&)));
ReliableChannel* secondInput = _sequencer->getReliableInputChannel(1); ReliableChannel* secondInput = _sequencer.getReliableInputChannel(1);
secondInput->setMessagesEnabled(false); secondInput->setMessagesEnabled(false);
connect(&secondInput->getBuffer(), SIGNAL(readyRead()), SLOT(readReliableChannel())); connect(&secondInput->getBuffer(), SIGNAL(readyRead()), SLOT(readReliableChannel()));
// enqueue a large amount of data in a low-priority channel // enqueue a large amount of data in a low-priority channel
ReliableChannel* output = _sequencer->getReliableOutputChannel(1); ReliableChannel* output = _sequencer.getReliableOutputChannel(1);
output->setPriority(0.25f); output->setPriority(0.25f);
output->setMessagesEnabled(false); output->setMessagesEnabled(false);
QByteArray bytes; QByteArray bytes;
@ -804,7 +834,7 @@ bool TestEndpoint::simulate(int iterationNumber) {
// update/send our delayed datagrams // update/send our delayed datagrams
for (QList<ByteArrayIntPair>::iterator it = _delayedDatagrams.begin(); it != _delayedDatagrams.end(); ) { for (QList<ByteArrayIntPair>::iterator it = _delayedDatagrams.begin(); it != _delayedDatagrams.end(); ) {
if (it->second-- == 1) { if (it->second-- == 1) {
_other->receiveDatagram(it->first); _other->parseData(it->first);
it = _delayedDatagrams.erase(it); it = _delayedDatagrams.erase(it);
} else { } else {
@ -819,41 +849,39 @@ bool TestEndpoint::simulate(int iterationNumber) {
ByteArrayVector datagrams = _pipeline.takeLast(); ByteArrayVector datagrams = _pipeline.takeLast();
_pipeline.prepend(ByteArrayVector()); _pipeline.prepend(ByteArrayVector());
foreach (const QByteArray& datagram, datagrams) { foreach (const QByteArray& datagram, datagrams) {
_sequencer->receivedDatagram(datagram); _sequencer.receivedDatagram(datagram);
datagramsReceived++; datagramsReceived++;
bytesReceived += datagram.size(); bytesReceived += datagram.size();
_remainingPipelineCapacity += datagram.size(); _remainingPipelineCapacity += datagram.size();
} }
int packetCount = _sequencer->startPacketGroup(); int packetCount = _sequencer.startPacketGroup();
groupsSent++; groupsSent++;
maxPacketsPerGroup = qMax(maxPacketsPerGroup, packetCount); maxPacketsPerGroup = qMax(maxPacketsPerGroup, packetCount);
for (int i = 0; i < packetCount; i++) { for (int i = 0; i < packetCount; i++) {
oldDatagramsSent = datagramsSent; oldDatagramsSent = datagramsSent;
oldBytesSent = bytesSent; oldBytesSent = bytesSent;
Bitstream& out = _sequencer->startPacket(); Bitstream& out = _sequencer.startPacket();
out << QVariant(); out << QVariant();
_sequencer->endPacket(); _sequencer.endPacket();
maxDatagramsPerPacket = qMax(maxDatagramsPerPacket, datagramsSent - oldDatagramsSent); maxDatagramsPerPacket = qMax(maxDatagramsPerPacket, datagramsSent - oldDatagramsSent);
maxBytesPerPacket = qMax(maxBytesPerPacket, bytesSent - oldBytesSent); maxBytesPerPacket = qMax(maxBytesPerPacket, bytesSent - oldBytesSent);
// record the send // record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber() }; _sendRecords.append(maybeCreateSendRecord());
_sendRecords.append(record);
} }
return false; return false;
} else if (_mode == METAVOXEL_CLIENT_MODE) { } else if (_mode == METAVOXEL_CLIENT_MODE) {
Bitstream& out = _sequencer->startPacket(); Bitstream& out = _sequencer.startPacket();
ClientStateMessage state = { _lod }; ClientStateMessage state = { _lod };
out << QVariant::fromValue(state); out << QVariant::fromValue(state);
_sequencer->endPacket(); _sequencer.endPacket();
// record the send // record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber(), SharedObjectPointer(), MetavoxelData(), _lod }; _sendRecords.append(maybeCreateSendRecord());
_sendRecords.append(record);
} else if (_mode == METAVOXEL_SERVER_MODE) { } else if (_mode == METAVOXEL_SERVER_MODE) {
// make a random change // make a random change
@ -879,16 +907,15 @@ bool TestEndpoint::simulate(int iterationNumber) {
if (!_lod.isValid()) { if (!_lod.isValid()) {
return false; return false;
} }
Bitstream& out = _sequencer->startPacket(); Bitstream& out = _sequencer.startPacket();
out << QVariant::fromValue(MetavoxelDeltaMessage()); out << QVariant::fromValue(MetavoxelDeltaMessage());
_data.writeDelta(_sendRecords.first().data, _sendRecords.first().lod, out, _lod); PacketRecord* sendRecord = getLastAcknowledgedSendRecord();
_data.writeDelta(sendRecord->getData(), sendRecord->getLOD(), out, _lod);
_sequencer.endPacket();
// record the send // record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber() + 1, SharedObjectPointer(), _data, _lod }; _sendRecords.append(maybeCreateSendRecord());
_sendRecords.append(record);
_sequencer->endPacket();
} else { } else {
// enqueue some number of high priority messages // enqueue some number of high priority messages
const float MIN_HIGH_PRIORITY_MESSAGES = 0.0f; const float MIN_HIGH_PRIORITY_MESSAGES = 0.0f;
@ -897,7 +924,7 @@ bool TestEndpoint::simulate(int iterationNumber) {
while (_highPriorityMessagesToSend >= 1.0f) { while (_highPriorityMessagesToSend >= 1.0f) {
QVariant message = createRandomMessage(); QVariant message = createRandomMessage();
_highPriorityMessagesSent.append(message); _highPriorityMessagesSent.append(message);
_sequencer->sendHighPriorityMessage(message); _sequencer.sendHighPriorityMessage(message);
highPriorityMessagesSent++; highPriorityMessagesSent++;
_highPriorityMessagesToSend -= 1.0f; _highPriorityMessagesToSend -= 1.0f;
} }
@ -909,7 +936,7 @@ bool TestEndpoint::simulate(int iterationNumber) {
while (_reliableMessagesToSend >= 1.0f) { while (_reliableMessagesToSend >= 1.0f) {
QVariant message = createRandomMessage(); QVariant message = createRandomMessage();
_reliableMessagesSent.append(message); _reliableMessagesSent.append(message);
_sequencer->getReliableOutputChannel()->sendMessage(message); _sequencer.getReliableOutputChannel()->sendMessage(message);
reliableMessagesSent++; reliableMessagesSent++;
_reliableMessagesToSend -= 1.0f; _reliableMessagesToSend -= 1.0f;
} }
@ -919,12 +946,12 @@ bool TestEndpoint::simulate(int iterationNumber) {
// send a packet // send a packet
try { try {
Bitstream& out = _sequencer->startPacket(); Bitstream& out = _sequencer.startPacket();
SequencedTestMessage message = { iterationNumber, createRandomMessage(), _localState }; SequencedTestMessage message = { iterationNumber, createRandomMessage(), _localState };
_unreliableMessagesSent.append(message); _unreliableMessagesSent.append(message);
unreliableMessagesSent++; unreliableMessagesSent++;
out << message; out << message;
_sequencer->endPacket(); _sequencer.endPacket();
} catch (const QString& message) { } catch (const QString& message) {
qDebug() << message; qDebug() << message;
@ -932,14 +959,28 @@ bool TestEndpoint::simulate(int iterationNumber) {
} }
// record the send // record the send
SendRecord record = { _sequencer->getOutgoingPacketNumber(), _localState }; _sendRecords.append(maybeCreateSendRecord());
_sendRecords.append(record);
} }
maxDatagramsPerPacket = qMax(maxDatagramsPerPacket, datagramsSent - oldDatagramsSent); maxDatagramsPerPacket = qMax(maxDatagramsPerPacket, datagramsSent - oldDatagramsSent);
maxBytesPerPacket = qMax(maxBytesPerPacket, bytesSent - oldBytesSent); maxBytesPerPacket = qMax(maxBytesPerPacket, bytesSent - oldBytesSent);
return false; return false;
} }
int TestEndpoint::parseData(const QByteArray& packet) {
if (_mode == CONGESTION_MODE) {
if (packet.size() <= _remainingPipelineCapacity) {
// have to copy the datagram; the one we're passed is a reference to a shared buffer
_pipeline[0].append(QByteArray(packet.constData(), packet.size()));
_remainingPipelineCapacity -= packet.size();
}
} else {
_sequencer.receivedDatagram(packet);
datagramsReceived++;
bytesReceived += packet.size();
}
return packet.size();
}
void TestEndpoint::sendDatagram(const QByteArray& datagram) { void TestEndpoint::sendDatagram(const QByteArray& datagram) {
datagramsSent++; datagramsSent++;
bytesSent += datagram.size(); bytesSent += datagram.size();
@ -967,21 +1008,7 @@ void TestEndpoint::sendDatagram(const QByteArray& datagram) {
} }
} }
_other->receiveDatagram(datagram); _other->parseData(datagram);
}
void TestEndpoint::handleHighPriorityMessage(const QVariant& message) {
if (message.userType() == ClearSharedObjectMessage::Type) {
return;
}
if (_other->_highPriorityMessagesSent.isEmpty()) {
throw QString("Received unsent/already sent high priority message.");
}
QVariant sentMessage = _other->_highPriorityMessagesSent.takeFirst();
if (!messagesEqual(message, sentMessage)) {
throw QString("Sent/received high priority message mismatch.");
}
highPriorityMessagesReceived++;
} }
void TestEndpoint::readMessage(Bitstream& in) { void TestEndpoint::readMessage(Bitstream& in) {
@ -990,8 +1017,7 @@ void TestEndpoint::readMessage(Bitstream& in) {
in >> message; in >> message;
// record the receipt // record the receipt
ReceiveRecord record = { _sequencer->getIncomingPacketNumber() }; _receiveRecords.append(maybeCreateReceiveRecord());
_receiveRecords.append(record);
return; return;
} }
if (_mode == METAVOXEL_CLIENT_MODE) { if (_mode == METAVOXEL_CLIENT_MODE) {
@ -1000,10 +1026,11 @@ void TestEndpoint::readMessage(Bitstream& in) {
handleMessage(message, in); handleMessage(message, in);
// deep-compare data to sent version // deep-compare data to sent version
int packetNumber = _sequencer->getIncomingPacketNumber(); int packetNumber = _sequencer.getIncomingPacketNumber();
foreach (const SendRecord& sendRecord, _other->_sendRecords) { foreach (PacketRecord* record, _other->_sendRecords) {
if (sendRecord.packetNumber == packetNumber) { TestSendRecord* sendRecord = static_cast<TestSendRecord*>(record);
if (!sendRecord.data.deepEquals(_data, _sendRecords.first().lod)) { if (sendRecord->getPacketNumber() == packetNumber) {
if (!sendRecord->getData().deepEquals(_data, getLastAcknowledgedSendRecord()->getLOD())) {
qDebug() << "Sent/received metavoxel data mismatch."; qDebug() << "Sent/received metavoxel data mismatch.";
exit(true); exit(true);
} }
@ -1012,8 +1039,7 @@ void TestEndpoint::readMessage(Bitstream& in) {
} }
// record the receipt // record the receipt
ReceiveRecord record = { packetNumber, SharedObjectPointer(), _data, _sendRecords.first().lod }; _receiveRecords.append(maybeCreateReceiveRecord());
_receiveRecords.append(record);
return; return;
} }
if (_mode == METAVOXEL_SERVER_MODE) { if (_mode == METAVOXEL_SERVER_MODE) {
@ -1022,8 +1048,7 @@ void TestEndpoint::readMessage(Bitstream& in) {
handleMessage(message, in); handleMessage(message, in);
// record the receipt // record the receipt
ReceiveRecord record = { _sequencer->getIncomingPacketNumber() }; _receiveRecords.append(maybeCreateReceiveRecord());
_receiveRecords.append(record);
return; return;
} }
@ -1033,8 +1058,7 @@ void TestEndpoint::readMessage(Bitstream& in) {
_remoteState = message.state; _remoteState = message.state;
// record the receipt // record the receipt
ReceiveRecord record = { _sequencer->getIncomingPacketNumber(), message.state }; _receiveRecords.append(maybeCreateReceiveRecord());
_receiveRecords.append(record);
for (QList<SequencedTestMessage>::iterator it = _other->_unreliableMessagesSent.begin(); for (QList<SequencedTestMessage>::iterator it = _other->_unreliableMessagesSent.begin();
it != _other->_unreliableMessagesSent.end(); it++) { it != _other->_unreliableMessagesSent.end(); it++) {
@ -1056,6 +1080,45 @@ void TestEndpoint::readMessage(Bitstream& in) {
exit(true); exit(true);
} }
void TestEndpoint::handleMessage(const QVariant& message, Bitstream& in) {
int userType = message.userType();
if (userType == ClientStateMessage::Type) {
ClientStateMessage state = message.value<ClientStateMessage>();
_lod = state.lod;
} else if (userType == MetavoxelDeltaMessage::Type) {
PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord();
_data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, getLastAcknowledgedSendRecord()->getLOD());
} else if (userType == QMetaType::QVariantList) {
foreach (const QVariant& element, message.toList()) {
handleMessage(element, in);
}
}
}
PacketRecord* TestEndpoint::maybeCreateSendRecord() const {
return new TestSendRecord(_lod, _data, _localState, _sequencer.getOutgoingPacketNumber());
}
PacketRecord* TestEndpoint::maybeCreateReceiveRecord() const {
return new TestReceiveRecord(getLastAcknowledgedSendRecord()->getLOD(), _data, _remoteState);
}
void TestEndpoint::handleHighPriorityMessage(const QVariant& message) {
if (message.userType() == ClearSharedObjectMessage::Type) {
return;
}
if (_other->_highPriorityMessagesSent.isEmpty()) {
throw QString("Received unsent/already sent high priority message.");
}
QVariant sentMessage = _other->_highPriorityMessagesSent.takeFirst();
if (!messagesEqual(message, sentMessage)) {
throw QString("Sent/received high priority message mismatch.");
}
highPriorityMessagesReceived++;
}
void TestEndpoint::handleReliableMessage(const QVariant& message) { void TestEndpoint::handleReliableMessage(const QVariant& message) {
if (message.userType() == ClearSharedObjectMessage::Type || if (message.userType() == ClearSharedObjectMessage::Type ||
message.userType() == ClearMainChannelSharedObjectMessage::Type) { message.userType() == ClearMainChannelSharedObjectMessage::Type) {
@ -1072,7 +1135,7 @@ void TestEndpoint::handleReliableMessage(const QVariant& message) {
} }
void TestEndpoint::readReliableChannel() { void TestEndpoint::readReliableChannel() {
CircularBuffer& buffer = _sequencer->getReliableInputChannel(1)->getBuffer(); CircularBuffer& buffer = _sequencer.getReliableInputChannel(1)->getBuffer();
QByteArray bytes = buffer.read(buffer.bytesAvailable()); QByteArray bytes = buffer.read(buffer.bytesAvailable());
if (_other->_dataStreamed.size() < bytes.size()) { if (_other->_dataStreamed.size() < bytes.size()) {
throw QString("Received unsent/already sent streamed data."); throw QString("Received unsent/already sent streamed data.");
@ -1085,44 +1148,6 @@ void TestEndpoint::readReliableChannel() {
streamedBytesReceived += bytes.size(); streamedBytesReceived += bytes.size();
} }
void TestEndpoint::clearSendRecordsBefore(int index) {
_sendRecords.erase(_sendRecords.begin(), _sendRecords.begin() + index + 1);
}
void TestEndpoint::clearReceiveRecordsBefore(int index) {
_receiveRecords.erase(_receiveRecords.begin(), _receiveRecords.begin() + index + 1);
}
void TestEndpoint::receiveDatagram(const QByteArray& datagram) {
if (_mode == CONGESTION_MODE) {
if (datagram.size() <= _remainingPipelineCapacity) {
// have to copy the datagram; the one we're passed is a reference to a shared buffer
_pipeline[0].append(QByteArray(datagram.constData(), datagram.size()));
_remainingPipelineCapacity -= datagram.size();
}
} else {
_sequencer->receivedDatagram(datagram);
datagramsReceived++;
bytesReceived += datagram.size();
}
}
void TestEndpoint::handleMessage(const QVariant& message, Bitstream& in) {
int userType = message.userType();
if (userType == ClientStateMessage::Type) {
ClientStateMessage state = message.value<ClientStateMessage>();
_lod = state.lod;
} else if (userType == MetavoxelDeltaMessage::Type) {
_data.readDelta(_receiveRecords.first().data, _receiveRecords.first().lod, in, _sendRecords.first().lod);
} else if (userType == QMetaType::QVariantList) {
foreach (const QVariant& element, message.toList()) {
handleMessage(element, in);
}
}
}
TestSharedObjectA::TestSharedObjectA(float foo, TestEnum baz, TestFlags bong) : TestSharedObjectA::TestSharedObjectA(float foo, TestEnum baz, TestFlags bong) :
_foo(foo), _foo(foo),
_baz(baz), _baz(baz),

View file

@ -15,8 +15,7 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QVariantList> #include <QVariantList>
#include <DatagramSequencer.h> #include <Endpoint.h>
#include <MetavoxelData.h>
#include <ScriptCache.h> #include <ScriptCache.h>
class SequencedTestMessage; class SequencedTestMessage;
@ -35,14 +34,14 @@ public:
}; };
/// Represents a simulated endpoint. /// Represents a simulated endpoint.
class TestEndpoint : public QObject { class TestEndpoint : public Endpoint {
Q_OBJECT Q_OBJECT
public: public:
enum Mode { BASIC_PEER_MODE, CONGESTION_MODE, METAVOXEL_SERVER_MODE, METAVOXEL_CLIENT_MODE }; enum Mode { BASIC_PEER_MODE, CONGESTION_MODE, METAVOXEL_SERVER_MODE, METAVOXEL_CLIENT_MODE };
TestEndpoint(const QByteArray& datagramHeader, Mode mode = BASIC_PEER_MODE); TestEndpoint(Mode mode = BASIC_PEER_MODE);
void setOther(TestEndpoint* other) { _other = other; } void setOther(TestEndpoint* other) { _other = other; }
@ -50,45 +49,28 @@ public:
/// \return true if failure was detected /// \return true if failure was detected
bool simulate(int iterationNumber); bool simulate(int iterationNumber);
private slots: virtual int parseData(const QByteArray& packet);
protected:
void sendDatagram(const QByteArray& datagram); virtual void sendDatagram(const QByteArray& data);
virtual void readMessage(Bitstream& in);
virtual void handleMessage(const QVariant& message, Bitstream& in);
virtual PacketRecord* maybeCreateSendRecord() const;
virtual PacketRecord* maybeCreateReceiveRecord() const;
private slots:
void handleHighPriorityMessage(const QVariant& message); void handleHighPriorityMessage(const QVariant& message);
void readMessage(Bitstream& in);
void handleReliableMessage(const QVariant& message); void handleReliableMessage(const QVariant& message);
void readReliableChannel(); void readReliableChannel();
void clearSendRecordsBefore(int index);
void clearReceiveRecordsBefore(int index);
private: private:
void receiveDatagram(const QByteArray& datagram);
void handleMessage(const QVariant& message, Bitstream& in);
class SendRecord {
public:
int packetNumber;
SharedObjectPointer localState;
MetavoxelData data;
MetavoxelLOD lod;
};
class ReceiveRecord {
public:
int packetNumber;
SharedObjectPointer remoteState;
MetavoxelData data;
MetavoxelLOD lod;
};
Mode _mode; Mode _mode;
DatagramSequencer* _sequencer;
QList<SendRecord> _sendRecords;
QList<ReceiveRecord> _receiveRecords;
SharedObjectPointer _localState; SharedObjectPointer _localState;
SharedObjectPointer _remoteState; SharedObjectPointer _remoteState;