cleanup octree networking code to use new API

This commit is contained in:
Stephen Birarda 2015-07-13 09:40:26 -07:00
parent ffcd8e1613
commit 3d62162812
20 changed files with 186 additions and 257 deletions

View file

@ -938,7 +938,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
// setup the extended header for the domain list packets
// this data is at the beginning of each of the domain list packets
QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0);
QDataStream extendedHeaderStream(&extendedHeader, &QIODevice::Append);
QDataStream extendedHeaderStream(&extendedHeader, QIODevice::Append);
extendedHeaderStream << limitedNodeList->getSessionUUID().toRfc4122();
extendedHeaderStream << node->getUUID().toRfc4122();

View file

@ -3925,70 +3925,70 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar
}
}
int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) {
int Application::processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
// parse the incoming stats datas stick it in a temporary object for now, while we
// determine which server it belongs to
OctreeSceneStats temp;
int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
int statsMessageLength = 0;
// quick fix for crash... why would voxelServer be NULL?
if (sendingNode) {
QUuid nodeUUID = sendingNode->getUUID();
const QUuid& nodeUUID = sendingNode->getUUID();
OctreeSceneStats* octreeStats;
// now that we know the node ID, let's add these stats to the stats for that node...
_octreeSceneStatsLock.lockForWrite();
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
_octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()),
packet.size());
} else {
_octreeServerSceneStats[nodeUUID] = temp;
// now that we know the node ID, let's add these stats to the stats for that node...
_octreeSceneStatsLock.lockForWrite();
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
octreeStats = &_octreeServerSceneStats[nodeUUID];
statsMessageLength = octreeStats->unpackFromPacket(*packet);
} else {
OctreeSceneStats temp;
statsMessageLength = temp.unpackFromPacket(*packet);
octreeStats = &temp;
}
_octreeSceneStatsLock.unlock();
VoxelPositionSize rootDetails;
voxelDetailsForCode(octreeStats->getJurisdictionRoot(), rootDetails);
// see if this is the first we've heard of this node...
NodeToJurisdictionMap* jurisdiction = NULL;
QString serverType;
if (sendingNode->getType() == NodeType::EntityServer) {
jurisdiction = &_entityServerJurisdictions;
serverType = "Entity";
}
jurisdiction->lockForRead();
if (jurisdiction->find(nodeUUID) == jurisdiction->end()) {
jurisdiction->unlock();
qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]",
qPrintable(serverType),
(double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
// Add the jurisditionDetails object to the list of "fade outs"
if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) {
OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
fade.voxelDetails = rootDetails;
const float slightly_smaller = 0.99f;
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_octreeFadesLock.lockForWrite();
_octreeFades.push_back(fade);
_octreeFadesLock.unlock();
}
_octreeSceneStatsLock.unlock();
VoxelPositionSize rootDetails;
voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails);
// see if this is the first we've heard of this node...
NodeToJurisdictionMap* jurisdiction = NULL;
QString serverType;
if (sendingNode->getType() == NodeType::EntityServer) {
jurisdiction = &_entityServerJurisdictions;
serverType = "Entity";
}
jurisdiction->lockForRead();
if (jurisdiction->find(nodeUUID) == jurisdiction->end()) {
jurisdiction->unlock();
qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]",
qPrintable(serverType),
(double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
// Add the jurisditionDetails object to the list of "fade outs"
if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) {
OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
fade.voxelDetails = rootDetails;
const float slightly_smaller = 0.99f;
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_octreeFadesLock.lockForWrite();
_octreeFades.push_back(fade);
_octreeFadesLock.unlock();
}
} else {
jurisdiction->unlock();
}
// store jurisdiction details for later use
// This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it
// but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the
// details from the OctreeSceneStats to construct the JurisdictionMap
JurisdictionMap jurisdictionMap;
jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes());
jurisdiction->lockForWrite();
(*jurisdiction)[nodeUUID] = jurisdictionMap;
} else {
jurisdiction->unlock();
}
// store jurisdiction details for later use
// This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it
// but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the
// details from the OctreeSceneStats to construct the JurisdictionMap
JurisdictionMap jurisdictionMap;
jurisdictionMap.copyContents(octreeStats->getJurisdictionRoot(), octreeStats->getJurisdictionEndNodes());
jurisdiction->lockForWrite();
(*jurisdiction)[nodeUUID] = jurisdictionMap;
jurisdiction->unlock();
return statsMessageLength;
}

View file

@ -612,7 +612,7 @@ private:
StDev _idleLoopStdev;
float _idleLoopMeasuredJitter;
int parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode);
int processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket);
NodeToJurisdictionMap _entityServerJurisdictions;

View file

@ -1,4 +1,4 @@
//Merge branch 'master' of ssh://github.com/highfidelity/hifi into isentropic/
//
// OctreePacketProcessor.cpp
// interface/src/octree
//
@ -18,54 +18,41 @@
OctreePacketProcessor::OctreePacketProcessor() {
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleEntityDataPacket");
packetReceiver.registerPacketListener(PacketType::EntityData, this, "handleEntityDataPacket");
packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleEntityErasePacket");
packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleOctreeStatsPacket");
packetReceiver.registerPacketListener(PacketType::EnvironmentData, this, "handleEnvironmentDataPacket");
QSet<PacketType::Value> types {
PacketType::OctreeStats, PacketType::EntityData,
PacketType::EntityErase, PacketType::OctreeStats, PacketType::EnvironmentData
}
packetReceiver.registerPacketListeners(types, this, "handleOctreePacket");
}
// TODO implement packet processing in PacketType-specific methods
void OctreePacketProcessor::handleEntityDataPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) {
queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()));
void OctreePacketProcessor::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) {
queueReceivedPacket(senderNode, packet);
}
void OctreePacketProcessor::handleEntityErasePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) {
queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()));
}
void OctreePacketProcessor::handleOctreeStatsPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) {
queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()));
}
void OctreePacketProcessor::handleEnvironmentDataPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) {
queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()));
}
void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) {
void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"OctreePacketProcessor::processPacket()");
QByteArray mutablePacket = packet;
const int WAY_BEHIND = 300;
if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) {
qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
}
int messageLength = mutablePacket.size();
int messageLength = packet->getSizeUsed();
Application* app = Application::getInstance();
bool wasStatsPacket = false;
PacketType::Value voxelPacketType = packetTypeForPacket(mutablePacket);
PacketType::Value octreePacketType = packet->getType();
// note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first
// then process any remaining bytes as if it was another packet
if (voxelPacketType == PacketType::OctreeStats) {
int statsMessageLength = app->parseOctreeStats(mutablePacket, sendingNode);
if (octreePacketType == PacketType::OctreeStats) {
int statsMessageLength = app->processOctreeStats(packet, sendingNode);
wasStatsPacket = true;
if (messageLength > statsMessageLength) {
mutablePacket = mutablePacket.mid(statsMessageLength);
@ -104,29 +91,26 @@ void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode,
app->trackIncomingOctreePacket(mutablePacket, sendingNode, wasStatsPacket);
if (sendingNode) {
switch(voxelPacketType) {
case PacketType::EntityErase: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processEraseMessage(mutablePacket, sendingNode);
}
} break;
switch(voxelPacketType) {
case PacketType::EntityErase: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processEraseMessage(mutablePacket, sendingNode);
}
} break;
case PacketType::EntityData: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processDatagram(mutablePacket, sendingNode);
}
} break;
case PacketType::EntityData: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processDatagram(mutablePacket, sendingNode);
}
} break;
case PacketType::EnvironmentData: {
app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket);
} break;
case PacketType::EnvironmentData: {
app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket);
} break;
default: {
// nothing to do
} break;
}
default: {
// nothing to do
} break;
}
}

View file

@ -14,7 +14,7 @@
#include <ReceivedPacketProcessor.h>
/// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes
/// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
class OctreePacketProcessor : public ReceivedPacketProcessor {
Q_OBJECT
@ -25,12 +25,9 @@ signals:
void packetVersionMismatch();
protected:
virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet);
virtual void processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
private slots:
void handleEntityDataPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr);
void handleEntityErasePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr);
void handleOctreeStatsPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr);
void handleEnvironmentDataPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr);
void handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
};
#endif // hifi_OctreePacketProcessor_h

View file

@ -38,6 +38,7 @@ const quint64 DOMAIN_SERVER_CHECK_IN_MSECS = 1 * 1000;
const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5;
using NodePacketPair = std::pair<SharedNodePointer, std::unique_ptr<NLPacket>>;
using NodeSharedPacketPair = std::pair<SharedNodePointer, QSharedPointer<NLPacket>>;
class Application;
class Assignment;

View file

@ -24,6 +24,12 @@ PacketReceiver::PacketReceiver(QObject* parent) :
}
void PacketReceiver::registerPacketListeners(const QSet<PacketType::Value>& types, QObject* object, const char* slot) {
foreach(PacketType::Value type, types) {
registerPacketListener(type, object, slot);
}
}
void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, const char* slot) {
Q_ASSERT(object);

View file

@ -17,6 +17,7 @@
#include <QtCore/QMetaMethod>
#include <QtCore/QMutex>
#include <QtCore/QObject>
#include <QtCore/QSet>
#include "NLPacket.h"
#include "PacketHeaders.h"
@ -37,7 +38,8 @@ public:
void resetCounters() { _inPacketCount = 0; _outPacketCount = 0; _inByteCount = 0; _outByteCount = 0; }
void shutdown() { _isShuttingDown = true; }
void registerPacketListeners(const QSet<PacketType::Value>& types, QObject* listener, const char* slot);
void registerPacketListener(PacketType::Value type, QObject* listener, const char* slot);
public slots:

View file

@ -24,15 +24,9 @@ void ReceivedPacketProcessor::terminating() {
_hasPackets.wakeAll();
}
void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) {
// Make sure our Node and NodeList knows we've heard from this node.
sendingNode->setLastHeardMicrostamp(usecTimestampNow());
// TODO: fix the NodePacketPair once we've figured out receive API
NodePacketPair networkPacket(sendingNode, NLPacket::create(PacketType::OctreeStats));
void ReceivedPacketProcessor::queueReceivedPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
lock();
_packets.push_back(std::move(networkPacket));
_packets.push_back({ sendingNode, packet });
_nodePacketCounts[sendingNode->getUUID()]++;
_lastWindowIncomingPackets++;
unlock();
@ -73,13 +67,12 @@ bool ReceivedPacketProcessor::process() {
}
lock();
std::list<NodePacketPair> currentPackets;
std::list<NodeSharedPacketPair> currentPackets;
currentPackets.swap(_packets);
unlock();
for(auto& packetPair : currentPackets) {
// TODO: Replace QByteArray() once NLPacket is coming through on receive side
processPacket(packetPair.first, QByteArray());
processPacket(packetPair.second, packetPair.first);
_lastWindowProcessedPackets++;
midProcess();
}

View file

@ -23,7 +23,7 @@ public:
ReceivedPacketProcessor();
/// Add packet from network receive thread to the processing queue.
void queueReceivedPacket(const SharedNodePointer& sendingNode, const QByteArray& packet);
void queueReceivedPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
/// Are there received packets waiting to be processed
bool hasPacketsToProcess() const { return _packets.size() > 0; }
@ -58,7 +58,7 @@ protected:
/// Callback for processing of recieved packets. Implement this to process the incoming packets.
/// \param SharedNodePointer& sendingNode the node that sent this packet
/// \param QByteArray& the packet to be processed
virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) = 0;
virtual void processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) = 0;
/// Implements generic processing behavior for this thread.
virtual bool process();
@ -76,7 +76,7 @@ protected:
virtual void postProcess() { }
protected:
std::list<NodePacketPair> _packets;
std::list<NodeSharedPacketPair> _packets;
QHash<QUuid, int> _nodePacketCounts;
QWaitCondition _hasPackets;

View file

@ -56,12 +56,11 @@ bool JurisdictionListener::queueJurisdictionRequest() {
return isStillRunning();
}
void JurisdictionListener::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) {
if (packetTypeForPacket(packet) == PacketType::Jurisdiction && sendingNode) {
QUuid nodeUUID = sendingNode->getUUID();
void JurisdictionListener::processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
if (packet->getType() == PacketType::Jurisdiction && sendingNode) {
JurisdictionMap map;
map.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
_jurisdictions[nodeUUID] = map;
map.unpackFromPacket(*packet);
_jurisdictions[sendingNode->getUUID()] = map;
}
}

View file

@ -47,7 +47,7 @@ public slots:
protected:
/// Callback for processing of received packets. Will process any queued PacketType::_JURISDICTION and update the
/// jurisdiction map member variable
virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet);
virtual void processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
private:
NodeToJurisdictionMap _jurisdictions;

View file

@ -280,7 +280,7 @@ std::unique_ptr<NLPacket> JurisdictionMap::packEmptyJurisdictionIntoMessage(Node
return std::move(packet); // includes header!
}
std::unique_ptr<NLPacket> JurisdictionMap::packIntoMessage() {
std::unique_ptr<NLPacket> JurisdictionMap::packIntoPacket() {
auto packet = NLPacket::create(PacketType::Jurisdiction);
// Pack the Node Type in first byte
@ -315,42 +315,28 @@ std::unique_ptr<NLPacket> JurisdictionMap::packIntoMessage() {
return std::move(packet);
}
int JurisdictionMap::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) {
int JurisdictionMap::unpackFromPacket(NLPacket& packet) {
clear();
const unsigned char* startPosition = sourceBuffer;
// increment to push past the packet header
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(sourceBuffer));
sourceBuffer += numBytesPacketHeader;
int remainingBytes = availableBytes - numBytesPacketHeader;
// read the root jurisdiction
int bytes = 0;
memcpy(&bytes, sourceBuffer, sizeof(bytes));
sourceBuffer += sizeof(bytes);
remainingBytes -= sizeof(bytes);
packet.readPrimitive(&bytes);
if (bytes > 0 && bytes <= remainingBytes) {
if (bytes > 0 && bytes <= packet.bytesAvailable()) {
_rootOctalCode = new unsigned char[bytes];
memcpy(_rootOctalCode, sourceBuffer, bytes);
sourceBuffer += bytes;
remainingBytes -= bytes;
packet.read(reinterpret_cast<char*>(_rootOctalCode), bytes);
// if and only if there's a root jurisdiction, also include the end nodes
int endNodeCount = 0;
memcpy(&endNodeCount, sourceBuffer, sizeof(endNodeCount));
sourceBuffer += sizeof(endNodeCount);
for (int i=0; i < endNodeCount; i++) {
packet.readPrimitive(&endNodeCount);
for (int i = 0; i < endNodeCount; i++) {
int bytes = 0;
memcpy(&bytes, sourceBuffer, sizeof(bytes));
sourceBuffer += sizeof(bytes);
remainingBytes -= sizeof(bytes);
packet.readPrimitive(&bytes);
if (bytes <= remainingBytes) {
if (bytes <= packet.bytesAvailable()) {
unsigned char* endNodeCode = new unsigned char[bytes];
memcpy(endNodeCode, sourceBuffer, bytes);
sourceBuffer += bytes;
remainingBytes -= bytes;
packet.read(reinterpret_cast<char*>(endNodeCode), bytes);
// if the endNodeCode was 0 length then don't add it
if (bytes > 0) {
@ -360,5 +346,5 @@ int JurisdictionMap::unpackFromMessage(const unsigned char* sourceBuffer, int av
}
}
return sourceBuffer - startPosition; // includes header!
return packet.pos(); // excludes header
}

View file

@ -61,8 +61,8 @@ public:
void copyContents(unsigned char* rootCodeIn, const std::vector<unsigned char*>& endNodesIn);
int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes);
std::unique_ptr<NLPacket> packIntoMessage();
int unpackFromPacket(NLPacket& packet);
std::unique_ptr<NLPacket> packIntoPacket();
/// Available to pack an empty or unknown jurisdiction into a network packet, used when no JurisdictionMap is available
static std::unique_ptr<NLPacket> packEmptyJurisdictionIntoMessage(NodeType_t type);

View file

@ -28,13 +28,11 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NodeType_t type) :
JurisdictionSender::~JurisdictionSender() {
}
void JurisdictionSender::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) {
if (packetTypeForPacket(packet) == PacketType::JurisdictionRequest) {
if (sendingNode) {
lockRequestingNodes();
_nodesRequestingJurisdictions.push(sendingNode->getUUID());
unlockRequestingNodes();
}
void JurisdictionSender::processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
if (packet->getType() == PacketType::JurisdictionRequest) {
lockRequestingNodes();
_nodesRequestingJurisdictions.push(sendingNode->getUUID());
unlockRequestingNodes();
}
}
@ -43,7 +41,7 @@ bool JurisdictionSender::process() {
// call our ReceivedPacketProcessor base class process so we'll get any pending packets
if (continueProcessing && (continueProcessing = ReceivedPacketProcessor::process())) {
auto packet = (_jurisdictionMap) ? _jurisdictionMap->packIntoMessage()
auto packet = (_jurisdictionMap) ? _jurisdictionMap->packIntoPacket()
: JurisdictionMap::packEmptyJurisdictionIntoMessage(getNodeType());
int nodeCount = 0;

View file

@ -38,7 +38,7 @@ public:
void setNodeType(NodeType_t type) { _nodeType = type; }
protected:
virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet);
virtual void processPacket(QSharedPointer<NLPacket> pack, SharedNodePointer sendingNode);
/// Locks all the resources of the thread.
void lockRequestingNodes() { _requestingNodeMutex.lock(); }

View file

@ -225,10 +225,10 @@ void OctreeHeadlessViewer::queryOctree() {
}
int OctreeHeadlessViewer::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode) {
int OctreeHeadlessViewer::parseOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sourceNode) {
OctreeSceneStats temp;
int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
int statsMessageLength = temp.unpackFromPacket(*packet);
// TODO: actually do something with these stats, like expose them to JS...

View file

@ -37,7 +37,7 @@ public:
void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; }
static int parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode);
static int parseOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sourceNode);
static void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket);
public slots:

View file

@ -442,30 +442,16 @@ int OctreeSceneStats::packIntoPacket() {
return _statsPacket->getSizeUsed();
}
int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) {
const unsigned char* startPosition = sourceBuffer;
int OctreeSceneStats::unpackFromPacket(NLPacket& packet) {
packet.readPrimitive(&_start);
packet.readPrimitive(&_end);
packet.readPrimitive(&_elapsed);
packet.readPrimitive(&_totalEncodeTime);
// increment to push past the packet header
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(sourceBuffer));
sourceBuffer += numBytesPacketHeader;
memcpy(&_start, sourceBuffer, sizeof(_start));
sourceBuffer += sizeof(_start);
memcpy(&_end, sourceBuffer, sizeof(_end));
sourceBuffer += sizeof(_end);
memcpy(&_elapsed, sourceBuffer, sizeof(_elapsed));
sourceBuffer += sizeof(_elapsed);
memcpy(&_totalEncodeTime, sourceBuffer, sizeof(_totalEncodeTime));
sourceBuffer += sizeof(_totalEncodeTime);
memcpy(&_isFullScene, sourceBuffer, sizeof(_isFullScene));
sourceBuffer += sizeof(_isFullScene);
memcpy(&_isMoving, sourceBuffer, sizeof(_isMoving));
sourceBuffer += sizeof(_isMoving);
memcpy(&_packets, sourceBuffer, sizeof(_packets));
sourceBuffer += sizeof(_packets);
memcpy(&_bytes, sourceBuffer, sizeof(_bytes));
sourceBuffer += sizeof(_bytes);
packet.readPrimitive(&_isFullScene);
packet.readPrimitive(&_isMoving);
packet.readPrimitive(&_packets);
packet.readPrimitive(&_bytes);
if (_isFullScene) {
_lastFullElapsed = _elapsed;
@ -474,75 +460,52 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a
_lastFullTotalBytes = _bytes;
}
memcpy(&_totalInternal, sourceBuffer, sizeof(_totalInternal));
sourceBuffer += sizeof(_totalInternal);
memcpy(&_totalLeaves, sourceBuffer, sizeof(_totalLeaves));
sourceBuffer += sizeof(_totalLeaves);
packet.readPrimitive(&_totalInternal);
packet.readPrimitive(&_totalLeaves);
_totalElements = _totalInternal + _totalLeaves;
memcpy(&_internal, sourceBuffer, sizeof(_internal));
sourceBuffer += sizeof(_internal);
memcpy(&_leaves, sourceBuffer, sizeof(_leaves));
sourceBuffer += sizeof(_leaves);
packet.readPrimitive(&_internal);
packet.readPrimitive(&_leaves);
_traversed = _internal + _leaves;
memcpy(&_internalSkippedDistance, sourceBuffer, sizeof(_internalSkippedDistance));
sourceBuffer += sizeof(_internalSkippedDistance);
memcpy(&_leavesSkippedDistance, sourceBuffer, sizeof(_leavesSkippedDistance));
sourceBuffer += sizeof(_leavesSkippedDistance);
packet.readPrimitive(&_internalSkippedDistance);
packet.readPrimitive(&_leavesSkippedDistance);
_skippedDistance = _internalSkippedDistance + _leavesSkippedDistance;
memcpy(&_internalSkippedOutOfView, sourceBuffer, sizeof(_internalSkippedOutOfView));
sourceBuffer += sizeof(_internalSkippedOutOfView);
memcpy(&_leavesSkippedOutOfView, sourceBuffer, sizeof(_leavesSkippedOutOfView));
sourceBuffer += sizeof(_leavesSkippedOutOfView);
packet.readPrimitive(&_internalSkippedOutOfView);
packet.readPrimitive(&_leavesSkippedOutOfView);
_skippedOutOfView = _internalSkippedOutOfView + _leavesSkippedOutOfView;
memcpy(&_internalSkippedWasInView, sourceBuffer, sizeof(_internalSkippedWasInView));
sourceBuffer += sizeof(_internalSkippedWasInView);
memcpy(&_leavesSkippedWasInView, sourceBuffer, sizeof(_leavesSkippedWasInView));
sourceBuffer += sizeof(_leavesSkippedWasInView);
packet.readPrimitive(&_internalSkippedWasInView);
packet.readPrimitive(&_leavesSkippedWasInView);
_skippedWasInView = _internalSkippedWasInView + _leavesSkippedWasInView;
memcpy(&_internalSkippedNoChange, sourceBuffer, sizeof(_internalSkippedNoChange));
sourceBuffer += sizeof(_internalSkippedNoChange);
memcpy(&_leavesSkippedNoChange, sourceBuffer, sizeof(_leavesSkippedNoChange));
sourceBuffer += sizeof(_leavesSkippedNoChange);
packet.readPrimitive(&_internalSkippedNoChange);
packet.readPrimitive(&_leavesSkippedNoChange);
_skippedNoChange = _internalSkippedNoChange + _leavesSkippedNoChange;
memcpy(&_internalSkippedOccluded, sourceBuffer, sizeof(_internalSkippedOccluded));
sourceBuffer += sizeof(_internalSkippedOccluded);
memcpy(&_leavesSkippedOccluded, sourceBuffer, sizeof(_leavesSkippedOccluded));
sourceBuffer += sizeof(_leavesSkippedOccluded);
packet.readPrimitive(&_internalSkippedOccluded);
packet.readPrimitive(&_leavesSkippedOccluded);
_skippedOccluded = _internalSkippedOccluded + _leavesSkippedOccluded;
memcpy(&_internalColorSent, sourceBuffer, sizeof(_internalColorSent));
sourceBuffer += sizeof(_internalColorSent);
memcpy(&_leavesColorSent, sourceBuffer, sizeof(_leavesColorSent));
sourceBuffer += sizeof(_leavesColorSent);
packet.readPrimitive(&_internalColorSent);
packet.readPrimitive(&_leavesColorSent);
_colorSent = _internalColorSent + _leavesColorSent;
memcpy(&_internalDidntFit, sourceBuffer, sizeof(_internalDidntFit));
sourceBuffer += sizeof(_internalDidntFit);
memcpy(&_leavesDidntFit, sourceBuffer, sizeof(_leavesDidntFit));
sourceBuffer += sizeof(_leavesDidntFit);
packet.readPrimitive(&_internalDidntFit);
packet.readPrimitive(&_leavesDidntFit);
_didntFit = _internalDidntFit + _leavesDidntFit;
memcpy(&_colorBitsWritten, sourceBuffer, sizeof(_colorBitsWritten));
sourceBuffer += sizeof(_colorBitsWritten);
memcpy(&_existsBitsWritten, sourceBuffer, sizeof(_existsBitsWritten));
sourceBuffer += sizeof(_existsBitsWritten);
memcpy(&_existsInPacketBitsWritten, sourceBuffer, sizeof(_existsInPacketBitsWritten));
sourceBuffer += sizeof(_existsInPacketBitsWritten);
memcpy(&_treesRemoved, sourceBuffer, sizeof(_treesRemoved));
sourceBuffer += sizeof(_treesRemoved);
packet.readPrimitive(&_colorBitsWritten);
packet.readPrimitive(&_existsBitsWritten);
packet.readPrimitive(&_existsInPacketBitsWritten);
packet.readPrimitive(&_treesRemoved);
// before allocating new juridiction, clean up existing ones
if (_jurisdictionRoot) {
delete[] _jurisdictionRoot;
_jurisdictionRoot = NULL;
}
// clear existing endNodes before copying new ones...
for (size_t i = 0; i < _jurisdictionEndNodes.size(); i++) {
if (_jurisdictionEndNodes[i]) {
@ -553,28 +516,29 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a
// read the root jurisdiction
int bytes = 0;
memcpy(&bytes, sourceBuffer, sizeof(bytes));
sourceBuffer += sizeof(bytes);
packet.readPrimitive(&bytes);
if (bytes == 0) {
_jurisdictionRoot = NULL;
_jurisdictionEndNodes.clear();
} else {
_jurisdictionRoot = new unsigned char[bytes];
memcpy(_jurisdictionRoot, sourceBuffer, bytes);
sourceBuffer += bytes;
packet.read(reinterpret_cast<char*>(_jurisdictionRoot), bytes);
// if and only if there's a root jurisdiction, also include the end elements
_jurisdictionEndNodes.clear();
int endNodeCount = 0;
memcpy(&endNodeCount, sourceBuffer, sizeof(endNodeCount));
sourceBuffer += sizeof(endNodeCount);
packet.readPrimitive(&endNodeCount);
for (int i=0; i < endNodeCount; i++) {
int bytes = 0;
memcpy(&bytes, sourceBuffer, sizeof(bytes));
sourceBuffer += sizeof(bytes);
packet.readPrimitive(&bytes);
unsigned char* endNodeCode = new unsigned char[bytes];
memcpy(endNodeCode, sourceBuffer, bytes);
sourceBuffer += bytes;
packet.read(reinterpret_cast<char*>(endNodeCode), bytes);
_jurisdictionEndNodes.push_back(endNodeCode);
}
}
@ -585,8 +549,7 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a
float calculatedBPV = total == 0 ? 0 : (_bytes * 8) / total;
_bitsPerOctreeAverage.updateAverage(calculatedBPV);
return sourceBuffer - startPosition; // includes header!
return packet.pos(); // excludes header!
}

View file

@ -93,8 +93,8 @@ public:
/// Pack the details of the statistics into a buffer for sending as a network packet
int packIntoPacket();
/// Unpack the details of the statistics from a buffer typically received as a network packet
int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes);
/// Unpack the details of the statistics from a network packet
int unpackFromPacket(NLPacket& packet);
/// Indicates that a scene has been completed and the statistics are ready to be sent
bool isReadyToSend() const { return _isReadyToSend; }