Endpoint::Endpoint(const QByteArray& datagramHeader) : _sequencer(new DatagramSequencer(datagramHeader, this)), _highPriorityMessagesToSend(0.0f), _reliableMessagesToSend(0.0f) { connect(_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendDatagram(const QByteArray&))); connect(_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readMessage(Bitstream&))); connect(_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleHighPriorityMessage(const QVariant&))); connect(_sequencer->getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)), SLOT(handleReliableMessage(const QVariant&))); ReliableChannel* secondInput = _sequencer->getReliableInputChannel(1); secondInput->setMessagesEnabled(false); connect(&secondInput->getBuffer(), SIGNAL(readyRead()), SLOT(readReliableChannel())); // enqueue a large amount of data in a low-priority channel ReliableChannel* output = _sequencer->getReliableOutputChannel(1); output->setPriority(0.25f); output->setMessagesEnabled(false); const int MIN_STREAM_BYTES = 100000; const int MAX_STREAM_BYTES = 200000; QByteArray bytes = createRandomBytes(MIN_STREAM_BYTES, MAX_STREAM_BYTES); _dataStreamed.append(bytes); output->getBuffer().write(bytes); streamedBytesSent += bytes.size(); }
static TestMessageC createRandomMessageC() { TestMessageC message; message.foo = randomBoolean(); message.bar = rand(); message.baz = randFloat(); message.bong.foo = createRandomBytes(); message.bong.baz = getRandomTestEnum(); return message; }
static QVariant createRandomMessage() { switch (randIntInRange(0, 2)) { case 0: { TestMessageA message = { randomBoolean(), rand(), randFloat() }; return QVariant::fromValue(message); } case 1: { TestMessageB message = { createRandomBytes() }; return QVariant::fromValue(message); } case 2: default: { TestMessageC message; message.foo = randomBoolean(); message.bar = rand(); message.baz = randFloat(); message.bong.foo = createRandomBytes(); return QVariant::fromValue(message); } } }
static QVariant createRandomMessage() { switch (randIntInRange(0, 2)) { case 0: { TestMessageA message = { randomBoolean(), rand(), randFloat() }; return QVariant::fromValue(message); } case 1: { TestMessageB message = { createRandomBytes(), createRandomSharedObject(), getRandomTestEnum() }; return QVariant::fromValue(message); } default: { return QVariant::fromValue(createRandomMessageC()); } } }
Endpoint::Endpoint(const QByteArray& datagramHeader) : _sequencer(new DatagramSequencer(datagramHeader, this)), _highPriorityMessagesToSend(0.0f), _reliableMessagesToSend(0.0f) { connect(_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendDatagram(const QByteArray&))); connect(_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readMessage(Bitstream&))); connect(_sequencer, SIGNAL(receivedHighPriorityMessage(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); // create the object that represents out delta-encoded state _localState = new TestSharedObjectA(); connect(_sequencer->getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)), SLOT(handleReliableMessage(const QVariant&))); ReliableChannel* secondInput = _sequencer->getReliableInputChannel(1); secondInput->setMessagesEnabled(false); connect(&secondInput->getBuffer(), SIGNAL(readyRead()), SLOT(readReliableChannel())); // enqueue a large amount of data in a low-priority channel ReliableChannel* output = _sequencer->getReliableOutputChannel(1); output->setPriority(0.25f); output->setMessagesEnabled(false); const int MIN_STREAM_BYTES = 100000; const int MAX_STREAM_BYTES = 200000; QByteArray bytes = createRandomBytes(MIN_STREAM_BYTES, MAX_STREAM_BYTES); _dataStreamed.append(bytes); output->getBuffer().write(bytes); streamedBytesSent += bytes.size(); }
static QByteArray createRandomBytes() { const int MIN_BYTES = 4; const int MAX_BYTES = 16; return createRandomBytes(MIN_BYTES, MAX_BYTES); }
static bool testSerialization(Bitstream::MetadataType metadataType) { QByteArray array; QDataStream outStream(&array, QIODevice::WriteOnly); Bitstream out(outStream, metadataType); SharedObjectPointer testObjectWrittenA = new TestSharedObjectA(randFloat(), TestSharedObjectA::SECOND_TEST_ENUM, TestSharedObjectA::TestFlags(TestSharedObjectA::FIRST_TEST_FLAG | TestSharedObjectA::THIRD_TEST_FLAG)); out << testObjectWrittenA; SharedObjectPointer testObjectWrittenB = new TestSharedObjectB(randFloat(), createRandomBytes(), TestSharedObjectB::THIRD_TEST_ENUM, TestSharedObjectB::SECOND_TEST_FLAG); out << testObjectWrittenB; TestMessageC messageWritten = createRandomMessageC(); out << QVariant::fromValue(messageWritten); QByteArray endWritten = "end"; out << endWritten; out.flush(); QDataStream inStream(array); Bitstream in(inStream, metadataType); in.addMetaObjectSubstitution("TestSharedObjectA", &TestSharedObjectB::staticMetaObject); in.addMetaObjectSubstitution("TestSharedObjectB", &TestSharedObjectA::staticMetaObject); in.addTypeSubstitution("TestMessageC", TestMessageA::Type); in.addTypeSubstitution("TestSharedObjectA::TestEnum", "TestSharedObjectB::TestEnum"); in.addTypeSubstitution("TestSharedObjectB::TestEnum", "TestSharedObjectA::TestEnum"); in.addTypeSubstitution("TestSharedObjectA::TestFlags", "TestSharedObjectB::TestFlags"); in.addTypeSubstitution("TestSharedObjectB::TestFlags", "TestSharedObjectA::TestFlags"); SharedObjectPointer testObjectReadA; in >> testObjectReadA; if (!testObjectReadA || testObjectReadA->metaObject() != &TestSharedObjectB::staticMetaObject) { qDebug() << "Wrong class for A" << testObjectReadA << metadataType; return true; } if (metadataType == Bitstream::FULL_METADATA && (static_cast<TestSharedObjectA*>(testObjectWrittenA.data())->getFoo() != static_cast<TestSharedObjectB*>(testObjectReadA.data())->getFoo() || static_cast<TestSharedObjectB*>(testObjectReadA.data())->getBaz() != TestSharedObjectB::SECOND_TEST_ENUM || static_cast<TestSharedObjectB*>(testObjectReadA.data())->getBong() != TestSharedObjectB::TestFlags(TestSharedObjectB::FIRST_TEST_FLAG | TestSharedObjectB::THIRD_TEST_FLAG))) { QDebug debug = qDebug() << "Failed to transfer shared field from A to B"; testObjectWrittenA->dump(debug); testObjectReadA->dump(debug); return true; } SharedObjectPointer testObjectReadB; in >> testObjectReadB; if (!testObjectReadB || testObjectReadB->metaObject() != &TestSharedObjectA::staticMetaObject) { qDebug() << "Wrong class for B" << testObjectReadB << metadataType; return true; } if (metadataType == Bitstream::FULL_METADATA && (static_cast<TestSharedObjectB*>(testObjectWrittenB.data())->getFoo() != static_cast<TestSharedObjectA*>(testObjectReadB.data())->getFoo() || static_cast<TestSharedObjectA*>(testObjectReadB.data())->getBaz() != TestSharedObjectA::THIRD_TEST_ENUM || static_cast<TestSharedObjectA*>(testObjectReadB.data())->getBong() != TestSharedObjectA::SECOND_TEST_FLAG)) { QDebug debug = qDebug() << "Failed to transfer shared field from B to A"; testObjectWrittenB->dump(debug); testObjectReadB->dump(debug); return true; } QVariant messageRead; in >> messageRead; if (!messageRead.isValid() || messageRead.userType() != TestMessageA::Type) { qDebug() << "Wrong type for message" << messageRead; return true; } if (metadataType == Bitstream::FULL_METADATA && messageWritten.foo != messageRead.value<TestMessageA>().foo) { QDebug debug = qDebug() << "Failed to transfer shared field between messages" << messageWritten.foo << messageRead.value<TestMessageA>().foo; return true; } QByteArray endRead; in >> endRead; if (endWritten != endRead) { qDebug() << "End tag mismatch." << endRead; return true; } return false; }