From c157aad775d398f3b2be19e0dbd7063d55f27d38 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 15 Aug 2013 10:44:43 -0700 Subject: [PATCH 01/20] starting to add PACKET_TYPE_VOXEL_JURISDICTION --- libraries/shared/src/PacketHeaders.h | 1 + libraries/voxels/src/JurisdictionMap.cpp | 75 ++++++++++++++++++++++++ libraries/voxels/src/JurisdictionMap.h | 3 + 3 files changed, 79 insertions(+) diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 3d49b6b066..720fb69936 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -38,6 +38,7 @@ const PACKET_TYPE PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY = 'C'; const PACKET_TYPE PACKET_TYPE_REQUEST_ASSIGNMENT = 'r'; const PACKET_TYPE PACKET_TYPE_SEND_ASSIGNMENT = 's'; const PACKET_TYPE PACKET_TYPE_VOXEL_STATS = '#'; +const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION = 'J'; typedef char PACKET_VERSION; diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index 377329caf2..5cd44e0030 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include "JurisdictionMap.h" #include "VoxelNode.h" @@ -206,3 +208,76 @@ bool JurisdictionMap::writeToFile(const char* filename) { settings.endGroup(); return true; } + +int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) { + unsigned char* bufferStart = destinationBuffer; + + int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_VOXEL_JURISDICTION); + destinationBuffer += headerLength; + + // add the root jurisdiction + if (_rootOctalCode) { + // copy the + int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_rootOctalCode)); + memcpy(destinationBuffer, &bytes, sizeof(bytes)); + destinationBuffer += sizeof(bytes); + memcpy(destinationBuffer, _rootOctalCode, bytes); + destinationBuffer += bytes; + + // if and only if there's a root jurisdiction, also include the end nodes + int endNodeCount = _endNodes.size(); + + memcpy(destinationBuffer, &endNodeCount, sizeof(endNodeCount)); + destinationBuffer += sizeof(endNodeCount); + + for (int i=0; i < endNodeCount; i++) { + unsigned char* endNodeCode = _endNodes[i]; + int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode)); + memcpy(destinationBuffer, &bytes, sizeof(bytes)); + destinationBuffer += sizeof(bytes); + memcpy(destinationBuffer, endNodeCode, bytes); + destinationBuffer += bytes; + } + } else { + int bytes = 0; + memcpy(destinationBuffer, &bytes, sizeof(bytes)); + destinationBuffer += sizeof(bytes); + } + + return destinationBuffer - bufferStart; // includes header! +} + +int JurisdictionMap::unpackFromMessage(unsigned char* sourceBuffer, int availableBytes) { + clear(); + unsigned char* startPosition = sourceBuffer; + + // increment to push past the packet header + int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer); + sourceBuffer += numBytesPacketHeader; + + // read the root jurisdiction + int bytes = 0; + memcpy(&bytes, sourceBuffer, sizeof(bytes)); + sourceBuffer += sizeof(bytes); + + if (bytes > 0) { + _rootOctalCode = new unsigned char[bytes]; + memcpy(_rootOctalCode, sourceBuffer, bytes); + sourceBuffer += 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++) { + int bytes = 0; + memcpy(&bytes, sourceBuffer, sizeof(bytes)); + sourceBuffer += sizeof(bytes); + unsigned char* endNodeCode = new unsigned char[bytes]; + memcpy(endNodeCode, sourceBuffer, bytes); + sourceBuffer += bytes; + _endNodes.push_back(endNodeCode); + } + } + + return sourceBuffer - startPosition; // includes header! +} diff --git a/libraries/voxels/src/JurisdictionMap.h b/libraries/voxels/src/JurisdictionMap.h index 50aabb65f2..5b0f19229a 100644 --- a/libraries/voxels/src/JurisdictionMap.h +++ b/libraries/voxels/src/JurisdictionMap.h @@ -49,6 +49,9 @@ public: int getEndNodeCount() const { return _endNodes.size(); } void copyContents(unsigned char* rootCodeIn, const std::vector endNodesIn); + + int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes); + int packIntoMessage(unsigned char* destinationBuffer, int availableBytes); private: void copyContents(const JurisdictionMap& other); // use assignment instead From 82782b6ec5c068a3fcd9bb3ab44715e563db2c15 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 15 Aug 2013 13:10:41 -0700 Subject: [PATCH 02/20] switched to using Application singleton --- interface/src/Application.cpp | 4 ++-- interface/src/VoxelEditPacketSender.cpp | 15 +++++++------- interface/src/VoxelEditPacketSender.h | 5 ----- interface/src/VoxelPacketProcessor.cpp | 26 ++++++++++++------------- interface/src/VoxelPacketProcessor.h | 8 -------- 5 files changed, 21 insertions(+), 37 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c4739c044d..c36f1a0545 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -221,8 +221,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _audio(&_audioScope, STARTUP_JITTER_SAMPLES), #endif _stopNetworkReceiveThread(false), - _voxelProcessor(this), - _voxelEditSender(this), + _voxelProcessor(), + _voxelEditSender(), _packetCount(0), _packetsPerSecond(0), _bytesPerSecond(0), diff --git a/interface/src/VoxelEditPacketSender.cpp b/interface/src/VoxelEditPacketSender.cpp index c663977268..621e09bd22 100644 --- a/interface/src/VoxelEditPacketSender.cpp +++ b/interface/src/VoxelEditPacketSender.cpp @@ -13,15 +13,12 @@ #include "Application.h" #include "VoxelEditPacketSender.h" -VoxelEditPacketSender::VoxelEditPacketSender(Application* app) : - _app(app) -{ -} - void VoxelEditPacketSender::sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail) { + Application* app = Application::getInstance(); + // if the app has Voxels disabled, we don't do any of this... - if (!_app->_renderVoxels->isChecked()) { + if (!app->_renderVoxels->isChecked()) { return; // bail early } @@ -35,7 +32,7 @@ void VoxelEditPacketSender::sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& } // Tell the application's bandwidth meters about what we've sent - _app->_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(totalBytesSent); + app->_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(totalBytesSent); } void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char* bufferOut, ssize_t sizeOut) { @@ -51,6 +48,8 @@ void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char* } void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) { + Application* app = Application::getInstance(); + // We want to filter out edit messages for voxel servers based on the server's Jurisdiction // But we can't really do that with a packed message, since each edit message could be destined // for a different voxel server... So we need to actually manage multiple queued packets... one @@ -63,7 +62,7 @@ void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned cha // we need to get the jurisdiction for this // here we need to get the "pending packet" for this server uint16_t nodeID = node->getNodeID(); - const JurisdictionMap& map = _app->_voxelServerJurisdictions[nodeID]; + const JurisdictionMap& map = app->_voxelServerJurisdictions[nodeID]; if (map.isMyJurisdiction(codeColorBuffer, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN) { EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeID]; packetBuffer._nodeID = nodeID; diff --git a/interface/src/VoxelEditPacketSender.h b/interface/src/VoxelEditPacketSender.h index d3058828e3..e3b0f7d18a 100644 --- a/interface/src/VoxelEditPacketSender.h +++ b/interface/src/VoxelEditPacketSender.h @@ -14,8 +14,6 @@ #include #include // for VoxelDetail -class Application; - /// Used for construction of edit voxel packets class EditPacketBuffer { public: @@ -29,8 +27,6 @@ public: /// Threaded processor for queueing and sending of outbound edit voxel packets. class VoxelEditPacketSender : public PacketSender { public: - VoxelEditPacketSender(Application* app); - /// Send voxel edit message immediately void sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail); @@ -46,7 +42,6 @@ private: void initializePacket(EditPacketBuffer& packetBuffer, PACKET_TYPE type); void flushQueue(EditPacketBuffer& packetBuffer); // flushes specific queued packet - Application* _app; std::map _pendingEditPackets; }; #endif // __shared__VoxelEditPacketSender__ diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index 558037b0bc..86188b2bf8 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -13,18 +13,16 @@ #include "Application.h" #include "VoxelPacketProcessor.h" -VoxelPacketProcessor::VoxelPacketProcessor(Application* app) : - _app(app) { -} - void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { - PerformanceWarning warn(_app->_renderPipelineWarnings->isChecked(),"VoxelPacketProcessor::processPacket()"); + Application* app = Application::getInstance(); + + PerformanceWarning warn(app->_renderPipelineWarnings->isChecked(),"VoxelPacketProcessor::processPacket()"); ssize_t messageLength = packetLength; // check to see if the UI thread asked us to kill the voxel tree. since we're the only thread allowed to do that - if (_app->_wantToKillLocalVoxels) { - _app->_voxels.killLocalVoxels(); - _app->_wantToKillLocalVoxels = false; + if (app->_wantToKillLocalVoxels) { + app->_voxels.killLocalVoxels(); + app->_wantToKillLocalVoxels = false; } // note: PACKET_TYPE_VOXEL_STATS can have PACKET_TYPE_VOXEL_DATA or PACKET_TYPE_VOXEL_DATA_MONOCHROME @@ -32,7 +30,7 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* // then process any remaining bytes as if it was another packet if (packetData[0] == PACKET_TYPE_VOXEL_STATS) { - int statsMessageLength = _app->parseVoxelStats(packetData, messageLength, senderAddress); + int statsMessageLength = app->parseVoxelStats(packetData, messageLength, senderAddress); if (messageLength > statsMessageLength) { packetData += statsMessageLength; messageLength -= statsMessageLength; @@ -44,16 +42,16 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* } } // fall through to piggyback message - if (_app->_renderVoxels->isChecked()) { + if (app->_renderVoxels->isChecked()) { Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (voxelServer && socketMatch(voxelServer->getActiveSocket(), &senderAddress)) { voxelServer->lock(); if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) { - _app->_environment.parseData(&senderAddress, packetData, messageLength); + app->_environment.parseData(&senderAddress, packetData, messageLength); } else { - _app->_voxels.setDataSourceID(voxelServer->getNodeID()); - _app->_voxels.parseData(packetData, messageLength); - _app->_voxels.setDataSourceID(UNKNOWN_NODE_ID); + app->_voxels.setDataSourceID(voxelServer->getNodeID()); + app->_voxels.parseData(packetData, messageLength); + app->_voxels.setDataSourceID(UNKNOWN_NODE_ID); } voxelServer->unlock(); } diff --git a/interface/src/VoxelPacketProcessor.h b/interface/src/VoxelPacketProcessor.h index f55daf5aba..0a89d0d03e 100644 --- a/interface/src/VoxelPacketProcessor.h +++ b/interface/src/VoxelPacketProcessor.h @@ -13,17 +13,9 @@ #include -class Application; - /// Handles processing of incoming voxel packets for the interface application. class VoxelPacketProcessor : public ReceivedPacketProcessor { -public: - VoxelPacketProcessor(Application* app); - protected: virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); - -private: - Application* _app; }; #endif // __shared__VoxelPacketProcessor__ From 209c9f93edf85de9d29ffa6437da193a8e941b96 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 15 Aug 2013 14:21:21 -0700 Subject: [PATCH 03/20] remove Application dependency from VoxelEditPacketSender class --- interface/src/Application.cpp | 11 +++++-- interface/src/Application.h | 3 +- interface/src/VoxelEditPacketSender.cpp | 40 +++++++++++++++---------- interface/src/VoxelEditPacketSender.h | 13 ++++++++ libraries/shared/src/PacketSender.cpp | 5 +++- libraries/shared/src/PacketSender.h | 11 ++++++- 6 files changed, 61 insertions(+), 22 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c36f1a0545..c6479d245a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -222,7 +222,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : #endif _stopNetworkReceiveThread(false), _voxelProcessor(), - _voxelEditSender(), + _voxelEditSender(this), _packetCount(0), _packetsPerSecond(0), _bytesPerSecond(0), @@ -329,6 +329,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _glWidget->setMouseTracking(true); // initialization continues in initializeGL when OpenGL context is ready + + // Tell our voxel edit sender about our known jurisdictions + _voxelEditSender.setVoxelServerJurisdictions(&_voxelServerJurisdictions); } Application::~Application() { @@ -1437,6 +1440,7 @@ void Application::setRenderWarnings(bool renderWarnings) { } void Application::setRenderVoxels(bool voxelRender) { + _voxelEditSender.setShouldSend(voxelRender); if (!voxelRender) { doKillLocalVoxels(); } @@ -4156,5 +4160,6 @@ void Application::updateParticleSystem(float deltaTime) { } } - - +void Application::packetSentNotification(ssize_t length) { + _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(length); +} diff --git a/interface/src/Application.h b/interface/src/Application.h index 88cb86312f..7d5d1497af 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -72,7 +72,7 @@ static const float NODE_KILLED_RED = 1.0f; static const float NODE_KILLED_GREEN = 0.0f; static const float NODE_KILLED_BLUE = 0.0f; -class Application : public QApplication, public NodeListHook { +class Application : public QApplication, public NodeListHook, public PacketSenderNotify { Q_OBJECT friend class VoxelPacketProcessor; @@ -131,6 +131,7 @@ public: virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); + virtual void packetSentNotification(ssize_t length); public slots: void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data); diff --git a/interface/src/VoxelEditPacketSender.cpp b/interface/src/VoxelEditPacketSender.cpp index 621e09bd22..cfc3cab218 100644 --- a/interface/src/VoxelEditPacketSender.cpp +++ b/interface/src/VoxelEditPacketSender.cpp @@ -10,29 +10,30 @@ #include -#include "Application.h" +#include +#include #include "VoxelEditPacketSender.h" + +VoxelEditPacketSender::VoxelEditPacketSender(PacketSenderNotify* notify) : + PacketSender(notify), + _shouldSend(true), + _voxelServerJurisdictions(NULL) { +} + void VoxelEditPacketSender::sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail) { - - Application* app = Application::getInstance(); - - // if the app has Voxels disabled, we don't do any of this... - if (!app->_renderVoxels->isChecked()) { + // allows app to disable sending if for example voxels have been disabled + if (!_shouldSend) { return; // bail early } unsigned char* bufferOut; int sizeOut; - int totalBytesSent = 0; if (createVoxelEditMessage(type, 0, 1, &detail, bufferOut, sizeOut)){ actuallySendMessage(UNKNOWN_NODE_ID, bufferOut, sizeOut); // sends to all servers... not ideal! delete[] bufferOut; } - - // Tell the application's bandwidth meters about what we've sent - app->_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(totalBytesSent); } void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char* bufferOut, ssize_t sizeOut) { @@ -48,7 +49,10 @@ void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char* } void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) { - Application* app = Application::getInstance(); + + if (!_shouldSend) { + return; // bail early + } // We want to filter out edit messages for voxel servers based on the server's Jurisdiction // But we can't really do that with a packed message, since each edit message could be destined @@ -58,12 +62,16 @@ void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned cha for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { // only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER) { - - // we need to get the jurisdiction for this - // here we need to get the "pending packet" for this server uint16_t nodeID = node->getNodeID(); - const JurisdictionMap& map = app->_voxelServerJurisdictions[nodeID]; - if (map.isMyJurisdiction(codeColorBuffer, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN) { + bool isMyJurisdiction = true; + + if (_voxelServerJurisdictions) { + // we need to get the jurisdiction for this + // here we need to get the "pending packet" for this server + const JurisdictionMap& map = (*_voxelServerJurisdictions)[nodeID]; + isMyJurisdiction = (map.isMyJurisdiction(codeColorBuffer, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN); + } + if (isMyJurisdiction) { EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeID]; packetBuffer._nodeID = nodeID; diff --git a/interface/src/VoxelEditPacketSender.h b/interface/src/VoxelEditPacketSender.h index e3b0f7d18a..ebced66b7b 100644 --- a/interface/src/VoxelEditPacketSender.h +++ b/interface/src/VoxelEditPacketSender.h @@ -13,6 +13,7 @@ #include #include // for VoxelDetail +#include /// Used for construction of edit voxel packets class EditPacketBuffer { @@ -27,6 +28,8 @@ public: /// Threaded processor for queueing and sending of outbound edit voxel packets. class VoxelEditPacketSender : public PacketSender { public: + VoxelEditPacketSender(PacketSenderNotify* notify = NULL); + /// Send voxel edit message immediately void sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail); @@ -37,11 +40,21 @@ public: /// flushes all queued packets for all nodes void flushQueue(); + bool getShouldSend() const { return _shouldSend; } + void setShouldSend(bool shouldSend) { _shouldSend = shouldSend; } + + void setVoxelServerJurisdictions(std::map* voxelServerJurisdictions) { + _voxelServerJurisdictions = voxelServerJurisdictions; + } + private: + bool _shouldSend; void actuallySendMessage(uint16_t nodeID, unsigned char* bufferOut, ssize_t sizeOut); void initializePacket(EditPacketBuffer& packetBuffer, PACKET_TYPE type); void flushQueue(EditPacketBuffer& packetBuffer); // flushes specific queued packet std::map _pendingEditPackets; + + std::map* _voxelServerJurisdictions; }; #endif // __shared__VoxelEditPacketSender__ diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index 4c150454a3..ecbe15359e 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -16,7 +16,7 @@ const uint64_t SEND_INTERVAL_USECS = 1000 * 5; // no more than 200pps... should #include "PacketSender.h" #include "SharedUtil.h" -PacketSender::PacketSender() { +PacketSender::PacketSender(PacketSenderNotify* notify) : _notify(notify) { _lastSendTime = usecTimestampNow(); } @@ -40,6 +40,9 @@ bool PacketSender::process() { UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); nodeSocket->send(&packet.getAddress(), packet.getData(), packet.getLength()); + if (_notify) { + _notify->packetSentNotification(packet.getLength()); + } lock(); _packets.erase(_packets.begin()); diff --git a/libraries/shared/src/PacketSender.h b/libraries/shared/src/PacketSender.h index 5a1a63695f..bd2ab99407 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/shared/src/PacketSender.h @@ -14,11 +14,18 @@ #include "GenericThread.h" #include "NetworkPacket.h" +/// Notification Hook for packets being sent by a PacketSender +class PacketSenderNotify { +public: + virtual void packetSentNotification(ssize_t length) = 0; +}; + + /// Generalized threaded processor for queueing and sending of outbound packets. class PacketSender : public GenericThread { public: - PacketSender(); + PacketSender(PacketSenderNotify* notify = NULL); /// Add packet to outbound queue. /// \param sockaddr& address the destination address @@ -33,6 +40,8 @@ private: std::vector _packets; uint64_t _lastSendTime; + PacketSenderNotify* _notify; + }; #endif // __shared__PacketSender__ From 7045dff7d30368f16fb46d0d7255e13bf034de0a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 15 Aug 2013 14:26:31 -0700 Subject: [PATCH 04/20] moved VoxelEditPacketSender to libraries --- {interface => libraries/voxels}/src/VoxelEditPacketSender.cpp | 0 {interface => libraries/voxels}/src/VoxelEditPacketSender.h | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename {interface => libraries/voxels}/src/VoxelEditPacketSender.cpp (100%) rename {interface => libraries/voxels}/src/VoxelEditPacketSender.h (97%) diff --git a/interface/src/VoxelEditPacketSender.cpp b/libraries/voxels/src/VoxelEditPacketSender.cpp similarity index 100% rename from interface/src/VoxelEditPacketSender.cpp rename to libraries/voxels/src/VoxelEditPacketSender.cpp diff --git a/interface/src/VoxelEditPacketSender.h b/libraries/voxels/src/VoxelEditPacketSender.h similarity index 97% rename from interface/src/VoxelEditPacketSender.h rename to libraries/voxels/src/VoxelEditPacketSender.h index ebced66b7b..a45f677cee 100644 --- a/interface/src/VoxelEditPacketSender.h +++ b/libraries/voxels/src/VoxelEditPacketSender.h @@ -1,6 +1,6 @@ // // VoxelEditPacketSender.h -// interface +// shared // // Created by Brad Hefta-Gaub on 8/12/13. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. @@ -13,7 +13,7 @@ #include #include // for VoxelDetail -#include +#include "JurisdictionMap.h" /// Used for construction of edit voxel packets class EditPacketBuffer { From 68845da9011e5f687a75efeb82225cb72d4c87a6 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 16 Aug 2013 10:10:17 -0700 Subject: [PATCH 05/20] added doxygen comments and cleanup for VoxelSceneStats class --- interface/src/ui/VoxelStatsDialog.cpp | 4 +- libraries/voxels/src/VoxelSceneStats.cpp | 2 +- libraries/voxels/src/VoxelSceneStats.h | 56 ++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index bfe93ec119..b6e3b3202a 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -30,7 +30,7 @@ VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) : this->QDialog::setLayout(form); // Setup labels - for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; ++i) { + for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; ++i) { VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(i); QLabel* label = _labels[i] = new QLabel(); label->setAlignment(Qt::AlignRight); @@ -56,7 +56,7 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { // Update labels char strBuf[256]; - for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; ++i) { + for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; ++i) { QLabel* label = _labels[i]; snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue(i)); label->setText(strBuf); diff --git a/libraries/voxels/src/VoxelSceneStats.cpp b/libraries/voxels/src/VoxelSceneStats.cpp index 02027a5ee4..1ebc4015e0 100644 --- a/libraries/voxels/src/VoxelSceneStats.cpp +++ b/libraries/voxels/src/VoxelSceneStats.cpp @@ -543,7 +543,7 @@ VoxelSceneStats::ItemInfo VoxelSceneStats::_ITEMS[] = { { "Mode" , greenish }, }; -char* VoxelSceneStats::getItemValue(int item) { +char* VoxelSceneStats::getItemValue(Item item) { const uint64_t USECS_PER_SECOND = 1000 * 1000; int calcFPS, calcAverageFPS, calculatedKBPS; switch(item) { diff --git a/libraries/voxels/src/VoxelSceneStats.h b/libraries/voxels/src/VoxelSceneStats.h index feb8b81edc..2d7f7cd068 100644 --- a/libraries/voxels/src/VoxelSceneStats.h +++ b/libraries/voxels/src/VoxelSceneStats.h @@ -16,42 +16,83 @@ class VoxelNode; +/// Collects statistics for calculating and sending a scene from a voxel server to an interface client class VoxelSceneStats { public: VoxelSceneStats(); ~VoxelSceneStats(); void reset(); + + /// Call when beginning the computation of a scene. Initializes internal structures void sceneStarted(bool fullScene, bool moving, VoxelNode* root, JurisdictionMap* jurisdictionMap); + + /// Call when the computation of a scene is completed. Finalizes internal structures void sceneCompleted(); void printDebugDetails(); + + /// Track that a packet was sent as part of the scene. void packetSent(int bytes); + /// Tracks the beginning of an encode pass during scene calculation. void encodeStarted(); + + /// Tracks the ending of an encode pass during scene calculation. void encodeStopped(); + /// Track that a node was traversed as part of computation of a scene. void traversed(const VoxelNode* node); + + /// Track that a node was skipped as part of computation of a scene due to being beyond the LOD distance. void skippedDistance(const VoxelNode* node); + + /// Track that a node was skipped as part of computation of a scene due to being out of view. void skippedOutOfView(const VoxelNode* node); + + /// Track that a node was skipped as part of computation of a scene due to previously being in view while in delta sending void skippedWasInView(const VoxelNode* node); + + /// Track that a node was skipped as part of computation of a scene due to not having changed since last full scene sent void skippedNoChange(const VoxelNode* node); + + /// Track that a node was skipped as part of computation of a scene due to being occluded void skippedOccluded(const VoxelNode* node); + + /// Track that a node's color was was sent as part of computation of a scene void colorSent(const VoxelNode* node); + + /// Track that a node was due to be sent, but didn't fit in the packet and was moved to next packet void didntFit(const VoxelNode* node); + + /// Track that the color bitmask was was sent as part of computation of a scene void colorBitsWritten(); + + /// Track that the exists in tree bitmask was was sent as part of computation of a scene void existsBitsWritten(); + + /// Track that the exists in packet bitmask was was sent as part of computation of a scene void existsInPacketBitsWritten(); + + /// Fix up tracking statistics in case where bitmasks were removed for some reason void childBitsRemoved(bool includesExistsBits, bool includesColors); + /// Pack the details of the statistics into a buffer for sending as a network packet int packIntoMessage(unsigned char* destinationBuffer, int availableBytes); + + /// Unpack the details of the statistics from a buffer typically received as a network packet int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes); + /// Indicates that a scene has been completed and the statistics are ready to be sent bool isReadyToSend() const { return _isReadyToSend; } + + /// Mark that the scene statistics have been sent void markAsSent() { _isReadyToSend = false; } + unsigned char* getStatsMessage() { return &_statsMessage[0]; } int getStatsMessageLength() const { return _statsMessageLength; } - enum { + /// List of various items tracked by VoxelSceneStats which can be accessed via getItemInfo() and getItemValue() + enum Item { ITEM_ELAPSED, ITEM_ENCODE, ITEM_PACKETS, @@ -71,16 +112,23 @@ public: ITEM_COUNT }; - // Meta information about each stats item + /// Meta information about each stats item struct ItemInfo { char const* const caption; unsigned colorRGBA; }; - ItemInfo& getItemInfo(int item) { return _ITEMS[item]; }; - char* getItemValue(int item); + /// Returns details about items tracked by VoxelSceneStats + /// \param + ItemInfo& getItemInfo(Item item) { return _ITEMS[item]; }; + + /// Returns a UI formatted value of an item tracked by VoxelSceneStats + char* getItemValue(Item item); + /// Returns OctCode for root node of the jurisdiction of this particular voxel server unsigned char* getJurisdictionRoot() const { return _jurisdictionRoot; } + + /// Returns list of OctCodes for end nodes of the jurisdiction of this particular voxel server const std::vector& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; } private: From 5a96f51602240a9b7e5e66b339ec26f9988cba20 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 19 Aug 2013 10:30:22 -0700 Subject: [PATCH 06/20] first cut at JurisdictionSender and related changes --- libraries/voxels/src/JurisdictionSender.cpp | 56 +++++++++++++++++++++ libraries/voxels/src/JurisdictionSender.h | 31 ++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 libraries/voxels/src/JurisdictionSender.cpp create mode 100644 libraries/voxels/src/JurisdictionSender.h diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp new file mode 100644 index 0000000000..f1afdf444c --- /dev/null +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -0,0 +1,56 @@ +// +// JurisdictionSender.cpp +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Threaded or non-threaded jurisdiction Sender for the Application +// + +#include + +#include +#include +#include +#include "JurisdictionSender.h" + + +JurisdictionSender::JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* notify) : + PacketSender(notify, JurisdictionSender::DEFAULT_PACKETS_PER_SECOND), + _jurisdictionMap(map) +{ +} + +bool JurisdictionSender::process() { +//printf("JurisdictionSender::process() _packetsPerSecond=%d\n", _packetsPerSecond); + // add our packet to our own queue, then let the PacketSender class do the rest of the work. + if (_jurisdictionMap) { +//printf("JurisdictionSender::process() _jurisdictionMap=%p\n",_jurisdictionMap); + unsigned char buffer[MAX_PACKET_SIZE]; + unsigned char* bufferOut = &buffer[0]; + ssize_t sizeOut = _jurisdictionMap->packIntoMessage(bufferOut, MAX_PACKET_SIZE); + int nodeCount = 0; + + NodeList* nodeList = NodeList::getInstance(); + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + +//printf("JurisdictionSender::process() node loop node=%d type=%c\n",node->getNodeID(), node->getType()); + + // only send to the NodeTypes that are interested in our jurisdiction details + const int numNodeTypes = 1; + const NODE_TYPE nodeTypes[numNodeTypes] = { NODE_TYPE_ANIMATION_SERVER }; + if (node->getActiveSocket() != NULL && memchr(nodeTypes, node->getType(), numNodeTypes)) { + sockaddr* nodeAddress = node->getActiveSocket(); + queuePacket(*nodeAddress, bufferOut, sizeOut); + nodeCount++; + } + } + + // set our packets per second to be the number of nodes + setPacketsPerSecond(nodeCount); + printf("loaded %d packets to send\n", nodeCount); + } + + return PacketSender::process(); +} diff --git a/libraries/voxels/src/JurisdictionSender.h b/libraries/voxels/src/JurisdictionSender.h new file mode 100644 index 0000000000..10d763cfdd --- /dev/null +++ b/libraries/voxels/src/JurisdictionSender.h @@ -0,0 +1,31 @@ +// +// JurisdictionSender.h +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Voxel Packet Sender +// + +#ifndef __shared__JurisdictionSender__ +#define __shared__JurisdictionSender__ + +#include +#include "JurisdictionMap.h" + +/// Threaded processor for queueing and sending of outbound edit voxel packets. +class JurisdictionSender : public PacketSender { +public: + static const int DEFAULT_PACKETS_PER_SECOND = 1; + + JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* notify = NULL); + + void setJurisdiction(JurisdictionMap* map) { _jurisdictionMap = map; } + + virtual bool process(); + +private: + JurisdictionMap* _jurisdictionMap; +}; +#endif // __shared__JurisdictionSender__ From e64664c0d18dce2215e6818afc6ad6446f7bcc44 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 19 Aug 2013 11:05:29 -0700 Subject: [PATCH 07/20] first cut at JurisdictionSender and related changes --- animation-server/src/main.cpp | 6 +++ domain-server/src/main.cpp | 14 +++++- libraries/shared/src/GenericThread.h | 3 +- libraries/shared/src/NodeList.cpp | 1 + libraries/shared/src/PacketSender.cpp | 24 +++++++--- libraries/shared/src/PacketSender.h | 17 +++++-- libraries/voxels/src/JurisdictionMap.cpp | 12 +++-- voxel-server/src/main.cpp | 58 +++++++++++++++++++++--- 8 files changed, 113 insertions(+), 22 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index b20ebad37f..1031a71479 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -735,21 +735,27 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* NO_BILLBOARD = "--NoBillboard"; ::includeBillboard = !cmdOptionExists(argc, argv, NO_BILLBOARD); + printf("includeBillboard=%s\n",debug::valueOf(::includeBillboard)); const char* NO_BORDER_TRACER = "--NoBorderTracer"; ::includeBorderTracer = !cmdOptionExists(argc, argv, NO_BORDER_TRACER); + printf("includeBorderTracer=%s\n",debug::valueOf(::includeBorderTracer)); const char* NO_MOVING_BUG = "--NoMovingBug"; ::includeMovingBug = !cmdOptionExists(argc, argv, NO_MOVING_BUG); + printf("includeMovingBug=%s\n",debug::valueOf(::includeMovingBug)); const char* INCLUDE_BLINKING_VOXEL = "--includeBlinkingVoxel"; ::includeBlinkingVoxel = cmdOptionExists(argc, argv, INCLUDE_BLINKING_VOXEL); + printf("includeBlinkingVoxel=%s\n",debug::valueOf(::includeBlinkingVoxel)); const char* NO_DANCE_FLOOR = "--NoDanceFloor"; ::includeDanceFloor = !cmdOptionExists(argc, argv, NO_DANCE_FLOOR); + printf("includeDanceFloor=%s\n",debug::valueOf(::includeDanceFloor)); const char* BUILD_STREET = "--BuildStreet"; ::buildStreet = cmdOptionExists(argc, argv, BUILD_STREET); + printf("buildStreet=%s\n",debug::valueOf(::buildStreet)); // Handle Local Domain testing with the --local command line const char* showPPS = "--showPPS"; diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 13865cbacc..054b877488 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -127,6 +127,14 @@ int main(int argc, const char * argv[]) unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE) + numBytesSocket + sizeof(unsigned char); int numInterestTypes = *(nodeTypesOfInterest - 1); + +/* +printf("line 131 newNode=%d type=%c numInterestTypes=%d\n", newNode->getNodeID(), newNode->getType(), numInterestTypes); +for (int t = 0; t < numInterestTypes; t++) { + printf("line 133 t=%d type=%c\n", t, nodeTypesOfInterest[t]); + +} +*/ if (numInterestTypes > 0) { // if the node has sent no types of interest, assume they want nothing but their own ID back @@ -136,15 +144,19 @@ int main(int argc, const char * argv[]) // this is not the node themselves // and this is an node of a type in the passed node types of interest // or the node did not pass us any specific types they are interested in - + +//printf("line 140 node=%d type=%c\n", node->getNodeID(), node->getType()); if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) { // this is an node of which there can be multiple, just add them to the packet // don't send avatar nodes to other avatars, that will come from avatar mixer +//printf("line 144 node=%d type=%c\n", node->getNodeID(), node->getType()); if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) { +//printf("line 146 node=%d type=%c\n", node->getNodeID(), node->getType()); currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node)); } } else { +//printf("line 151 node=%d type=%c\n", node->getNodeID(), node->getType()); // solo node, we need to only send newest if (newestSoloNodes[node->getType()] == NULL || newestSoloNodes[node->getType()]->getWakeMicrostamp() < node->getWakeMicrostamp()) { diff --git a/libraries/shared/src/GenericThread.h b/libraries/shared/src/GenericThread.h index 2d4c90a469..e2dea19ea8 100644 --- a/libraries/shared/src/GenericThread.h +++ b/libraries/shared/src/GenericThread.h @@ -30,10 +30,11 @@ public: /// If you're running in non-threaded mode, you must call this regularly void* threadRoutine(); -protected: /// Override this function to do whatever your class actually does, return false to exit thread early. virtual bool process() = 0; +protected: + /// Locks all the resources of the thread. void lock() { pthread_mutex_lock(&_mutex); } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 23b39df205..0aecf1e52d 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -411,6 +411,7 @@ Node* NodeList::addOrUpdateNode(sockaddr* publicSocket, sockaddr* localSocket, c } else { if (node->getType() == NODE_TYPE_AUDIO_MIXER || + //node->getType() == NODE_TYPE_ANIMATION_SERVER || node->getType() == NODE_TYPE_VOXEL_SERVER) { // until the Audio class also uses our nodeList, we need to update // the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index ecbe15359e..eebe0acb24 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -10,14 +10,19 @@ #include -const uint64_t SEND_INTERVAL_USECS = 1000 * 5; // no more than 200pps... should be settable - #include "NodeList.h" #include "PacketSender.h" #include "SharedUtil.h" -PacketSender::PacketSender(PacketSenderNotify* notify) : _notify(notify) { - _lastSendTime = usecTimestampNow(); +const int PacketSender::DEFAULT_PACKETS_PER_SECOND = 200; +const int PacketSender::MINIMUM_PACKETS_PER_SECOND = 1; + + +PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) : + _packetsPerSecond(packetsPerSecond), + _lastSendTime(usecTimestampNow()), + _notify(notify) +{ } @@ -29,9 +34,14 @@ void PacketSender::queuePacket(sockaddr& address, unsigned char* packetData, ssi } bool PacketSender::process() { +//printf("PacketSender::process() packets pending=%ld _packetsPerSecond=%d\n",_packets.size(),_packetsPerSecond); + + + uint64_t USECS_PER_SECOND = 1000 * 1000; + uint64_t SEND_INTERVAL_USECS = (_packetsPerSecond == 0) ? USECS_PER_SECOND : (USECS_PER_SECOND / _packetsPerSecond); + if (_packets.size() == 0) { - const uint64_t SEND_THREAD_SLEEP_INTERVAL = (1000 * 1000)/60; // check at 60fps - usleep(SEND_THREAD_SLEEP_INTERVAL); + usleep(SEND_INTERVAL_USECS); } while (_packets.size() > 0) { NetworkPacket& packet = _packets.front(); @@ -39,7 +49,9 @@ bool PacketSender::process() { // send the packet through the NodeList... UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); +//printf("sending a packet... length=%lu\n",packet.getLength()); nodeSocket->send(&packet.getAddress(), packet.getData(), packet.getLength()); + if (_notify) { _notify->packetSentNotification(packet.getLength()); } diff --git a/libraries/shared/src/PacketSender.h b/libraries/shared/src/PacketSender.h index bd2ab99407..7b2edacc44 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/shared/src/PacketSender.h @@ -24,8 +24,10 @@ public: /// Generalized threaded processor for queueing and sending of outbound packets. class PacketSender : public GenericThread { public: + static const int DEFAULT_PACKETS_PER_SECOND; + static const int MINIMUM_PACKETS_PER_SECOND; - PacketSender(PacketSenderNotify* notify = NULL); + PacketSender(PacketSenderNotify* notify = NULL, int packetsPerSecond = DEFAULT_PACKETS_PER_SECOND); /// Add packet to outbound queue. /// \param sockaddr& address the destination address @@ -34,14 +36,21 @@ public: /// \thread any thread, typically the application thread void queuePacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength); -private: + void setPacketsPerSecond(int packetsPerSecond) { _packetsPerSecond = std::min(MINIMUM_PACKETS_PER_SECOND, packetsPerSecond); } + int getPacketsPerSecond() const { return _packetsPerSecond; } + + void setPacketSenderNotify(PacketSenderNotify* notify) { _notify = notify; } + PacketSenderNotify* getPacketSenderNotify() const { return _notify; } + virtual bool process(); +protected: + int _packetsPerSecond; + +private: std::vector _packets; uint64_t _lastSendTime; - PacketSenderNotify* _notify; - }; #endif // __shared__PacketSender__ diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index 5040f5a857..1f6ce09da5 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -217,13 +217,15 @@ int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int avail // if and only if there's a root jurisdiction, also include the end nodes int endNodeCount = _endNodes.size(); - memcpy(destinationBuffer, &endNodeCount, sizeof(endNodeCount)); destinationBuffer += sizeof(endNodeCount); for (int i=0; i < endNodeCount; i++) { unsigned char* endNodeCode = _endNodes[i]; - int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode)); + int bytes = 0; + if (endNodeCode) { + bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode)); + } memcpy(destinationBuffer, &bytes, sizeof(bytes)); destinationBuffer += sizeof(bytes); memcpy(destinationBuffer, endNodeCode, bytes); @@ -266,7 +268,11 @@ int JurisdictionMap::unpackFromMessage(unsigned char* sourceBuffer, int availabl unsigned char* endNodeCode = new unsigned char[bytes]; memcpy(endNodeCode, sourceBuffer, bytes); sourceBuffer += bytes; - _endNodes.push_back(endNodeCode); + + // if the endNodeCode was 0 length then don't add it + if (bytes > 0) { + _endNodes.push_back(endNodeCode); + } } } diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index c7e266e430..2c15a98fa1 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -21,6 +21,8 @@ #include #include +#include + #ifdef _WIN32 #include "Syssocket.h" #include "Systime.h" @@ -73,6 +75,7 @@ EnvironmentData environmentData[3]; int receivedPacketCount = 0; JurisdictionMap* jurisdiction = NULL; +JurisdictionSender* jurisdictionSender = NULL; void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) { // randomly generate children for this node @@ -400,7 +403,7 @@ void persistVoxelsWhenDirty() { } } -void *distributeVoxelsToListeners(void *args) { +void* distributeVoxelsToListeners(void* args) { NodeList* nodeList = NodeList::getInstance(); timeval lastSendTime; @@ -408,7 +411,6 @@ void *distributeVoxelsToListeners(void *args) { while (true) { gettimeofday(&lastSendTime, NULL); - // enumerate the nodes to send 3 packets to each for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { VoxelNodeData* nodeData = (VoxelNodeData*) node->getLinkedData(); @@ -482,11 +484,10 @@ int main(int argc, const char * argv[]) { } if (jurisdictionRoot || jurisdictionEndNodes) { - jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes); + ::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes); } } - // should we send environments? Default is yes, but this command line suppresses sending const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove"; ::dumpVoxelsOnMove = cmdOptionExists(argc, argv, DUMP_VOXELS_ON_MOVE); @@ -509,6 +510,10 @@ int main(int argc, const char * argv[]) { NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort); setvbuf(stdout, NULL, _IOLBF, 0); + const int numNodeTypes = 2; + const NODE_TYPE nodeTypes[numNodeTypes] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER }; + NodeList::getInstance()->setNodeTypesOfInterest(&nodeTypes[0], numNodeTypes); + // Handle Local Domain testing with the --local command line const char* local = "--local"; ::wantLocalDomain = cmdOptionExists(argc, argv,local); @@ -655,8 +660,11 @@ int main(int argc, const char * argv[]) { timeval lastDomainServerCheckIn = {}; + // set up our jurisdiction broadcaster... + ::jurisdictionSender = new JurisdictionSender(::jurisdiction); + jurisdictionSender->initialize(true); + // loop to send to nodes requesting data - while (true) { // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed @@ -735,12 +743,30 @@ int main(int argc, const char * argv[]) { voxelData += voxelDataSize; atByte += voxelDataSize; } + + //printf("PACKET_TYPE_SET_VOXEL ...\n"); + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); + if (node) { + //printf("PACKET_TYPE_SET_VOXEL node->setLastHeardMicrostamp(usecTimestampNow());\n"); + node->setLastHeardMicrostamp(usecTimestampNow()); + } + } else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) { // Send these bits off to the VoxelTree class to process them pthread_mutex_lock(&::treeLock); serverTree.processRemoveVoxelBitstream((unsigned char*)packetData, receivedBytes); pthread_mutex_unlock(&::treeLock); + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); + if (node) { + //printf("PACKET_TYPE_ERASE_VOXEL node->setLastHeardMicrostamp(usecTimestampNow());\n"); + node->setLastHeardMicrostamp(usecTimestampNow()); + } + } else if (packetData[0] == PACKET_TYPE_Z_COMMAND) { // the Z command is a special command that allows the sender to send the voxel server high level semantic @@ -774,6 +800,14 @@ int main(int argc, const char * argv[]) { printf("rebroadcasting Z message to connected nodes... nodeList.broadcastToNodes()\n"); nodeList->broadcastToNodes(packetData, receivedBytes, &NODE_TYPE_AGENT, 1); } + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); + if (node) { + printf("PACKET_TYPE_Z_COMMAND node->setLastHeardMicrostamp(usecTimestampNow());\n"); + node->setLastHeardMicrostamp(usecTimestampNow()); + } + } else if (packetData[0] == PACKET_TYPE_HEAD_DATA) { // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we // need to make sure we have it in our nodeList. @@ -789,6 +823,11 @@ int main(int argc, const char * argv[]) { } else if (packetData[0] == PACKET_TYPE_PING) { // If the packet is a ping, let processNodeData handle it. nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); + } else if (packetData[0] == PACKET_TYPE_DOMAIN) { + //printf("PACKET_TYPE_DOMAIN packet\n"); + nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); + } else { + printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]); } } } @@ -796,8 +835,13 @@ int main(int argc, const char * argv[]) { pthread_join(sendVoxelThread, NULL); pthread_mutex_destroy(&::treeLock); - if (jurisdiction) { - delete jurisdiction; + if (::jurisdiction) { + delete ::jurisdiction; + } + + if (::jurisdictionSender) { + jurisdictionSender->terminate(); + delete ::jurisdictionSender; } return 0; From 55a025a0ed42b100d8e06f2f27e3616b780bed73 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 19 Aug 2013 11:16:22 -0700 Subject: [PATCH 08/20] removed debug --- domain-server/src/main.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 054b877488..51eea6b838 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -127,14 +127,6 @@ int main(int argc, const char * argv[]) unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE) + numBytesSocket + sizeof(unsigned char); int numInterestTypes = *(nodeTypesOfInterest - 1); - -/* -printf("line 131 newNode=%d type=%c numInterestTypes=%d\n", newNode->getNodeID(), newNode->getType(), numInterestTypes); -for (int t = 0; t < numInterestTypes; t++) { - printf("line 133 t=%d type=%c\n", t, nodeTypesOfInterest[t]); - -} -*/ if (numInterestTypes > 0) { // if the node has sent no types of interest, assume they want nothing but their own ID back @@ -145,18 +137,14 @@ for (int t = 0; t < numInterestTypes; t++) { // and this is an node of a type in the passed node types of interest // or the node did not pass us any specific types they are interested in -//printf("line 140 node=%d type=%c\n", node->getNodeID(), node->getType()); if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) { // this is an node of which there can be multiple, just add them to the packet // don't send avatar nodes to other avatars, that will come from avatar mixer -//printf("line 144 node=%d type=%c\n", node->getNodeID(), node->getType()); if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) { -//printf("line 146 node=%d type=%c\n", node->getNodeID(), node->getType()); currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node)); } } else { -//printf("line 151 node=%d type=%c\n", node->getNodeID(), node->getType()); // solo node, we need to only send newest if (newestSoloNodes[node->getType()] == NULL || newestSoloNodes[node->getType()]->getWakeMicrostamp() < node->getWakeMicrostamp()) { From 5e7e6fc9d73d91f45f5f35b4864cd1875ed4a602 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 19 Aug 2013 20:15:46 -0700 Subject: [PATCH 09/20] First cut at JurisdictionListener and PACKET_TYPE_VOXEL_JURISDICTION_REQUEST --- animation-server/src/main.cpp | 22 ++++++ interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- interface/src/VoxelPacketProcessor.h | 3 +- libraries/shared/src/GenericThread.h | 2 + libraries/shared/src/PacketHeaders.h | 1 + libraries/shared/src/PacketSender.cpp | 6 +- libraries/shared/src/PacketSender.h | 7 +- .../shared/src/ReceivedPacketProcessor.cpp | 15 +++- .../shared/src/ReceivedPacketProcessor.h | 11 ++- libraries/voxels/src/JurisdictionListener.cpp | 75 ++++++++++++++++++ libraries/voxels/src/JurisdictionListener.h | 47 ++++++++++++ libraries/voxels/src/JurisdictionMap.h | 6 ++ libraries/voxels/src/JurisdictionSender.cpp | 76 ++++++++++++------- libraries/voxels/src/JurisdictionSender.h | 13 +++- .../voxels/src/VoxelEditPacketSender.cpp | 2 +- libraries/voxels/src/VoxelEditPacketSender.h | 4 +- voxel-server/src/main.cpp | 8 +- 18 files changed, 255 insertions(+), 47 deletions(-) create mode 100644 libraries/voxels/src/JurisdictionListener.cpp create mode 100644 libraries/voxels/src/JurisdictionListener.h diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 1031a71479..ca2cad1bc2 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,10 @@ bool wantLocalDomain = false; unsigned long packetsSent = 0; unsigned long bytesSent = 0; + +JurisdictionListener* jurisdictionListener = NULL; + + static void sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail) { unsigned char* bufferOut; int sizeOut; @@ -777,6 +782,12 @@ int main(int argc, const char * argv[]) nodeList->linkedDataCreateCallback = NULL; // do we need a callback? nodeList->startSilentNodeRemovalThread(); + // Create our JurisdictionListener so we'll know where to send edit packets + ::jurisdictionListener = new JurisdictionListener(); + if (::jurisdictionListener) { + ::jurisdictionListener->initialize(true); + } + srand((unsigned)time(0)); pthread_t animateVoxelThread; @@ -801,11 +812,22 @@ int main(int argc, const char * argv[]) // Nodes sending messages to us... if (nodeList->getNodeSocket()->receive(&nodePublicAddress, packetData, &receivedBytes) && packetVersionMatch(packetData)) { + + if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { + if (::jurisdictionListener) { + ::jurisdictionListener->queueReceivedPacket(nodePublicAddress, packetData, receivedBytes); + } + } NodeList::getInstance()->processNodeData(&nodePublicAddress, packetData, receivedBytes); } } pthread_join(animateVoxelThread, NULL); + + if (::jurisdictionListener) { + ::jurisdictionListener->terminate(); + delete ::jurisdictionListener; + } return 0; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ab1b222753..5be6556e8a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3271,7 +3271,7 @@ void* Application::networkReceive(void* args) { case PACKET_TYPE_VOXEL_STATS: case PACKET_TYPE_ENVIRONMENT_DATA: { // add this packet to our list of voxel packets and process them on the voxel processing - app->_voxelProcessor.queuePacket(senderAddress, app->_incomingPacket, bytesReceived); + app->_voxelProcessor.queueReceivedPacket(senderAddress, app->_incomingPacket, bytesReceived); break; } case PACKET_TYPE_BULK_AVATAR_DATA: diff --git a/interface/src/Application.h b/interface/src/Application.h index 1a3334ecec..abbb66ec98 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -343,7 +343,7 @@ private: VoxelSceneStats _voxelSceneStats; int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress); - std::map _voxelServerJurisdictions; + NodeToJurisdictionMap _voxelServerJurisdictions; std::vector _voxelFades; }; diff --git a/interface/src/VoxelPacketProcessor.h b/interface/src/VoxelPacketProcessor.h index 0a89d0d03e..87aae397d5 100644 --- a/interface/src/VoxelPacketProcessor.h +++ b/interface/src/VoxelPacketProcessor.h @@ -13,7 +13,8 @@ #include -/// Handles processing of incoming voxel packets for the interface application. +/// 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 VoxelPacketProcessor : public ReceivedPacketProcessor { protected: virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); diff --git a/libraries/shared/src/GenericThread.h b/libraries/shared/src/GenericThread.h index e2dea19ea8..e363d16178 100644 --- a/libraries/shared/src/GenericThread.h +++ b/libraries/shared/src/GenericThread.h @@ -41,6 +41,8 @@ protected: /// Unlocks all the resources of the thread. void unlock() { pthread_mutex_unlock(&_mutex); } + bool isStillRunning() const { return !_stopThread; } + private: pthread_mutex_t _mutex; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 720fb69936..2f4f8d2196 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -39,6 +39,7 @@ const PACKET_TYPE PACKET_TYPE_REQUEST_ASSIGNMENT = 'r'; const PACKET_TYPE PACKET_TYPE_SEND_ASSIGNMENT = 's'; const PACKET_TYPE PACKET_TYPE_VOXEL_STATS = '#'; const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION = 'J'; +const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION_REQUEST = 'j'; typedef char PACKET_VERSION; diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index eebe0acb24..9397e44be0 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -26,7 +26,7 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) : } -void PacketSender::queuePacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { +void PacketSender::queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { NetworkPacket packet(address, packetData, packetLength); lock(); _packets.push_back(packet); @@ -34,9 +34,6 @@ void PacketSender::queuePacket(sockaddr& address, unsigned char* packetData, ssi } bool PacketSender::process() { -//printf("PacketSender::process() packets pending=%ld _packetsPerSecond=%d\n",_packets.size(),_packetsPerSecond); - - uint64_t USECS_PER_SECOND = 1000 * 1000; uint64_t SEND_INTERVAL_USECS = (_packetsPerSecond == 0) ? USECS_PER_SECOND : (USECS_PER_SECOND / _packetsPerSecond); @@ -49,7 +46,6 @@ bool PacketSender::process() { // send the packet through the NodeList... UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); -//printf("sending a packet... length=%lu\n",packet.getLength()); nodeSocket->send(&packet.getAddress(), packet.getData(), packet.getLength()); if (_notify) { diff --git a/libraries/shared/src/PacketSender.h b/libraries/shared/src/PacketSender.h index 7b2edacc44..3a07444f2b 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/shared/src/PacketSender.h @@ -22,7 +22,7 @@ public: /// Generalized threaded processor for queueing and sending of outbound packets. -class PacketSender : public GenericThread { +class PacketSender : public virtual GenericThread { public: static const int DEFAULT_PACKETS_PER_SECOND; static const int MINIMUM_PACKETS_PER_SECOND; @@ -34,7 +34,7 @@ public: /// \param packetData pointer to data /// \param ssize_t packetLength size of data /// \thread any thread, typically the application thread - void queuePacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength); + void queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength); void setPacketsPerSecond(int packetsPerSecond) { _packetsPerSecond = std::min(MINIMUM_PACKETS_PER_SECOND, packetsPerSecond); } int getPacketsPerSecond() const { return _packetsPerSecond; } @@ -46,6 +46,9 @@ public: protected: int _packetsPerSecond; + + bool hasPacketsToSend() const { return _packets.size() > 0; } + int packetsToSendCount() const { return _packets.size(); } private: std::vector _packets; diff --git a/libraries/shared/src/ReceivedPacketProcessor.cpp b/libraries/shared/src/ReceivedPacketProcessor.cpp index 3b6ccf5a98..f1c6e4f8df 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.cpp +++ b/libraries/shared/src/ReceivedPacketProcessor.cpp @@ -8,9 +8,20 @@ // Threaded or non-threaded packet receiver. // +#include "NodeList.h" #include "ReceivedPacketProcessor.h" +#include "SharedUtil.h" + +void ReceivedPacketProcessor::queueReceivedPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { + //printf("ReceivedPacketProcessor::queueReceivedPacket() packetData=%p, packetLength=%lu\n", packetData, packetLength); + + + // Make sure our Node and NodeList knows we've heard from this node. + Node* node = NodeList::getInstance()->nodeWithAddress(&address); + if (node) { + node->setLastHeardMicrostamp(usecTimestampNow()); + } -void ReceivedPacketProcessor::queuePacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { NetworkPacket packet(address, packetData, packetLength); lock(); _packets.push_back(packet); @@ -19,10 +30,12 @@ void ReceivedPacketProcessor::queuePacket(sockaddr& address, unsigned char* pack bool ReceivedPacketProcessor::process() { if (_packets.size() == 0) { + //printf("ReceivedPacketProcessor::process() no packets... sleeping... \n"); const uint64_t RECEIVED_THREAD_SLEEP_INTERVAL = (1000 * 1000)/60; // check at 60fps usleep(RECEIVED_THREAD_SLEEP_INTERVAL); } while (_packets.size() > 0) { + //printf("ReceivedPacketProcessor::process() we got packets!! call processPacket() \n"); NetworkPacket& packet = _packets.front(); processPacket(packet.getAddress(), packet.getData(), packet.getLength()); diff --git a/libraries/shared/src/ReceivedPacketProcessor.h b/libraries/shared/src/ReceivedPacketProcessor.h index 0ea1aba2c1..f6d49cbb09 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.h +++ b/libraries/shared/src/ReceivedPacketProcessor.h @@ -15,7 +15,7 @@ #include "NetworkPacket.h" /// Generalized threaded processor for handling received inbound packets. -class ReceivedPacketProcessor : public GenericThread { +class ReceivedPacketProcessor : public virtual GenericThread { public: /// Add packet from network receive thread to the processing queue. @@ -23,7 +23,7 @@ public: /// \param packetData pointer to received data /// \param ssize_t packetLength size of received data /// \thread network receive thread - void queuePacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + void queueReceivedPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); protected: /// Callback for processing of recieved packets. Implement this to process the incoming packets. @@ -35,6 +35,13 @@ protected: /// Implements generic processing behavior for this thread. virtual bool process(); + + /// Are there received packets waiting to be processed + bool hasPacketsToProcess() const { return _packets.size() > 0; } + + /// How many received packets waiting are to be processed + int packetsToProcessCount() const { return _packets.size(); } + private: std::vector _packets; diff --git a/libraries/voxels/src/JurisdictionListener.cpp b/libraries/voxels/src/JurisdictionListener.cpp new file mode 100644 index 0000000000..ceb2fbcf0c --- /dev/null +++ b/libraries/voxels/src/JurisdictionListener.cpp @@ -0,0 +1,75 @@ +// +// JurisdictionListener.cpp +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Threaded or non-threaded jurisdiction Sender for the Application +// + +#include + +#include +#include +#include +#include "JurisdictionListener.h" + + +JurisdictionListener::JurisdictionListener(PacketSenderNotify* notify) : + PacketSender(notify, JurisdictionListener::DEFAULT_PACKETS_PER_SECOND) +{ +} + +bool JurisdictionListener::queueJurisdictionRequest() { + static unsigned char buffer[MAX_PACKET_SIZE]; + unsigned char* bufferOut = &buffer[0]; + ssize_t sizeOut = populateTypeAndVersion(bufferOut, PACKET_TYPE_VOXEL_JURISDICTION_REQUEST); + int nodeCount = 0; + + NodeList* nodeList = NodeList::getInstance(); + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + + // only send to the NodeTypes that are interested in our jurisdiction details + const int numNodeTypes = 1; + const NODE_TYPE nodeTypes[numNodeTypes] = { NODE_TYPE_VOXEL_SERVER }; + if (node->getActiveSocket() != NULL && memchr(nodeTypes, node->getType(), numNodeTypes)) { + sockaddr* nodeAddress = node->getActiveSocket(); + PacketSender::queuePacketForSending(*nodeAddress, bufferOut, sizeOut); + nodeCount++; + } + } + + // set our packets per second to be the number of nodes + setPacketsPerSecond(nodeCount); + + // keep going if still running + return isStillRunning(); +} + +void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { + if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { + Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + if (node) { + uint16_t nodeID = node->getNodeID(); + JurisdictionMap map; + map.unpackFromMessage(packetData, packetLength); + _jurisdictions[nodeID] = map; + } + } +} + +bool JurisdictionListener::process() { + bool continueProcessing = isStillRunning(); + + // If we're still running, and we don't have any requests waiting to be sent, then queue our jurisdiction requests + if (continueProcessing && !hasPacketsToSend()) { + queueJurisdictionRequest(); + continueProcessing = PacketSender::process(); + } + if (continueProcessing) { + // NOTE: This will sleep if there are no pending packets to process + continueProcessing = ReceivedPacketProcessor::process(); + } + return continueProcessing; +} diff --git a/libraries/voxels/src/JurisdictionListener.h b/libraries/voxels/src/JurisdictionListener.h new file mode 100644 index 0000000000..4954d480e1 --- /dev/null +++ b/libraries/voxels/src/JurisdictionListener.h @@ -0,0 +1,47 @@ +// +// JurisdictionListener.h +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Voxel Packet Sender +// + +#ifndef __shared__JurisdictionListener__ +#define __shared__JurisdictionListener__ + +#include +#include + +#include "JurisdictionMap.h" + +/// Sends out PACKET_TYPE_VOXEL_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes +/// the PACKET_TYPE_VOXEL_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions +/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets +/// and adding them to the processing queue by calling queueReceivedPacket() +class JurisdictionListener : public PacketSender, public ReceivedPacketProcessor { +public: + static const int DEFAULT_PACKETS_PER_SECOND = 1; + + JurisdictionListener(PacketSenderNotify* notify = NULL); + virtual bool process(); + + const NodeToJurisdictionMap& getJurisdictions() const { return _jurisdictions; }; + +protected: + /// Callback for processing of received packets. Will process any queued PACKET_TYPE_VOXEL_JURISDICTION and update the + /// jurisdiction map member variable + /// \param sockaddr& senderAddress the address of the sender + /// \param packetData pointer to received data + /// \param ssize_t packetLength size of received data + /// \thread "this" individual processing thread + virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + +private: + NodeToJurisdictionMap _jurisdictions; + + bool queueJurisdictionRequest(); + +}; +#endif // __shared__JurisdictionListener__ diff --git a/libraries/voxels/src/JurisdictionMap.h b/libraries/voxels/src/JurisdictionMap.h index 68a608f49b..80fcef2ced 100644 --- a/libraries/voxels/src/JurisdictionMap.h +++ b/libraries/voxels/src/JurisdictionMap.h @@ -10,6 +10,7 @@ #define __hifi__JurisdictionMap__ #include +#include #include class JurisdictionMap { @@ -62,6 +63,11 @@ private: std::vector _endNodes; }; +/// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are +/// managing which jurisdictions. +typedef std::map NodeToJurisdictionMap; + + #endif /* defined(__hifi__JurisdictionMap__) */ diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index f1afdf444c..bb5262eddc 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -18,39 +18,59 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* notify) : PacketSender(notify, JurisdictionSender::DEFAULT_PACKETS_PER_SECOND), + ReceivedPacketProcessor(), _jurisdictionMap(map) { } -bool JurisdictionSender::process() { -//printf("JurisdictionSender::process() _packetsPerSecond=%d\n", _packetsPerSecond); - // add our packet to our own queue, then let the PacketSender class do the rest of the work. - if (_jurisdictionMap) { -//printf("JurisdictionSender::process() _jurisdictionMap=%p\n",_jurisdictionMap); - unsigned char buffer[MAX_PACKET_SIZE]; - unsigned char* bufferOut = &buffer[0]; - ssize_t sizeOut = _jurisdictionMap->packIntoMessage(bufferOut, MAX_PACKET_SIZE); - int nodeCount = 0; - - NodeList* nodeList = NodeList::getInstance(); - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - -//printf("JurisdictionSender::process() node loop node=%d type=%c\n",node->getNodeID(), node->getType()); - - // only send to the NodeTypes that are interested in our jurisdiction details - const int numNodeTypes = 1; - const NODE_TYPE nodeTypes[numNodeTypes] = { NODE_TYPE_ANIMATION_SERVER }; - if (node->getActiveSocket() != NULL && memchr(nodeTypes, node->getType(), numNodeTypes)) { - sockaddr* nodeAddress = node->getActiveSocket(); - queuePacket(*nodeAddress, bufferOut, sizeOut); - nodeCount++; - } +void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { + if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { + Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + if (node) { + uint16_t nodeID = node->getNodeID(); + lock(); + _nodesRequestingJurisdictions.insert(nodeID); + unlock(); } - - // set our packets per second to be the number of nodes - setPacketsPerSecond(nodeCount); - printf("loaded %d packets to send\n", nodeCount); + } +} + +bool JurisdictionSender::process() { + bool continueProcessing = isStillRunning(); + + // call our ReceivedPacketProcessor base class process so we'll get any pending packets + if (continueProcessing) { + continueProcessing = ReceivedPacketProcessor::process(); } - return PacketSender::process(); + if (continueProcessing) { + // add our packet to our own queue, then let the PacketSender class do the rest of the work. + if (_jurisdictionMap) { + unsigned char buffer[MAX_PACKET_SIZE]; + unsigned char* bufferOut = &buffer[0]; + ssize_t sizeOut = _jurisdictionMap->packIntoMessage(bufferOut, MAX_PACKET_SIZE); + int nodeCount = 0; + + for (std::set::iterator nodeIterator = _nodesRequestingJurisdictions.begin(); + nodeIterator != _nodesRequestingJurisdictions.end(); nodeIterator++) { + + uint16_t nodeID = *nodeIterator; + Node* node = NodeList::getInstance()->nodeWithID(nodeID); + + if (node->getActiveSocket() != NULL) { + sockaddr* nodeAddress = node->getActiveSocket(); + queuePacketForSending(*nodeAddress, bufferOut, sizeOut); + nodeCount++; + // remove it from the set + _nodesRequestingJurisdictions.erase(nodeIterator); + } + } + + // set our packets per second to be the number of nodes + setPacketsPerSecond(nodeCount); + } + + continueProcessing = PacketSender::process(); + } + return continueProcessing; } diff --git a/libraries/voxels/src/JurisdictionSender.h b/libraries/voxels/src/JurisdictionSender.h index 10d763cfdd..34f5a9f06f 100644 --- a/libraries/voxels/src/JurisdictionSender.h +++ b/libraries/voxels/src/JurisdictionSender.h @@ -11,11 +11,16 @@ #ifndef __shared__JurisdictionSender__ #define __shared__JurisdictionSender__ +#include + #include +#include #include "JurisdictionMap.h" -/// Threaded processor for queueing and sending of outbound edit voxel packets. -class JurisdictionSender : public PacketSender { +/// Will process PACKET_TYPE_VOXEL_JURISDICTION_REQUEST packets and send out PACKET_TYPE_VOXEL_JURISDICTION packets +/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets +/// and adding them to the processing queue by calling queueReceivedPacket() +class JurisdictionSender : public PacketSender, public ReceivedPacketProcessor { public: static const int DEFAULT_PACKETS_PER_SECOND = 1; @@ -25,7 +30,11 @@ public: virtual bool process(); +protected: + virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + private: JurisdictionMap* _jurisdictionMap; + std::set _nodesRequestingJurisdictions; }; #endif // __shared__JurisdictionSender__ diff --git a/libraries/voxels/src/VoxelEditPacketSender.cpp b/libraries/voxels/src/VoxelEditPacketSender.cpp index cfc3cab218..605fb9e9e9 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.cpp +++ b/libraries/voxels/src/VoxelEditPacketSender.cpp @@ -43,7 +43,7 @@ void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char* if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER && ((node->getNodeID() == nodeID) || (nodeID == (uint16_t)UNKNOWN_NODE_ID)) ) { sockaddr* nodeAddress = node->getActiveSocket(); - queuePacket(*nodeAddress, bufferOut, sizeOut); + queuePacketForSending(*nodeAddress, bufferOut, sizeOut); } } } diff --git a/libraries/voxels/src/VoxelEditPacketSender.h b/libraries/voxels/src/VoxelEditPacketSender.h index a45f677cee..935996bb4b 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.h +++ b/libraries/voxels/src/VoxelEditPacketSender.h @@ -43,7 +43,7 @@ public: bool getShouldSend() const { return _shouldSend; } void setShouldSend(bool shouldSend) { _shouldSend = shouldSend; } - void setVoxelServerJurisdictions(std::map* voxelServerJurisdictions) { + void setVoxelServerJurisdictions(NodeToJurisdictionMap* voxelServerJurisdictions) { _voxelServerJurisdictions = voxelServerJurisdictions; } @@ -55,6 +55,6 @@ private: std::map _pendingEditPackets; - std::map* _voxelServerJurisdictions; + NodeToJurisdictionMap* _voxelServerJurisdictions; }; #endif // __shared__VoxelEditPacketSender__ diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 2c15a98fa1..1f1e05cc0c 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -662,7 +662,9 @@ int main(int argc, const char * argv[]) { // set up our jurisdiction broadcaster... ::jurisdictionSender = new JurisdictionSender(::jurisdiction); - jurisdictionSender->initialize(true); + if (::jurisdictionSender) { + ::jurisdictionSender->initialize(true); + } // loop to send to nodes requesting data while (true) { @@ -826,6 +828,10 @@ int main(int argc, const char * argv[]) { } else if (packetData[0] == PACKET_TYPE_DOMAIN) { //printf("PACKET_TYPE_DOMAIN packet\n"); nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); + } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { + if (::jurisdictionSender) { + jurisdictionSender->queueReceivedPacket(nodePublicAddress, packetData, receivedBytes); + } } else { printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]); } From 0f7ea55e82412b0d085a5ff2f26c34e98f687c1d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:08:20 -0700 Subject: [PATCH 10/20] make animation-server work with jurisdictions --- animation-server/src/main.cpp | 131 ++++-------------- libraries/shared/src/SharedUtil.cpp | 32 +++++ libraries/shared/src/SharedUtil.h | 6 + libraries/voxels/src/JurisdictionListener.cpp | 6 + libraries/voxels/src/JurisdictionListener.h | 2 +- libraries/voxels/src/JurisdictionMap.cpp | 13 ++ libraries/voxels/src/JurisdictionMap.h | 2 + libraries/voxels/src/JurisdictionSender.cpp | 6 + .../voxels/src/VoxelEditPacketSender.cpp | 15 ++ libraries/voxels/src/VoxelEditPacketSender.h | 4 + 10 files changed, 113 insertions(+), 104 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index ca2cad1bc2..9b43378eb2 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #ifdef _WIN32 @@ -52,26 +53,9 @@ unsigned long bytesSent = 0; JurisdictionListener* jurisdictionListener = NULL; +VoxelEditPacketSender* voxelEditPacketSender = NULL; -static void sendVoxelEditMessage(PACKET_TYPE type, VoxelDetail& detail) { - unsigned char* bufferOut; - int sizeOut; - - if (createVoxelEditMessage(type, 0, 1, &detail, bufferOut, sizeOut)){ - - ::packetsSent++; - ::bytesSent += sizeOut; - - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n",sizeOut); - } - - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } -} - glm::vec3 rotatePoint(glm::vec3 point, float angle) { // First, create the quaternion based on this angle of rotation glm::quat q(glm::vec3(0, -angle, 0)); @@ -146,8 +130,6 @@ const BugPart bugParts[VOXELS_PER_BUG] = { static void renderMovingBug() { VoxelDetail details[VOXELS_PER_BUG]; - unsigned char* bufferOut; - int sizeOut; // Generate voxels for where bug used to be for (int i = 0; i < VOXELS_PER_BUG; i++) { @@ -168,17 +150,7 @@ static void renderMovingBug() { // send the "erase message" first... PACKET_TYPE message = PACKET_TYPE_ERASE_VOXEL; - if (createVoxelEditMessage(message, 0, VOXELS_PER_BUG, (VoxelDetail*)&details, bufferOut, sizeOut)){ - - ::packetsSent++; - ::bytesSent += sizeOut; - - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n", sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } + ::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details); // Move the bug... if (moveBugInLine) { @@ -238,17 +210,7 @@ static void renderMovingBug() { // send the "create message" ... message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; - if (createVoxelEditMessage(message, 0, VOXELS_PER_BUG, (VoxelDetail*)&details, bufferOut, sizeOut)){ - - ::packetsSent++; - ::bytesSent += sizeOut; - - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n", sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } + ::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details); } @@ -284,7 +246,7 @@ static void sendVoxelBlinkMessage() { PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; - sendVoxelEditMessage(message, detail); + ::voxelEditPacketSender->sendVoxelEditMessage(message, detail); } bool stringOfLightsInitialized = false; @@ -302,8 +264,6 @@ static void sendBlinkingStringOfLights() { PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! float lightScale = STRING_OF_LIGHTS_SIZE; static VoxelDetail details[LIGHTS_PER_SEGMENT]; - unsigned char* bufferOut; - int sizeOut; // first initialized the string of lights if needed... if (!stringOfLightsInitialized) { @@ -343,19 +303,7 @@ static void sendBlinkingStringOfLights() { details[indexInSegment].blue = offColor[2]; } - // send entire segment at once - if (createVoxelEditMessage(message, 0, LIGHTS_PER_SEGMENT, (VoxelDetail*)&details, bufferOut, sizeOut)){ - - ::packetsSent++; - ::bytesSent += sizeOut; - - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n",sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } - + ::voxelEditPacketSender->queueVoxelEditMessages(message, LIGHTS_PER_SEGMENT, (VoxelDetail*)&details); } stringOfLightsInitialized = true; } else { @@ -386,17 +334,7 @@ static void sendBlinkingStringOfLights() { details[1].blue = onColor[2]; // send both changes in same message - if (createVoxelEditMessage(message, 0, 2, (VoxelDetail*)&details, bufferOut, sizeOut)){ - - ::packetsSent++; - ::bytesSent += sizeOut; - - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n",sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } + ::voxelEditPacketSender->queueVoxelEditMessages(message, 2, (VoxelDetail*)&details); } } @@ -432,8 +370,6 @@ void sendDanceFloor() { PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! float lightScale = DANCE_FLOOR_LIGHT_SIZE; static VoxelDetail details[DANCE_FLOOR_VOXELS_PER_PACKET]; - unsigned char* bufferOut; - int sizeOut; // first initialized the billboard of lights if needed... if (!::danceFloorInitialized) { @@ -510,16 +446,7 @@ void sendDanceFloor() { } if (item == DANCE_FLOOR_VOXELS_PER_PACKET - 1) { - if (createVoxelEditMessage(message, 0, DANCE_FLOOR_VOXELS_PER_PACKET, - (VoxelDetail*)&details, bufferOut, sizeOut)){ - ::packetsSent++; - ::bytesSent += sizeOut; - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n", sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } + ::voxelEditPacketSender->queueVoxelEditMessages(message, DANCE_FLOOR_VOXELS_PER_PACKET, (VoxelDetail*)&details); } } } @@ -559,8 +486,6 @@ static void sendBillboard() { PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! float lightScale = BILLBOARD_LIGHT_SIZE; static VoxelDetail details[VOXELS_PER_PACKET]; - unsigned char* bufferOut; - int sizeOut; // first initialized the billboard of lights if needed... if (!billboardInitialized) { @@ -608,15 +533,7 @@ static void sendBillboard() { } if (item == VOXELS_PER_PACKET - 1) { - if (createVoxelEditMessage(message, 0, VOXELS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){ - ::packetsSent++; - ::bytesSent += sizeOut; - if (::shouldShowPacketsPerSecond) { - printf("sending packet of size=%d\n", sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } + ::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_PACKET, (VoxelDetail*)&details); } } } @@ -639,8 +556,6 @@ void doBuildStreet() { PACKET_TYPE message = PACKET_TYPE_SET_VOXEL_DESTRUCTIVE; // we're a bully! static VoxelDetail details[BRICKS_PER_PACKET]; - unsigned char* bufferOut; - int sizeOut; for (int z = 0; z < ROAD_LENGTH; z++) { for (int x = 0; x < ROAD_WIDTH; x++) { @@ -661,15 +576,7 @@ void doBuildStreet() { details[item].blue = randomTone; if (item == BRICKS_PER_PACKET - 1) { - if (createVoxelEditMessage(message, 0, BRICKS_PER_PACKET, (VoxelDetail*)&details, bufferOut, sizeOut)){ - ::packetsSent++; - ::bytesSent += sizeOut; - if (true || ::shouldShowPacketsPerSecond) { - printf("building road sending packet of size=%d\n", sizeOut); - } - NodeList::getInstance()->broadcastToNodes(bufferOut, sizeOut, &NODE_TYPE_VOXEL_SERVER, 1); - delete[] bufferOut; - } + ::voxelEditPacketSender->queueVoxelEditMessages(message, BRICKS_PER_PACKET, (VoxelDetail*)&details); } } } @@ -710,6 +617,10 @@ void* animateVoxels(void* args) { doBuildStreet(); } + if (::voxelEditPacketSender) { + ::voxelEditPacketSender->flushQueue(); + } + uint64_t end = usecTimestampNow(); uint64_t elapsedSeconds = (end - ::start) / 1000000; if (::shouldShowPacketsPerSecond) { @@ -788,6 +699,15 @@ int main(int argc, const char * argv[]) ::jurisdictionListener->initialize(true); } + // Create out VoxelEditPacketSender + ::voxelEditPacketSender = new VoxelEditPacketSender; + if (::voxelEditPacketSender) { + ::voxelEditPacketSender->initialize(true); + if (::jurisdictionListener) { + ::voxelEditPacketSender->setVoxelServerJurisdictions(::jurisdictionListener->getJurisdictions()); + } + } + srand((unsigned)time(0)); pthread_t animateVoxelThread; @@ -829,5 +749,10 @@ int main(int argc, const char * argv[]) delete ::jurisdictionListener; } + if (::voxelEditPacketSender) { + ::voxelEditPacketSender->terminate(); + delete ::voxelEditPacketSender; + } + return 0; } diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index cf2374b84e..c34663c077 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -255,6 +255,38 @@ bool createVoxelEditMessage(unsigned char command, short int sequence, return success; } +/// encodes the voxel details portion of a voxel edit message +bool encodeVoxelEditMessageDetails(unsigned char command, int voxelCount, VoxelDetail* voxelDetails, + unsigned char* bufferOut, int sizeIn, int& sizeOut) { + + bool success = true; // assume the best + unsigned char* copyAt = bufferOut; + sizeOut = 0; + + for (int i = 0; i < voxelCount && success; i++) { + // get the coded voxel + unsigned char* voxelData = pointToVoxel(voxelDetails[i].x,voxelDetails[i].y,voxelDetails[i].z, + voxelDetails[i].s,voxelDetails[i].red,voxelDetails[i].green,voxelDetails[i].blue); + + int lengthOfVoxelData = bytesRequiredForCodeLength(*voxelData)+SIZE_OF_COLOR_DATA; + + // make sure we have room to copy this voxel + if (sizeOut + lengthOfVoxelData > sizeIn) { + success = false; + } else { + // add it to our message + memcpy(copyAt, voxelData, lengthOfVoxelData); + copyAt += lengthOfVoxelData; + sizeOut += lengthOfVoxelData; + } + // cleanup + delete[] voxelData; + } + + return success; +} + + ////////////////////////////////////////////////////////////////////////////////////////// // Function: pointToVoxel() // Description: Given a universal point with location x,y,z this will return the voxel diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 49e8ae6f02..32553b967b 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -81,9 +81,15 @@ struct VoxelDetail { }; unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r = 0, unsigned char g = 0, unsigned char b = 0); + +// Creates a full Voxel edit message, including command header, sequence, and details bool createVoxelEditMessage(unsigned char command, short int sequence, int voxelCount, VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut); +/// encodes the voxel details portion of a voxel edit message +bool encodeVoxelEditMessageDetails(unsigned char command, int voxelCount, VoxelDetail* voxelDetails, + unsigned char* bufferOut, int sizeIn, int& sizeOut); + #ifdef _WIN32 void usleep(int waitTime); #endif diff --git a/libraries/voxels/src/JurisdictionListener.cpp b/libraries/voxels/src/JurisdictionListener.cpp index ceb2fbcf0c..a084dab114 100644 --- a/libraries/voxels/src/JurisdictionListener.cpp +++ b/libraries/voxels/src/JurisdictionListener.cpp @@ -48,13 +48,19 @@ bool JurisdictionListener::queueJurisdictionRequest() { } void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { +printf("processPacket()\n"); if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { +printf("processPacket()... PACKET_TYPE_VOXEL_JURISDICTION\n"); + Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (node) { uint16_t nodeID = node->getNodeID(); JurisdictionMap map; map.unpackFromMessage(packetData, packetLength); _jurisdictions[nodeID] = map; + + qDebug() << "Got a new map...\n"; + map.displayDebugDetails(); } } } diff --git a/libraries/voxels/src/JurisdictionListener.h b/libraries/voxels/src/JurisdictionListener.h index 4954d480e1..4b5d2d1fa4 100644 --- a/libraries/voxels/src/JurisdictionListener.h +++ b/libraries/voxels/src/JurisdictionListener.h @@ -27,7 +27,7 @@ public: JurisdictionListener(PacketSenderNotify* notify = NULL); virtual bool process(); - const NodeToJurisdictionMap& getJurisdictions() const { return _jurisdictions; }; + NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; }; protected: /// Callback for processing of received packets. Will process any queued PACKET_TYPE_VOXEL_JURISDICTION and update the diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index 1f6ce09da5..9a14bc31e6 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -181,6 +182,18 @@ bool JurisdictionMap::readFromFile(const char* filename) { return true; } +void JurisdictionMap::displayDebugDetails() { + QString rootNodeValue = octalCodeToHexString(_rootOctalCode); + + qDebug() << "root:" << rootNodeValue << "\n"; + + for (int i = 0; i < _endNodes.size(); i++) { + QString value = octalCodeToHexString(_endNodes[i]); + qDebug() << "End node[" << i << "]: " << rootNodeValue << "\n"; + } +} + + bool JurisdictionMap::writeToFile(const char* filename) { QString settingsFile(filename); QSettings settings(settingsFile, QSettings::IniFormat); diff --git a/libraries/voxels/src/JurisdictionMap.h b/libraries/voxels/src/JurisdictionMap.h index 80fcef2ced..67adbf79a9 100644 --- a/libraries/voxels/src/JurisdictionMap.h +++ b/libraries/voxels/src/JurisdictionMap.h @@ -53,6 +53,8 @@ public: int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes); int packIntoMessage(unsigned char* destinationBuffer, int availableBytes); + + void displayDebugDetails(); private: void copyContents(const JurisdictionMap& other); // use assignment instead diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index bb5262eddc..2ff76656a9 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -25,6 +25,7 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { +printf("processPacket()... PACKET_TYPE_VOXEL_JURISDICTION_REQUEST\n"); Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (node) { uint16_t nodeID = node->getNodeID(); @@ -59,6 +60,9 @@ bool JurisdictionSender::process() { if (node->getActiveSocket() != NULL) { sockaddr* nodeAddress = node->getActiveSocket(); + +printf("JurisdictionSender::process()... queuePacketForSending(PACKET_TYPE_VOXEL_JURISDICTION)\n"); + queuePacketForSending(*nodeAddress, bufferOut, sizeOut); nodeCount++; // remove it from the set @@ -68,6 +72,8 @@ bool JurisdictionSender::process() { // set our packets per second to be the number of nodes setPacketsPerSecond(nodeCount); + } else { +printf("JurisdictionSender::process()... no jurisdiction!!!\n"); } continueProcessing = PacketSender::process(); diff --git a/libraries/voxels/src/VoxelEditPacketSender.cpp b/libraries/voxels/src/VoxelEditPacketSender.cpp index 605fb9e9e9..5853652688 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.cpp +++ b/libraries/voxels/src/VoxelEditPacketSender.cpp @@ -48,6 +48,21 @@ void VoxelEditPacketSender::actuallySendMessage(uint16_t nodeID, unsigned char* } } +void VoxelEditPacketSender::queueVoxelEditMessages(PACKET_TYPE type, int numberOfDetails, VoxelDetail* details) { + if (!_shouldSend) { + return; // bail early + } + + for (int i = 0; i < numberOfDetails; i++) { + static unsigned char bufferOut[MAX_PACKET_SIZE]; + int sizeOut = 0; + + if (encodeVoxelEditMessageDetails(type, 1, &details[i], &bufferOut[0], MAX_PACKET_SIZE, sizeOut)) { + queueVoxelEditMessage(type, bufferOut, sizeOut); + } + } +} + void VoxelEditPacketSender::queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) { if (!_shouldSend) { diff --git a/libraries/voxels/src/VoxelEditPacketSender.h b/libraries/voxels/src/VoxelEditPacketSender.h index 935996bb4b..e07bd11baa 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.h +++ b/libraries/voxels/src/VoxelEditPacketSender.h @@ -37,6 +37,10 @@ public: /// node or nodes the packet should be sent to. void queueVoxelEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length); + /// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines + /// which voxel-server node or nodes the packet should be sent to. + void queueVoxelEditMessages(PACKET_TYPE type, int numberOfDetails, VoxelDetail* details); + /// flushes all queued packets for all nodes void flushQueue(); From f581b58fbcae89c77a7b745fd0addedb5cbbde18 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:11:28 -0700 Subject: [PATCH 11/20] spacing fix --- interface/src/ui/VoxelStatsDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index b6e3b3202a..612d4c6e56 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -30,7 +30,7 @@ VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) : this->QDialog::setLayout(form); // Setup labels - for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; ++i) { + for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; ++i) { VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(i); QLabel* label = _labels[i] = new QLabel(); label->setAlignment(Qt::AlignRight); From 436f70ab5dac6abc6ff6ecc3da14d70f0bdec36d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:12:22 -0700 Subject: [PATCH 12/20] removed dead code --- libraries/shared/src/NodeList.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 7892a4aece..8850d34e87 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -411,7 +411,6 @@ Node* NodeList::addOrUpdateNode(sockaddr* publicSocket, sockaddr* localSocket, c } else { if (node->getType() == NODE_TYPE_AUDIO_MIXER || - //node->getType() == NODE_TYPE_ANIMATION_SERVER || node->getType() == NODE_TYPE_VOXEL_SERVER) { // until the Audio class also uses our nodeList, we need to update // the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously From da6bd2e3b09e37d35534ff8f0fc013deb77bb0bf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:22:51 -0700 Subject: [PATCH 13/20] cleanup, handle no JurisdictionMap case in JurisidictionSender --- libraries/shared/src/PacketSender.cpp | 2 +- .../shared/src/ReceivedPacketProcessor.cpp | 7 +-- libraries/voxels/src/JurisdictionMap.cpp | 14 +++++ libraries/voxels/src/JurisdictionMap.h | 3 ++ libraries/voxels/src/JurisdictionSender.cpp | 51 +++++++++---------- 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index 9397e44be0..511b01541f 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -66,5 +66,5 @@ bool PacketSender::process() { } } - return true; // keep running till they terminate us + return isStillRunning(); // keep running till they terminate us } diff --git a/libraries/shared/src/ReceivedPacketProcessor.cpp b/libraries/shared/src/ReceivedPacketProcessor.cpp index f1c6e4f8df..dce65b586e 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.cpp +++ b/libraries/shared/src/ReceivedPacketProcessor.cpp @@ -13,9 +13,6 @@ #include "SharedUtil.h" void ReceivedPacketProcessor::queueReceivedPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { - //printf("ReceivedPacketProcessor::queueReceivedPacket() packetData=%p, packetLength=%lu\n", packetData, packetLength); - - // Make sure our Node and NodeList knows we've heard from this node. Node* node = NodeList::getInstance()->nodeWithAddress(&address); if (node) { @@ -30,12 +27,10 @@ void ReceivedPacketProcessor::queueReceivedPacket(sockaddr& address, unsigned ch bool ReceivedPacketProcessor::process() { if (_packets.size() == 0) { - //printf("ReceivedPacketProcessor::process() no packets... sleeping... \n"); const uint64_t RECEIVED_THREAD_SLEEP_INTERVAL = (1000 * 1000)/60; // check at 60fps usleep(RECEIVED_THREAD_SLEEP_INTERVAL); } while (_packets.size() > 0) { - //printf("ReceivedPacketProcessor::process() we got packets!! call processPacket() \n"); NetworkPacket& packet = _packets.front(); processPacket(packet.getAddress(), packet.getData(), packet.getLength()); @@ -43,5 +38,5 @@ bool ReceivedPacketProcessor::process() { _packets.erase(_packets.begin()); unlock(); } - return true; // keep running till they terminate us + return isStillRunning(); // keep running till they terminate us } diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index 9a14bc31e6..3b05e2980a 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -213,6 +213,20 @@ bool JurisdictionMap::writeToFile(const char* filename) { return true; } +int JurisdictionMap::packEmptyJurisdictionIntoMessage(unsigned char* destinationBuffer, int availableBytes) { + unsigned char* bufferStart = destinationBuffer; + + int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_VOXEL_JURISDICTION); + destinationBuffer += headerLength; + + // No root or end node details to pack! + int bytes = 0; + memcpy(destinationBuffer, &bytes, sizeof(bytes)); + destinationBuffer += sizeof(bytes); + + return destinationBuffer - bufferStart; // includes header! +} + int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) { unsigned char* bufferStart = destinationBuffer; diff --git a/libraries/voxels/src/JurisdictionMap.h b/libraries/voxels/src/JurisdictionMap.h index 67adbf79a9..79484d6ec4 100644 --- a/libraries/voxels/src/JurisdictionMap.h +++ b/libraries/voxels/src/JurisdictionMap.h @@ -53,6 +53,9 @@ public: int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes); int packIntoMessage(unsigned char* destinationBuffer, int availableBytes); + + /// Available to pack an empty or unknown jurisdiction into a network packet, used when no JurisdictionMap is available + static int packEmptyJurisdictionIntoMessage(unsigned char* destinationBuffer, int availableBytes); void displayDebugDetails(); diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index 2ff76656a9..e5f1f1c747 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -46,35 +46,34 @@ bool JurisdictionSender::process() { if (continueProcessing) { // add our packet to our own queue, then let the PacketSender class do the rest of the work. + static unsigned char buffer[MAX_PACKET_SIZE]; + unsigned char* bufferOut = &buffer[0]; + ssize_t sizeOut = 0; + if (_jurisdictionMap) { - unsigned char buffer[MAX_PACKET_SIZE]; - unsigned char* bufferOut = &buffer[0]; - ssize_t sizeOut = _jurisdictionMap->packIntoMessage(bufferOut, MAX_PACKET_SIZE); - int nodeCount = 0; - - for (std::set::iterator nodeIterator = _nodesRequestingJurisdictions.begin(); - nodeIterator != _nodesRequestingJurisdictions.end(); nodeIterator++) { - - uint16_t nodeID = *nodeIterator; - Node* node = NodeList::getInstance()->nodeWithID(nodeID); - - if (node->getActiveSocket() != NULL) { - sockaddr* nodeAddress = node->getActiveSocket(); - -printf("JurisdictionSender::process()... queuePacketForSending(PACKET_TYPE_VOXEL_JURISDICTION)\n"); - - queuePacketForSending(*nodeAddress, bufferOut, sizeOut); - nodeCount++; - // remove it from the set - _nodesRequestingJurisdictions.erase(nodeIterator); - } - } - - // set our packets per second to be the number of nodes - setPacketsPerSecond(nodeCount); + sizeOut = _jurisdictionMap->packIntoMessage(bufferOut, MAX_PACKET_SIZE); } else { -printf("JurisdictionSender::process()... no jurisdiction!!!\n"); + sizeOut = JurisdictionMap::packEmptyJurisdictionIntoMessage(bufferOut, MAX_PACKET_SIZE); } + int nodeCount = 0; + + for (std::set::iterator nodeIterator = _nodesRequestingJurisdictions.begin(); + nodeIterator != _nodesRequestingJurisdictions.end(); nodeIterator++) { + + uint16_t nodeID = *nodeIterator; + Node* node = NodeList::getInstance()->nodeWithID(nodeID); + + if (node->getActiveSocket() != NULL) { + sockaddr* nodeAddress = node->getActiveSocket(); + queuePacketForSending(*nodeAddress, bufferOut, sizeOut); + nodeCount++; + // remove it from the set + _nodesRequestingJurisdictions.erase(nodeIterator); + } + } + + // set our packets per second to be the number of nodes + setPacketsPerSecond(nodeCount); continueProcessing = PacketSender::process(); } From b0664163a75b6be0ce35bf72fb202183e9acbf4c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:27:31 -0700 Subject: [PATCH 14/20] removed debug --- libraries/voxels/src/JurisdictionListener.cpp | 6 ------ libraries/voxels/src/JurisdictionSender.cpp | 1 - 2 files changed, 7 deletions(-) diff --git a/libraries/voxels/src/JurisdictionListener.cpp b/libraries/voxels/src/JurisdictionListener.cpp index a084dab114..ceb2fbcf0c 100644 --- a/libraries/voxels/src/JurisdictionListener.cpp +++ b/libraries/voxels/src/JurisdictionListener.cpp @@ -48,19 +48,13 @@ bool JurisdictionListener::queueJurisdictionRequest() { } void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { -printf("processPacket()\n"); if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { -printf("processPacket()... PACKET_TYPE_VOXEL_JURISDICTION\n"); - Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (node) { uint16_t nodeID = node->getNodeID(); JurisdictionMap map; map.unpackFromMessage(packetData, packetLength); _jurisdictions[nodeID] = map; - - qDebug() << "Got a new map...\n"; - map.displayDebugDetails(); } } } diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index e5f1f1c747..e699951527 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -25,7 +25,6 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { -printf("processPacket()... PACKET_TYPE_VOXEL_JURISDICTION_REQUEST\n"); Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (node) { uint16_t nodeID = node->getNodeID(); From 526270e408d7380cbf1edb359f81783883118dbc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:30:05 -0700 Subject: [PATCH 15/20] removed debug --- voxel-server/src/main.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 1f1e05cc0c..2579c54751 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -746,12 +746,9 @@ int main(int argc, const char * argv[]) { atByte += voxelDataSize; } - //printf("PACKET_TYPE_SET_VOXEL ...\n"); - // Make sure our Node and NodeList knows we've heard from this node. Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); if (node) { - //printf("PACKET_TYPE_SET_VOXEL node->setLastHeardMicrostamp(usecTimestampNow());\n"); node->setLastHeardMicrostamp(usecTimestampNow()); } @@ -765,10 +762,8 @@ int main(int argc, const char * argv[]) { // Make sure our Node and NodeList knows we've heard from this node. Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); if (node) { - //printf("PACKET_TYPE_ERASE_VOXEL node->setLastHeardMicrostamp(usecTimestampNow());\n"); node->setLastHeardMicrostamp(usecTimestampNow()); } - } else if (packetData[0] == PACKET_TYPE_Z_COMMAND) { // the Z command is a special command that allows the sender to send the voxel server high level semantic @@ -806,10 +801,8 @@ int main(int argc, const char * argv[]) { // Make sure our Node and NodeList knows we've heard from this node. Node* node = NodeList::getInstance()->nodeWithAddress(&nodePublicAddress); if (node) { - printf("PACKET_TYPE_Z_COMMAND node->setLastHeardMicrostamp(usecTimestampNow());\n"); node->setLastHeardMicrostamp(usecTimestampNow()); } - } else if (packetData[0] == PACKET_TYPE_HEAD_DATA) { // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we // need to make sure we have it in our nodeList. @@ -826,7 +819,6 @@ int main(int argc, const char * argv[]) { // If the packet is a ping, let processNodeData handle it. nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); } else if (packetData[0] == PACKET_TYPE_DOMAIN) { - //printf("PACKET_TYPE_DOMAIN packet\n"); nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes); } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { if (::jurisdictionSender) { From 50532bc67d07076aa3039ecd63435ab15ac23841 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 11:42:30 -0700 Subject: [PATCH 16/20] added NodeListHook to JurisdictionListener to properly remove nodes that are killed --- libraries/voxels/src/JurisdictionListener.cpp | 15 +++++++++++++++ libraries/voxels/src/JurisdictionListener.h | 10 +++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/src/JurisdictionListener.cpp b/libraries/voxels/src/JurisdictionListener.cpp index ceb2fbcf0c..ea8bea3a2d 100644 --- a/libraries/voxels/src/JurisdictionListener.cpp +++ b/libraries/voxels/src/JurisdictionListener.cpp @@ -19,6 +19,21 @@ JurisdictionListener::JurisdictionListener(PacketSenderNotify* notify) : PacketSender(notify, JurisdictionListener::DEFAULT_PACKETS_PER_SECOND) { + NodeList* nodeList = NodeList::getInstance(); + nodeList->addHook(this); +} + +JurisdictionListener::~JurisdictionListener() { + NodeList* nodeList = NodeList::getInstance(); + nodeList->removeHook(this); +} + +void JurisdictionListener::nodeAdded(Node* node) { + // nothing to do. But need to implement it. +} + +void JurisdictionListener::nodeKilled(Node* node) { + _jurisdictions.erase(_jurisdictions.find(node->getNodeID())); } bool JurisdictionListener::queueJurisdictionRequest() { diff --git a/libraries/voxels/src/JurisdictionListener.h b/libraries/voxels/src/JurisdictionListener.h index 4b5d2d1fa4..0a614446ed 100644 --- a/libraries/voxels/src/JurisdictionListener.h +++ b/libraries/voxels/src/JurisdictionListener.h @@ -11,6 +11,7 @@ #ifndef __shared__JurisdictionListener__ #define __shared__JurisdictionListener__ +#include #include #include @@ -20,15 +21,22 @@ /// the PACKET_TYPE_VOXEL_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions /// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets /// and adding them to the processing queue by calling queueReceivedPacket() -class JurisdictionListener : public PacketSender, public ReceivedPacketProcessor { +class JurisdictionListener : public NodeListHook, public PacketSender, public ReceivedPacketProcessor { public: static const int DEFAULT_PACKETS_PER_SECOND = 1; JurisdictionListener(PacketSenderNotify* notify = NULL); + ~JurisdictionListener(); + virtual bool process(); NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; }; + /// Called by NodeList to inform us that a node has been added. + void nodeAdded(Node* node); + /// Called by NodeList to inform us that a node has been killed. + void nodeKilled(Node* node); + protected: /// Callback for processing of received packets. Will process any queued PACKET_TYPE_VOXEL_JURISDICTION and update the /// jurisdiction map member variable From db6e327741ae098b26901955c60a59b60f536604 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 12:00:07 -0700 Subject: [PATCH 17/20] fixed build buster --- libraries/voxels/src/JurisdictionMap.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/src/JurisdictionMap.h b/libraries/voxels/src/JurisdictionMap.h index 79484d6ec4..a3e96933a9 100644 --- a/libraries/voxels/src/JurisdictionMap.h +++ b/libraries/voxels/src/JurisdictionMap.h @@ -9,8 +9,9 @@ #ifndef __hifi__JurisdictionMap__ #define __hifi__JurisdictionMap__ -#include #include +#include +#include #include class JurisdictionMap { From 96bdcd6a4a0c1587fd54fabc1252b273346076b1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 12:10:34 -0700 Subject: [PATCH 18/20] attempt to fix build buster --- interface/src/ui/VoxelStatsDialog.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index 612d4c6e56..e0b3d1aea2 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -30,7 +30,7 @@ VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) : this->QDialog::setLayout(form); // Setup labels - for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; ++i) { + for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; i++) { VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(i); QLabel* label = _labels[i] = new QLabel(); label->setAlignment(Qt::AlignRight); @@ -56,9 +56,9 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { // Update labels char strBuf[256]; - for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; ++i) { - QLabel* label = _labels[i]; - snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue(i)); + for (int i = 0; i < (int)VoxelSceneStats::ITEM_COUNT; i++) { + QLabel* label = _labels[(VoxelSceneStats::Item)i]; + snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue((VoxelSceneStats::Item)i)); label->setText(strBuf); } From af140bbeb2a50643df127f5dd4e3e9899fd6f751 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 20 Aug 2013 12:16:25 -0700 Subject: [PATCH 19/20] fixed build buster --- interface/src/ui/VoxelStatsDialog.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index e0b3d1aea2..52b32ef7a5 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -30,9 +30,10 @@ VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) : this->QDialog::setLayout(form); // Setup labels - for (VoxelSceneStats::Item i = VoxelSceneStats::ITEM_ELAPSED; i < VoxelSceneStats::ITEM_COUNT; i++) { - VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(i); - QLabel* label = _labels[i] = new QLabel(); + for (int i = 0; i < (int)VoxelSceneStats::ITEM_COUNT; i++) { + VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i); + VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(item); + QLabel* label = _labels[item] = new QLabel(); label->setAlignment(Qt::AlignRight); // Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background) @@ -57,8 +58,9 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { // Update labels char strBuf[256]; for (int i = 0; i < (int)VoxelSceneStats::ITEM_COUNT; i++) { - QLabel* label = _labels[(VoxelSceneStats::Item)i]; - snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue((VoxelSceneStats::Item)i)); + VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i); + QLabel* label = _labels[item]; + snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue(item)); label->setText(strBuf); } From 4fd23a0cd91af19ed3c1731255f3034b07c2e0f8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 13:09:51 -0700 Subject: [PATCH 20/20] CR feedback --- animation-server/src/main.cpp | 12 ++++++------ libraries/voxels/src/JurisdictionMap.cpp | 1 - libraries/voxels/src/JurisdictionSender.cpp | 6 +----- libraries/voxels/src/VoxelSceneStats.h | 3 ++- voxel-server/src/main.cpp | 5 ++--- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 9b43378eb2..eb1e3546dd 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -651,27 +651,27 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* NO_BILLBOARD = "--NoBillboard"; ::includeBillboard = !cmdOptionExists(argc, argv, NO_BILLBOARD); - printf("includeBillboard=%s\n",debug::valueOf(::includeBillboard)); + printf("includeBillboard=%s\n", debug::valueOf(::includeBillboard)); const char* NO_BORDER_TRACER = "--NoBorderTracer"; ::includeBorderTracer = !cmdOptionExists(argc, argv, NO_BORDER_TRACER); - printf("includeBorderTracer=%s\n",debug::valueOf(::includeBorderTracer)); + printf("includeBorderTracer=%s\n", debug::valueOf(::includeBorderTracer)); const char* NO_MOVING_BUG = "--NoMovingBug"; ::includeMovingBug = !cmdOptionExists(argc, argv, NO_MOVING_BUG); - printf("includeMovingBug=%s\n",debug::valueOf(::includeMovingBug)); + printf("includeMovingBug=%s\n", debug::valueOf(::includeMovingBug)); const char* INCLUDE_BLINKING_VOXEL = "--includeBlinkingVoxel"; ::includeBlinkingVoxel = cmdOptionExists(argc, argv, INCLUDE_BLINKING_VOXEL); - printf("includeBlinkingVoxel=%s\n",debug::valueOf(::includeBlinkingVoxel)); + printf("includeBlinkingVoxel=%s\n", debug::valueOf(::includeBlinkingVoxel)); const char* NO_DANCE_FLOOR = "--NoDanceFloor"; ::includeDanceFloor = !cmdOptionExists(argc, argv, NO_DANCE_FLOOR); - printf("includeDanceFloor=%s\n",debug::valueOf(::includeDanceFloor)); + printf("includeDanceFloor=%s\n", debug::valueOf(::includeDanceFloor)); const char* BUILD_STREET = "--BuildStreet"; ::buildStreet = cmdOptionExists(argc, argv, BUILD_STREET); - printf("buildStreet=%s\n",debug::valueOf(::buildStreet)); + printf("buildStreet=%s\n", debug::valueOf(::buildStreet)); // Handle Local Domain testing with the --local command line const char* showPPS = "--showPPS"; diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index 3b05e2980a..94e589c801 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -235,7 +235,6 @@ int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int avail // add the root jurisdiction if (_rootOctalCode) { - // copy the int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_rootOctalCode)); memcpy(destinationBuffer, &bytes, sizeof(bytes)); destinationBuffer += sizeof(bytes); diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index e699951527..df48c27c47 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -39,11 +39,7 @@ bool JurisdictionSender::process() { bool continueProcessing = isStillRunning(); // call our ReceivedPacketProcessor base class process so we'll get any pending packets - if (continueProcessing) { - continueProcessing = ReceivedPacketProcessor::process(); - } - - if (continueProcessing) { + if (continueProcessing && (continueProcessing = ReceivedPacketProcessor::process())) { // add our packet to our own queue, then let the PacketSender class do the rest of the work. static unsigned char buffer[MAX_PACKET_SIZE]; unsigned char* bufferOut = &buffer[0]; diff --git a/libraries/voxels/src/VoxelSceneStats.h b/libraries/voxels/src/VoxelSceneStats.h index 2d7f7cd068..0883de45e1 100644 --- a/libraries/voxels/src/VoxelSceneStats.h +++ b/libraries/voxels/src/VoxelSceneStats.h @@ -119,10 +119,11 @@ public: }; /// Returns details about items tracked by VoxelSceneStats - /// \param + /// \param Item item The item from the stats you're interested in. ItemInfo& getItemInfo(Item item) { return _ITEMS[item]; }; /// Returns a UI formatted value of an item tracked by VoxelSceneStats + /// \param Item item The item from the stats you're interested in. char* getItemValue(Item item); /// Returns OctCode for root node of the jurisdiction of this particular voxel server diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 2579c54751..3446ebe9c1 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -510,9 +510,8 @@ int main(int argc, const char * argv[]) { NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort); setvbuf(stdout, NULL, _IOLBF, 0); - const int numNodeTypes = 2; - const NODE_TYPE nodeTypes[numNodeTypes] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER }; - NodeList::getInstance()->setNodeTypesOfInterest(&nodeTypes[0], numNodeTypes); + const NODE_TYPE nodeTypes[] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER }; + NodeList::getInstance()->setNodeTypesOfInterest(&nodeTypes[0], sizeof(nodeTypes)); // Handle Local Domain testing with the --local command line const char* local = "--local";