initial changes to OctreeQueryNode for new APIs

This commit is contained in:
Stephen Birarda 2015-07-07 12:08:01 -07:00
parent 474b82e3bf
commit 74924bc5f1
4 changed files with 50 additions and 81 deletions

View file

@ -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<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(_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(&sectionSize, 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) {

View file

@ -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<NLPacket> _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;

View file

@ -13,13 +13,11 @@
#include "SentPacketHistory.h"
#include <qdebug.h>
SentPacketHistory::SentPacketHistory(int size)
: _sentPackets(size),
_newestSequenceNumber(std::numeric_limits<uint16_t>::max())
{
}
void SentPacketHistory::packetSent(uint16_t sequenceNumber, const QByteArray& packet) {

View file

@ -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<QByteArray> _sentPackets; // circular buffer
RingBufferHistory<NLPacket> _sentPackets; // circular buffer
uint16_t _newestSequenceNumber;
};