diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 56d5e041a9..c7fd6090cf 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -22,11 +22,9 @@ OctreeQueryNode::OctreeQueryNode() : _viewSent(false), - _octreePacket(new unsigned char[MAX_PACKET_SIZE]), - _octreePacketAt(_octreePacket), - _octreePacketAvailableBytes(MAX_PACKET_SIZE), + _octreePacket(), _octreePacketWaiting(false), - _lastOctreePacket(new unsigned char[MAX_PACKET_SIZE]), + _lastOctreePayload(new char[MAX_PACKET_SIZE]), _lastOctreePacketLength(0), _duplicatePacketCount(0), _firstSuppressedPacket(usecTimestampNow()), @@ -55,9 +53,8 @@ OctreeQueryNode::~OctreeQueryNode() { if (_octreeSendThread) { forceNodeShutdown(); } - - delete[] _octreePacket; - delete[] _lastOctreePacket; + + delete[] _lastOctreePayload; } void OctreeQueryNode::nodeKilled() { @@ -74,7 +71,7 @@ void OctreeQueryNode::forceNodeShutdown() { _isShuttingDown = true; elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications if (_octreeSendThread) { - // we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually + // we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually // shuts down because we really need it to shutdown, and it's ok if we wait for it to complete OctreeSendThread* sendThread = _octreeSendThread; _octreeSendThread = NULL; @@ -96,8 +93,8 @@ void OctreeQueryNode::sendThreadFinished() { } void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) { - _octreeSendThread = new OctreeSendThread(myServer, node); - + _octreeSendThread = new OctreeSendThread(myServer, node); + // we want to be notified when the thread finishes connect(_octreeSendThread, &GenericThread::finished, this, &OctreeQueryNode::sendThreadFinished); _octreeSendThread->initialize(true); @@ -110,12 +107,11 @@ bool OctreeQueryNode::packetIsDuplicate() const { } // since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp // of the entire packet, we need to compare only the packet content... - int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(_myPacketType); - + if (_lastOctreePacketLength == getPacketLength()) { - if (memcmp(_lastOctreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE), - _octreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE), - getPacketLength() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE)) == 0) { + if (memcmp(_lastOctreePayload + OCTREE_PACKET_EXTRA_HEADERS_SIZE, + _octreePacket->getPayload() + OCTREE_PACKET_EXTRA_HEADERS_SIZE, + _octreePacket->getSizeUsed() - OCTREE_PACKET_EXTRA_HEADERS_SIZE) == 0) { return true; } } @@ -163,6 +159,9 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() { void OctreeQueryNode::init() { _myPacketType = getMyPacketType(); + + _octreePacket = NLPacket::create(getMyPacketType()); + resetOctreePacket(); // don't bump sequence } @@ -177,8 +176,8 @@ void OctreeQueryNode::resetOctreePacket() { // changed since we last reset it. Since we know that no two packets can ever be identical without being the same // scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing // packet send rate. - _lastOctreePacketLength = getPacketLength(); - memcpy(_lastOctreePacket, _octreePacket, _lastOctreePacketLength); + _lastOctreePacketLength = _octreePacket->getSizeUsed(); + memcpy(_lastOctreePayload, _octreePacket->getPayload(), _lastOctreePacketLength); // If we're moving, and the client asked for low res, then we force monochrome, otherwise, use // the clients requested color state. @@ -192,31 +191,17 @@ void OctreeQueryNode::resetOctreePacket() { setAtBit(flags, PACKET_IS_COMPRESSED_BIT); } - _octreePacketAvailableBytes = MAX_PACKET_SIZE; - int numBytesPacketHeader = DependencyManager::get()->populatePacketHeader(reinterpret_cast(_octreePacket), - _myPacketType); - - _octreePacketAt = _octreePacket + numBytesPacketHeader; - _octreePacketAvailableBytes -= numBytesPacketHeader; + _octreePacket->reset(); // pack in flags - OCTREE_PACKET_FLAGS* flagsAt = (OCTREE_PACKET_FLAGS*)_octreePacketAt; - *flagsAt = flags; - _octreePacketAt += sizeof(OCTREE_PACKET_FLAGS); - _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_FLAGS); + _octreePacket->write(&flags, sizeof(flags)); // pack in sequence number - OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt; - *sequenceAt = _sequenceNumber; - _octreePacketAt += sizeof(OCTREE_PACKET_SEQUENCE); - _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SEQUENCE); + _octreePacket->write(&_sequenceNumber, sizeof(_sequenceNumber)); // pack in timestamp OCTREE_PACKET_SENT_TIME now = usecTimestampNow(); - OCTREE_PACKET_SENT_TIME* timeAt = (OCTREE_PACKET_SENT_TIME*)_octreePacketAt; - *timeAt = now; - _octreePacketAt += sizeof(OCTREE_PACKET_SENT_TIME); - _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SENT_TIME); + _octreePacket->write(&now, sizeof(now)); _octreePacketWaiting = false; } @@ -230,14 +215,11 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by // compressed packets include lead bytes which contain compressed size, this allows packing of // multiple compressed portions together if (_currentPacketIsCompressed) { - *(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)_octreePacketAt = bytes; - _octreePacketAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); - _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); + OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionSize = bytes; + _octreePacket->write(§ionSize, sizeof(sectionSize)); } - if (bytes <= _octreePacketAvailableBytes) { - memcpy(_octreePacketAt, buffer, bytes); - _octreePacketAvailableBytes -= bytes; - _octreePacketAt += bytes; + if (bytes <= _octreePacket->bytesAvailable()) { + _octreePacket->write(buffer, bytes); _octreePacketWaiting = true; } } @@ -258,8 +240,8 @@ bool OctreeQueryNode::updateCurrentViewFrustum() { float originalFOV = getCameraFov(); float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND; - if (0.0f != getCameraAspectRatio() && - 0.0f != getCameraNearClip() && + if (0.0f != getCameraAspectRatio() && + 0.0f != getCameraNearClip() && 0.0f != getCameraFarClip()) { newestViewFrustum.setProjection(glm::perspective( glm::radians(wideFOV), // hack @@ -351,7 +333,7 @@ void OctreeQueryNode::dumpOutOfView() { if (_isShuttingDown) { return; } - + int stillInView = 0; int outOfView = 0; OctreeElementBag tempBag; @@ -374,15 +356,7 @@ void OctreeQueryNode::dumpOutOfView() { } } -void OctreeQueryNode::octreePacketSent() { - packetSent(_octreePacket, getPacketLength()); -} - -void OctreeQueryNode::packetSent(unsigned char* packet, int packetLength) { - packetSent(QByteArray((char*)packet, packetLength)); -} - -void OctreeQueryNode::packetSent(const QByteArray& packet) { +void OctreeQueryNode::packetSent(const NLPacket& packet) { _sentPacketHistory.packetSent(_sequenceNumber, packet); _sequenceNumber++; } @@ -391,12 +365,13 @@ bool OctreeQueryNode::hasNextNackedPacket() const { return !_nackedSequenceNumbers.isEmpty(); } -const QByteArray* OctreeQueryNode::getNextNackedPacket() { +NLPacket&& OctreeQueryNode::getNextNackedPacket() { if (!_nackedSequenceNumbers.isEmpty()) { // could return null if packet is not in the history - return _sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue()); + return std::move(_sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue())); } - return NULL; + + return nullptr; } void OctreeQueryNode::parseNackPacket(const QByteArray& packet) { diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 32b09094b9..9838f3b737 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -41,8 +41,7 @@ public: void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet - const unsigned char* getPacket() const { return _octreePacket; } - unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); } + NLPacket& getPacket() const { return _octreePacket; } bool isPacketWaiting() const { return _octreePacketWaiting; } bool packetIsDuplicate() const; @@ -62,7 +61,7 @@ public: ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; } ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; } - + // These are not classic setters because they are calculating and maintaining state // which is set asynchronously through the network receive bool updateCurrentViewFrustum(); @@ -86,49 +85,46 @@ public: } bool hasLodChanged() const { return _lodChanged; } - + OctreeSceneStats stats; - + void initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node); bool isOctreeSendThreadInitalized() { return _octreeSendThread; } - + void dumpOutOfView(); - + quint64 getLastRootTimestamp() const { return _lastRootTimestamp; } void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; } unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; } int getDuplicatePacketCount() const { return _duplicatePacketCount; } void sceneStart(quint64 sceneSendStartTime) { _sceneSendStartTime = sceneSendStartTime; } - + void nodeKilled(); void forceNodeShutdown(); bool isShuttingDown() const { return _isShuttingDown; } - void octreePacketSent(); - void packetSent(unsigned char* packet, int packetLength); - void packetSent(const QByteArray& packet); + void octreePacketSent() { packetSent(_octreePacket); } + void packetSent(const NLPacket& packet); OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; } void parseNackPacket(const QByteArray& packet); bool hasNextNackedPacket() const; - const QByteArray* getNextNackedPacket(); + NLPacket&& getNextNackedPacket(); private slots: void sendThreadFinished(); - + private: OctreeQueryNode(const OctreeQueryNode &); OctreeQueryNode& operator= (const OctreeQueryNode&); - + bool _viewSent; - unsigned char* _octreePacket; - unsigned char* _octreePacketAt; - unsigned int _octreePacketAvailableBytes; + std::unique_ptr _octreePacket; bool _octreePacketWaiting; - unsigned char* _lastOctreePacket; + char* _lastOctreePayload = nullptr; unsigned int _lastOctreePacketLength; int _duplicatePacketCount; quint64 _firstSuppressedPacket; @@ -154,7 +150,7 @@ private: OCTREE_PACKET_SEQUENCE _sequenceNumber; quint64 _lastRootTimestamp; - + PacketType::Value _myPacketType; bool _isShuttingDown; diff --git a/libraries/networking/src/SentPacketHistory.cpp b/libraries/networking/src/SentPacketHistory.cpp index 39f8a9c26e..8eedf2de05 100644 --- a/libraries/networking/src/SentPacketHistory.cpp +++ b/libraries/networking/src/SentPacketHistory.cpp @@ -13,13 +13,11 @@ #include "SentPacketHistory.h" #include - - - SentPacketHistory::SentPacketHistory(int size) : _sentPackets(size), _newestSequenceNumber(std::numeric_limits::max()) { + } void SentPacketHistory::packetSent(uint16_t sequenceNumber, const QByteArray& packet) { diff --git a/libraries/networking/src/SentPacketHistory.h b/libraries/networking/src/SentPacketHistory.h index 96d10a63cf..e07b128e4a 100644 --- a/libraries/networking/src/SentPacketHistory.h +++ b/libraries/networking/src/SentPacketHistory.h @@ -22,11 +22,11 @@ class SentPacketHistory { public: SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP); - void packetSent(uint16_t sequenceNumber, const QByteArray& packet); + void packetSent(uint16_t sequenceNumber, const NLPacket& packet); const QByteArray* getPacket(uint16_t sequenceNumber) const; private: - RingBufferHistory _sentPackets; // circular buffer + RingBufferHistory _sentPackets; // circular buffer uint16_t _newestSequenceNumber; };