mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 03:15:21 +02:00
Modify tests to use Endpoint base class.
This commit is contained in:
parent
61c2ea40ae
commit
d4470c04d6
2 changed files with 156 additions and 149 deletions
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue