From d4ec337cae00a44718fc0d80d0c5650a583f0c52 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 23 Oct 2014 13:39:56 -0700 Subject: [PATCH 01/21] Don't send reverb data as often --- assignment-client/src/audio/AudioMixer.cpp | 58 ++++++++++++++++------ libraries/audio/src/InboundAudioStream.cpp | 28 ++++++++--- libraries/audio/src/InboundAudioStream.h | 6 +++ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 8d87638434..faaebb1102 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -731,30 +731,56 @@ void AudioMixer::run() { dataAt += sizeof(quint16); // Pack stream properties - bool inAZone = false; + bool hasReverb = false; + float reverbTime; + float wetLevel; + + // find reverb properties for (int i = 0; i < _zoneReverbSettings.size(); ++i) { AudioMixerClientData* data = static_cast(node->getLinkedData()); - glm::vec3 streamPosition = data->getAvatarAudioStream()->getPosition(); + AvatarAudioStream* stream = data->getAvatarAudioStream(); + glm::vec3 streamPosition = stream->getPosition(); if (_audioZones[_zoneReverbSettings[i].zone].contains(streamPosition)) { - bool hasReverb = true; - float reverbTime = _zoneReverbSettings[i].reverbTime; - float wetLevel = _zoneReverbSettings[i].wetLevel; - - memcpy(dataAt, &hasReverb, sizeof(bool)); - dataAt += sizeof(bool); + hasReverb = true; + reverbTime = _zoneReverbSettings[i].reverbTime; + wetLevel = _zoneReverbSettings[i].wetLevel; + break; + } + } + AvatarAudioStream* stream = nodeData->getAvatarAudioStream(); + bool dataChanged = (stream->hasReverb() != hasReverb) || + (stream->hasReverb() && (stream->getRevebTime() != reverbTime || + stream->getWetLevel() != wetLevel)); + // Update stream + if (hasReverb) { + stream->setReverb(reverbTime, wetLevel); + } else { + stream->clearReverb(); + } + + // Send at change or every so often + float CHANCE_OF_SEND = 0.01; + bool sendData = dataChanged || (randFloat() < CHANCE_OF_SEND); + + unsigned char bitset = 0; + if (sendData) { + setAtBit(bitset, HAS_DATA_BIT); + if (hasReverb) { + setAtBit(bitset, HAS_REVERB_BIT); + } + + memcpy(dataAt, &bitset, sizeof(unsigned char)); + dataAt += sizeof(unsigned char); + + if (hasReverb) { memcpy(dataAt, &reverbTime, sizeof(float)); dataAt += sizeof(float); memcpy(dataAt, &wetLevel, sizeof(float)); dataAt += sizeof(float); - - inAZone = true; - break; } - } - if (!inAZone) { - bool hasReverb = false; - memcpy(dataAt, &hasReverb, sizeof(bool)); - dataAt += sizeof(bool); + } else { + memcpy(dataAt, &bitset, sizeof(unsigned char)); + dataAt += sizeof(unsigned char); } // pack mixed audio samples diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 59578951f8..3e4a8639c6 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -13,6 +13,7 @@ #include "InboundAudioStream.h" #include "PacketHeaders.h" +#include const int STARVE_HISTORY_CAPACITY = 50; @@ -83,6 +84,12 @@ void InboundAudioStream::clearBuffer() { _currentJitterBufferFrames = 0; } +void InboundAudioStream::setReverb(float reverbTime, float wetLevel) { + _hasReverb = true; + _reverbTime = reverbTime; + _wetLevel = wetLevel; +} + void InboundAudioStream::perSecondCallbackForUpdatingStats() { _incomingSequenceNumberStats.pushStatsToHistory(); _timeGapStatsForDesiredCalcOnTooManyStarves.currentIntervalComplete(); @@ -165,14 +172,19 @@ int InboundAudioStream::parseData(const QByteArray& packet) { int InboundAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { int read = 0; if (type == PacketTypeMixedAudio) { - memcpy(&_hasReverb, packetAfterSeqNum.data() + read, sizeof(bool)); - read += sizeof(bool); + char bitset; + memcpy(&bitset, packetAfterSeqNum.data() + read, sizeof(char)); + read += sizeof(char); - if (_hasReverb) { - memcpy(&_reverbTime, packetAfterSeqNum.data() + read, sizeof(float)); - read += sizeof(float); - memcpy(&_wetLevel, packetAfterSeqNum.data() + read, sizeof(float)); - read += sizeof(float); + bool hasData = oneAtBit(bitset, HAS_DATA_BIT); + if (hasData) { + _hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); + if (_hasReverb) { + memcpy(&_reverbTime, packetAfterSeqNum.data() + read, sizeof(float)); + read += sizeof(float); + memcpy(&_wetLevel, packetAfterSeqNum.data() + read, sizeof(float)); + read += sizeof(float); + } } } @@ -206,7 +218,7 @@ int InboundAudioStream::writeDroppableSilentSamples(int silentSamples) { _framesAvailableStat.reset(); } - + int ret = _ringBuffer.addSilentSamples(silentSamples - numSilentFramesToDrop * samplesPerFrame); return ret; diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index 3e69db0afb..737147e2ba 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -45,6 +45,10 @@ const int DEFAULT_WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES = 50; const int DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION = 10; const bool DEFAULT_REPETITION_WITH_FADE = true; +// Mixed Audio bitset +const int HAS_DATA_BIT = 0; // 1st bit +const int HAS_REVERB_BIT = 1; // 2nd bit + class InboundAudioStream : public NodeData { Q_OBJECT public: @@ -158,6 +162,8 @@ public: bool hasReverb() const { return _hasReverb; } float getRevebTime() const { return _reverbTime; } float getWetLevel() const { return _wetLevel; } + void setReverb(float reverbTime, float wetLevel); + void clearReverb() { _hasReverb = false; } public slots: /// This function should be called every second for all the stats to function properly. If dynamic jitter buffers From d528c47a83bacd44fc88b6a53d7d5a7e22a43d66 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 23 Oct 2014 13:42:17 -0700 Subject: [PATCH 02/21] Bump audio packet version --- libraries/networking/src/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index 8ce379b203..b96d88430a 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -53,7 +53,7 @@ PacketVersion versionForPacketType(PacketType type) { case PacketTypeSilentAudioFrame: return 4; case PacketTypeMixedAudio: - return 2; + return 3; case PacketTypeAvatarData: return 3; case PacketTypeAvatarIdentity: From 1ae1d28e7b3259fc42647453ef59c079608549b7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 23 Oct 2014 14:07:42 -0700 Subject: [PATCH 03/21] typo --- interface/external/gverb/readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/external/gverb/readme.txt b/interface/external/gverb/readme.txt index aa2fe8a602..1a85659b91 100644 --- a/interface/external/gverb/readme.txt +++ b/interface/external/gverb/readme.txt @@ -1,7 +1,7 @@ Instructions for adding the Gverb library to Interface (This is a required library) -Clément Brisset, Octobre 22nd, 2014 +Clément Brisset, October 22nd, 2014 1. Go to https://github.com/highfidelity/gverb Or download the sources directly via this link: From 5e49c08e273b253081650864071bc460d857b250 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 23 Oct 2014 14:08:36 -0700 Subject: [PATCH 04/21] extra space --- libraries/audio/src/InboundAudioStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 3e4a8639c6..a830d7c9db 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -218,7 +218,7 @@ int InboundAudioStream::writeDroppableSilentSamples(int silentSamples) { _framesAvailableStat.reset(); } - + int ret = _ringBuffer.addSilentSamples(silentSamples - numSilentFramesToDrop * samplesPerFrame); return ret; From 529a7e0369108305ef96d105d327b1f981f115be Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 23 Oct 2014 22:55:40 -0700 Subject: [PATCH 05/21] CR --- assignment-client/src/audio/AudioMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index faaebb1102..31f50251b9 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -759,7 +759,7 @@ void AudioMixer::run() { } // Send at change or every so often - float CHANCE_OF_SEND = 0.01; + float CHANCE_OF_SEND = 0.01f; bool sendData = dataChanged || (randFloat() < CHANCE_OF_SEND); unsigned char bitset = 0; From 6072fd4066d02098eee08f08d29674a27202c251 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 24 Oct 2014 10:41:54 -0700 Subject: [PATCH 06/21] Added audio env packet type --- libraries/networking/src/PacketHeaders.cpp | 5 +++++ libraries/networking/src/PacketHeaders.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index b96d88430a..0b6a3bc1f0 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -135,8 +135,13 @@ QString nameForPacketType(PacketType type) { PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityAddResponse); PACKET_TYPE_NAME_LOOKUP(PacketTypeOctreeDataNack); PACKET_TYPE_NAME_LOOKUP(PacketTypeVoxelEditNack); + PACKET_TYPE_NAME_LOOKUP(PacketTypeAudioEnvironment); PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityEditNack); PACKET_TYPE_NAME_LOOKUP(PacketTypeSignedTransactionPayment); + PACKET_TYPE_NAME_LOOKUP(PacketTypeIceServerHeartbeat); + PACKET_TYPE_NAME_LOOKUP(PacketTypeIceServerHeartbeatResponse); + PACKET_TYPE_NAME_LOOKUP(PacketTypeUnverifiedPing); + PACKET_TYPE_NAME_LOOKUP(PacketTypeUnverifiedPingReply); default: return QString("Type: ") + QString::number((int)type); } diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 7632f47686..2e9ce697f0 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -68,7 +68,7 @@ enum PacketType { PacketTypeEntityAddResponse, PacketTypeOctreeDataNack, // 45 PacketTypeVoxelEditNack, - UNUSED_6, + PacketTypeAudioEnvironment, PacketTypeEntityEditNack, // 48 PacketTypeSignedTransactionPayment, PacketTypeIceServerHeartbeat, From 847ef64b667f266aaceebcec5a4002f48f23fc80 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 24 Oct 2014 14:27:55 -0700 Subject: [PATCH 07/21] move audio env data over to new packet --- assignment-client/src/audio/AudioMixer.cpp | 68 +++++++++++----------- interface/src/Audio.cpp | 21 +++++++ interface/src/Audio.h | 1 + interface/src/DatagramProcessor.cpp | 14 +++-- libraries/audio/src/InboundAudioStream.cpp | 22 +------ libraries/networking/src/PacketHeaders.cpp | 4 +- 6 files changed, 68 insertions(+), 62 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 31f50251b9..afde574ae2 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -638,8 +638,9 @@ void AudioMixer::run() { int nextFrame = 0; QElapsedTimer timer; timer.start(); - + char clientMixBuffer[MAX_PACKET_SIZE]; + char clientEnvBuffer[MAX_PACKET_SIZE]; int usecToSleep = BUFFER_SEND_INTERVAL_USECS; @@ -718,23 +719,25 @@ void AudioMixer::run() { && nodeData->getAvatarAudioStream()) { int streamsMixed = prepareMixForListeningNode(node.data()); - - char* dataAt; + + char* mixDataAt; if (streamsMixed > 0) { - // pack header - int numBytesPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio); - dataAt = clientMixBuffer + numBytesPacketHeader; - + // pack headers + int numBytesMixPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio); + mixDataAt = clientMixBuffer + numBytesMixPacketHeader; + // pack sequence number quint16 sequence = nodeData->getOutgoingSequenceNumber(); - memcpy(dataAt, &sequence, sizeof(quint16)); - dataAt += sizeof(quint16); - - // Pack stream properties - bool hasReverb = false; - float reverbTime; - float wetLevel; + memcpy(mixDataAt, &sequence, sizeof(quint16)); + mixDataAt += sizeof(quint16); + // pack mixed audio samples + memcpy(mixDataAt, _mixSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); + mixDataAt += NETWORK_BUFFER_LENGTH_BYTES_STEREO; + + // Send stream properties + bool hasReverb = false; + float reverbTime, wetLevel; // find reverb properties for (int i = 0; i < _zoneReverbSettings.size(); ++i) { AudioMixerClientData* data = static_cast(node->getLinkedData()); @@ -762,48 +765,45 @@ void AudioMixer::run() { float CHANCE_OF_SEND = 0.01f; bool sendData = dataChanged || (randFloat() < CHANCE_OF_SEND); - unsigned char bitset = 0; if (sendData) { + int numBytesEnvPacketHeader = populatePacketHeader(clientEnvBuffer, PacketTypeAudioEnvironment); + char* envDataAt = clientEnvBuffer + numBytesEnvPacketHeader; + + unsigned char bitset = 0; setAtBit(bitset, HAS_DATA_BIT); if (hasReverb) { setAtBit(bitset, HAS_REVERB_BIT); } - memcpy(dataAt, &bitset, sizeof(unsigned char)); - dataAt += sizeof(unsigned char); + memcpy(envDataAt, &bitset, sizeof(unsigned char)); + envDataAt += sizeof(unsigned char); if (hasReverb) { - memcpy(dataAt, &reverbTime, sizeof(float)); - dataAt += sizeof(float); - memcpy(dataAt, &wetLevel, sizeof(float)); - dataAt += sizeof(float); + memcpy(envDataAt, &reverbTime, sizeof(float)); + envDataAt += sizeof(float); + memcpy(envDataAt, &wetLevel, sizeof(float)); + envDataAt += sizeof(float); } - } else { - memcpy(dataAt, &bitset, sizeof(unsigned char)); - dataAt += sizeof(unsigned char); + nodeList->writeDatagram(clientEnvBuffer, envDataAt - clientEnvBuffer, node); } - - // pack mixed audio samples - memcpy(dataAt, _mixSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); - dataAt += NETWORK_BUFFER_LENGTH_BYTES_STEREO; } else { // pack header int numBytesPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeSilentAudioFrame); - dataAt = clientMixBuffer + numBytesPacketHeader; + mixDataAt = clientMixBuffer + numBytesPacketHeader; // pack sequence number quint16 sequence = nodeData->getOutgoingSequenceNumber(); - memcpy(dataAt, &sequence, sizeof(quint16)); - dataAt += sizeof(quint16); + memcpy(mixDataAt, &sequence, sizeof(quint16)); + mixDataAt += sizeof(quint16); // pack number of silent audio samples quint16 numSilentSamples = NETWORK_BUFFER_LENGTH_SAMPLES_STEREO; - memcpy(dataAt, &numSilentSamples, sizeof(quint16)); - dataAt += sizeof(quint16); + memcpy(mixDataAt, &numSilentSamples, sizeof(quint16)); + mixDataAt += sizeof(quint16); } // send mixed audio packet - nodeList->writeDatagram(clientMixBuffer, dataAt - clientMixBuffer, node); + nodeList->writeDatagram(clientMixBuffer, mixDataAt - clientMixBuffer, node); nodeData->incrementOutgoingMixedAudioSequenceNumber(); // send an audio stream stats packet if it's time diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index dd84eb3211..7d039387bb 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -1018,6 +1018,27 @@ void Audio::parseAudioStreamStatsPacket(const QByteArray& packet) { } } +void Audio::parseAudioEnvironmentData(const QByteArray &packet) { + int numBytesPacketHeader = numBytesForPacketHeader(packet); + const char* dataAt = packet.constData() + numBytesPacketHeader; + + char bitset; + memcpy(&bitset, dataAt, sizeof(char)); + dataAt += sizeof(char); + + bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT);; + if (hasReverb) { + float reverbTime, wetLevel; + memcpy(&reverbTime, dataAt, sizeof(float)); + dataAt += sizeof(float); + memcpy(&wetLevel, dataAt, sizeof(float)); + dataAt += sizeof(float); + _receivedAudioStream.setReverb(reverbTime, wetLevel); + } else { + _receivedAudioStream.clearReverb(); + } +} + void Audio::sendDownstreamAudioStatsPacket() { // since this function is called every second, we'll sample for some of our stats here diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 900b6ce0d6..fcbfb12761 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -125,6 +125,7 @@ public slots: void stop(); void addReceivedAudioToStream(const QByteArray& audioByteArray); void parseAudioStreamStatsPacket(const QByteArray& packet); + void parseAudioEnvironmentData(const QByteArray& packet); void addSpatialAudioToBuffer(unsigned int sampleTime, const QByteArray& spatialAudio, unsigned int numSamples); void handleAudioInput(); void reset(); diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 868654b9da..6f9f4cae68 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -49,14 +49,18 @@ void DatagramProcessor::processDatagrams() { PacketType incomingType = packetTypeForPacket(incomingPacket); // only process this packet if we have a match on the packet version switch (incomingType) { + case PacketTypeAudioEnvironment: + case PacketTypeAudioStreamStats: case PacketTypeMixedAudio: - case PacketTypeSilentAudioFrame: - case PacketTypeAudioStreamStats: { - if (incomingType != PacketTypeAudioStreamStats) { - QMetaObject::invokeMethod(&application->_audio, "addReceivedAudioToStream", Qt::QueuedConnection, + case PacketTypeSilentAudioFrame: { + if (incomingType == PacketTypeAudioStreamStats) { + QMetaObject::invokeMethod(&application->_audio, "parseAudioStreamStatsPacket", Qt::QueuedConnection, + Q_ARG(QByteArray, incomingPacket)); + } else if (incomingType == PacketTypeAudioEnvironment) { + QMetaObject::invokeMethod(&application->_audio, "parseAudioEnvironmentData", Qt::QueuedConnection, Q_ARG(QByteArray, incomingPacket)); } else { - QMetaObject::invokeMethod(&application->_audio, "parseAudioStreamStatsPacket", Qt::QueuedConnection, + QMetaObject::invokeMethod(&application->_audio, "addReceivedAudioToStream", Qt::QueuedConnection, Q_ARG(QByteArray, incomingPacket)); } diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index a830d7c9db..12449a9879 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -170,27 +170,9 @@ int InboundAudioStream::parseData(const QByteArray& packet) { } int InboundAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { - int read = 0; - if (type == PacketTypeMixedAudio) { - char bitset; - memcpy(&bitset, packetAfterSeqNum.data() + read, sizeof(char)); - read += sizeof(char); - - bool hasData = oneAtBit(bitset, HAS_DATA_BIT); - if (hasData) { - _hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); - if (_hasReverb) { - memcpy(&_reverbTime, packetAfterSeqNum.data() + read, sizeof(float)); - read += sizeof(float); - memcpy(&_wetLevel, packetAfterSeqNum.data() + read, sizeof(float)); - read += sizeof(float); - } - } - } - // mixed audio packets do not have any info between the seq num and the audio data. - numAudioSamples = (packetAfterSeqNum.size() - read) / sizeof(int16_t); - return read; + numAudioSamples = packetAfterSeqNum.size() / sizeof(int16_t); + return 0; } int InboundAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int numAudioSamples) { diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index 0b6a3bc1f0..73671295df 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -53,7 +53,7 @@ PacketVersion versionForPacketType(PacketType type) { case PacketTypeSilentAudioFrame: return 4; case PacketTypeMixedAudio: - return 3; + return 1; case PacketTypeAvatarData: return 3; case PacketTypeAvatarIdentity: @@ -71,11 +71,9 @@ PacketVersion versionForPacketType(PacketType type) { return 1; case PacketTypeOctreeStats: return 1; - case PacketTypeEntityAddOrEdit: case PacketTypeEntityData: return VERSION_ENTITIES_SUPPORT_DIMENSIONS; - case PacketTypeEntityErase: return 2; case PacketTypeAudioStreamStats: From 12f0237dc7df928dd87dcbb628034056070c4e6d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 24 Oct 2014 14:56:56 -0700 Subject: [PATCH 08/21] Cleanup --- assignment-client/src/audio/AudioMixer.cpp | 24 +++++++++++----------- libraries/audio/src/InboundAudioStream.cpp | 1 - libraries/audio/src/InboundAudioStream.h | 5 ++--- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index afde574ae2..bd3e37c0ae 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -638,7 +638,7 @@ void AudioMixer::run() { int nextFrame = 0; QElapsedTimer timer; timer.start(); - + char clientMixBuffer[MAX_PACKET_SIZE]; char clientEnvBuffer[MAX_PACKET_SIZE]; @@ -719,13 +719,13 @@ void AudioMixer::run() { && nodeData->getAvatarAudioStream()) { int streamsMixed = prepareMixForListeningNode(node.data()); - + char* mixDataAt; if (streamsMixed > 0) { - // pack headers + // pack header int numBytesMixPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio); mixDataAt = clientMixBuffer + numBytesMixPacketHeader; - + // pack sequence number quint16 sequence = nodeData->getOutgoingSequenceNumber(); memcpy(mixDataAt, &sequence, sizeof(quint16)); @@ -741,8 +741,7 @@ void AudioMixer::run() { // find reverb properties for (int i = 0; i < _zoneReverbSettings.size(); ++i) { AudioMixerClientData* data = static_cast(node->getLinkedData()); - AvatarAudioStream* stream = data->getAvatarAudioStream(); - glm::vec3 streamPosition = stream->getPosition(); + glm::vec3 streamPosition = data->getAvatarAudioStream()->getPosition(); if (_audioZones[_zoneReverbSettings[i].zone].contains(streamPosition)) { hasReverb = true; reverbTime = _zoneReverbSettings[i].reverbTime; @@ -754,11 +753,13 @@ void AudioMixer::run() { bool dataChanged = (stream->hasReverb() != hasReverb) || (stream->hasReverb() && (stream->getRevebTime() != reverbTime || stream->getWetLevel() != wetLevel)); - // Update stream - if (hasReverb) { - stream->setReverb(reverbTime, wetLevel); - } else { - stream->clearReverb(); + if (dataChanged) { + // Update stream + if (hasReverb) { + stream->setReverb(reverbTime, wetLevel); + } else { + stream->clearReverb(); + } } // Send at change or every so often @@ -770,7 +771,6 @@ void AudioMixer::run() { char* envDataAt = clientEnvBuffer + numBytesEnvPacketHeader; unsigned char bitset = 0; - setAtBit(bitset, HAS_DATA_BIT); if (hasReverb) { setAtBit(bitset, HAS_REVERB_BIT); } diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 12449a9879..366659b633 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -13,7 +13,6 @@ #include "InboundAudioStream.h" #include "PacketHeaders.h" -#include const int STARVE_HISTORY_CAPACITY = 50; diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index 737147e2ba..ad2b7266ed 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -45,9 +45,8 @@ const int DEFAULT_WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES = 50; const int DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION = 10; const bool DEFAULT_REPETITION_WITH_FADE = true; -// Mixed Audio bitset -const int HAS_DATA_BIT = 0; // 1st bit -const int HAS_REVERB_BIT = 1; // 2nd bit +// Audio Env bitset +const int HAS_REVERB_BIT = 0; // 1st bit class InboundAudioStream : public NodeData { Q_OBJECT From 9c30903eb67e6339da4038c145e2b860838b99cc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 12:05:56 -0700 Subject: [PATCH 09/21] add the VerboseLoggingHelper class for repeated messages --- libraries/shared/src/VerboseLoggingHelper.cpp | 34 ++++++++++++++++++ libraries/shared/src/VerboseLoggingHelper.h | 36 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 libraries/shared/src/VerboseLoggingHelper.cpp create mode 100644 libraries/shared/src/VerboseLoggingHelper.h diff --git a/libraries/shared/src/VerboseLoggingHelper.cpp b/libraries/shared/src/VerboseLoggingHelper.cpp new file mode 100644 index 0000000000..6fa3f8a5a5 --- /dev/null +++ b/libraries/shared/src/VerboseLoggingHelper.cpp @@ -0,0 +1,34 @@ +// +// VerboseLoggingHelper.cpp +// libraries/shared/src +// +// Created by Stephen Birarda on 2014-10-28. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "VerboseLoggingHelper.h" + +VerboseLoggingHelper& VerboseLoggingHelper::getInstance() { + static VerboseLoggingHelper sharedInstance; + return sharedInstance; +} + +VerboseLoggingHelper::VerboseLoggingHelper() { + // setup our timer to flush the verbose logs every 5 seconds + _timer = new QTimer(this); + connect(_timer, &QTimer::timeout, this, &VerboseLoggingHelper::flushMessages); + _timer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000); +} + +void VerboseLoggingHelper::flushMessages() { + QHash::iterator message = _messageCountHash.begin(); + while (message != _messageCountHash.end()) { + qDebug() << message.key().arg(message.value()); + message = _messageCountHash.erase(message); + } +} \ No newline at end of file diff --git a/libraries/shared/src/VerboseLoggingHelper.h b/libraries/shared/src/VerboseLoggingHelper.h new file mode 100644 index 0000000000..368dfa51e6 --- /dev/null +++ b/libraries/shared/src/VerboseLoggingHelper.h @@ -0,0 +1,36 @@ +// +// VerboseLoggingHelper.h +// libraries/shared/src +// +// Created by Stephen Birarda on 2014-10-28. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_VerboseLoggingHelper_h +#define hifi_VerboseLoggingHelper_h + +#include +#include +#include + +const int VERBOSE_LOG_INTERVAL_SECONDS = 5; + +class VerboseLoggingHelper : public QObject { + Q_OBJECT +public: + static VerboseLoggingHelper& getInstance(); + + void addMessage(const QString& message) { _messageCountHash[message] += 1; } +private: + VerboseLoggingHelper(); + + void flushMessages(); + + QTimer* _timer; + QHash _messageCountHash; +}; + +#endif // hifi_VerboseLoggingHelper_h \ No newline at end of file From 8a4c716452ae0c1dd95468ffe0eafff1ee4d83a1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 12:15:52 -0700 Subject: [PATCH 10/21] leverage the VerboseLoggingHelper for packets from unknown nodes --- libraries/networking/src/LimitedNodeList.cpp | 8 ++++++-- libraries/shared/src/VerboseLoggingHelper.cpp | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 919dc75c23..93f50b2824 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" @@ -211,8 +213,10 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { << uuidFromPacketHeader(packet); } } else { - qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" - << uuidFromPacketHeader(packet); + QString unknownPacketString = "%1 packets of type " + QString::number(checkType) + + " received from unknown node with UUID " + + uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet)); + VerboseLoggingHelper::getInstance().addMessage(unknownPacketString); } } else { return true; diff --git a/libraries/shared/src/VerboseLoggingHelper.cpp b/libraries/shared/src/VerboseLoggingHelper.cpp index 6fa3f8a5a5..ae014f425d 100644 --- a/libraries/shared/src/VerboseLoggingHelper.cpp +++ b/libraries/shared/src/VerboseLoggingHelper.cpp @@ -28,7 +28,8 @@ VerboseLoggingHelper::VerboseLoggingHelper() { void VerboseLoggingHelper::flushMessages() { QHash::iterator message = _messageCountHash.begin(); while (message != _messageCountHash.end()) { - qDebug() << message.key().arg(message.value()); + qDebug() << qPrintable(message.key().arg(message.value())) + << "in last" << VERBOSE_LOG_INTERVAL_SECONDS << "seconds."; message = _messageCountHash.erase(message); } } \ No newline at end of file From 2711ff2b5f9e895888ce1a65779f82846be29f53 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 13:48:53 -0700 Subject: [PATCH 11/21] move functionality from VerboseLoggingHelper into the Logging class --- interface/src/Application.cpp | 4 -- libraries/networking/src/LimitedNodeList.cpp | 8 +-- libraries/networking/src/Logging.cpp | 69 +++++-------------- libraries/networking/src/Logging.h | 41 +++++------ libraries/shared/src/VerboseLoggingHelper.cpp | 35 ---------- libraries/shared/src/VerboseLoggingHelper.h | 36 ---------- 6 files changed, 38 insertions(+), 155 deletions(-) delete mode 100644 libraries/shared/src/VerboseLoggingHelper.cpp delete mode 100644 libraries/shared/src/VerboseLoggingHelper.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 140e51ee3e..f0bd2fb66c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -581,10 +581,6 @@ void Application::initializeGL() { float startupTime = (float)_applicationStartupTime.elapsed() / 1000.0; _justStarted = false; qDebug("Startup time: %4.2f seconds.", startupTime); - const char LOGSTASH_INTERFACE_START_TIME_KEY[] = "interface-start-time"; - - // ask the Logstash class to record the startup time - Logging::stashValue(STAT_TYPE_TIMER, LOGSTASH_INTERFACE_START_TIME_KEY, startupTime); } // update before the first render diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 93f50b2824..46ab4f4b0b 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -19,8 +19,6 @@ #include #include -#include - #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" @@ -213,10 +211,8 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { << uuidFromPacketHeader(packet); } } else { - QString unknownPacketString = "%1 packets of type " + QString::number(checkType) - + " received from unknown node with UUID " - + uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet)); - VerboseLoggingHelper::getInstance().addMessage(unknownPacketString); + qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" + << uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet)); } } else { return true; diff --git a/libraries/networking/src/Logging.cpp b/libraries/networking/src/Logging.cpp index f42f1bda58..bb704729af 100644 --- a/libraries/networking/src/Logging.cpp +++ b/libraries/networking/src/Logging.cpp @@ -9,12 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include -#include -#include -#include -//#include // not available on windows, apparently not needed on mac - #ifdef _WIN32 #include #define getpid _getpid @@ -22,55 +16,22 @@ #define pid_t int // hack to build #endif -#include - -#include "HifiSockAddr.h" -#include "SharedUtil.h" -#include "NodeList.h" +#include #include "Logging.h" -HifiSockAddr Logging::_logstashSocket = HifiSockAddr(); QString Logging::_targetName = QString(); -const HifiSockAddr& Logging::socket() { - - if (_logstashSocket.getAddress().isNull()) { - // we need to construct the socket object - // use the constant port - _logstashSocket.setPort(htons(LOGSTASH_UDP_PORT)); - - // lookup the IP address for the constant hostname - QHostInfo hostInfo = QHostInfo::fromName(LOGSTASH_HOSTNAME); - if (!hostInfo.addresses().isEmpty()) { - // use the first IP address - _logstashSocket.setAddress(hostInfo.addresses().first()); - } else { - qDebug("Failed to lookup logstash IP - will try again on next log attempt."); - } - } - - return _logstashSocket; +Logging& Logging::getInstance() { + static Logging staticInstance; + return staticInstance; } -bool Logging::shouldSendStats() { - static bool shouldSendStats = isInEnvironment("production"); - return shouldSendStats; -} - -void Logging::stashValue(char statType, const char* key, float value) { - static char logstashPacket[MAX_PACKET_SIZE]; - - // load up the logstash packet with the key and the passed float value - // send it to 4 decimal places - int numPacketBytes = sprintf(logstashPacket, "%c %s %.4f", statType, key, value); - - NodeList *nodeList = NodeList::getInstance(); - - if (nodeList) { - nodeList->getNodeSocket().writeDatagram(logstashPacket, numPacketBytes, - _logstashSocket.getAddress(), _logstashSocket.getPort()); - } +Logging::Logging() { + // setup our timer to flush the verbose logs every 5 seconds + QTimer* logFlushTimer = new QTimer(this); + connect(logFlushTimer, &QTimer::timeout, this, &Logging::flushRepeatedMessages); + logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000); } const char* stringForLogType(QtMsgType msgType) { @@ -95,6 +56,7 @@ void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& co if (message.isEmpty()) { return; } + // log prefix is in the following format // [DEBUG] [TIMESTAMP] [PID:PARENT_PID] [TARGET] logged string @@ -118,9 +80,16 @@ void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& co prefixString.append("]"); } - if (!_targetName.isEmpty()) { - prefixString.append(QString(" [%1]").arg(_targetName)); + if (!getInstance()._targetName.isEmpty()) { + prefixString.append(QString(" [%1]").arg(getInstance()._targetName)); } fprintf(stdout, "%s %s\n", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData()); } + +void Logging::flushRepeatedMessages() { + QHash::iterator message = _repeatMessageCountHash.begin(); + while (message != _repeatMessageCountHash.end()) { + message = _repeatMessageCountHash.erase(message); + } +} diff --git a/libraries/networking/src/Logging.h b/libraries/networking/src/Logging.h index c52812bd33..458cbf90e8 100644 --- a/libraries/networking/src/Logging.h +++ b/libraries/networking/src/Logging.h @@ -12,33 +12,18 @@ #ifndef hifi_Logging_h #define hifi_Logging_h -#include +#include +#include +#include +#include +#include -const int LOGSTASH_UDP_PORT = 9500; -const char LOGSTASH_HOSTNAME[] = "graphite.highfidelity.io"; - -const char STAT_TYPE_TIMER = 't'; -const char STAT_TYPE_COUNTER = 'c'; -const char STAT_TYPE_GAUGE = 'g'; - -class HifiSockAddr; +const int VERBOSE_LOG_INTERVAL_SECONDS = 5; /// Handles custom message handling and sending of stats/logs to Logstash instance -class Logging { +class Logging : public QObject { + Q_OBJECT public: - /// \return the socket used to send stats to logstash - static const HifiSockAddr& socket(); - - /// checks if this target should send stats to logstash, given its current environment - /// \return true if the caller should send stats to logstash - static bool shouldSendStats(); - - /// stashes a float value to Logstash instance - /// \param statType a stat type from the constants in this file - /// \param key the key at which to store the stat - /// \param value the value to store - static void stashValue(char statType, const char* key, float value); - /// sets the target name to output via the verboseMessageHandler, called once before logging begins /// \param targetName the desired target name to output in logs static void setTargetName(const QString& targetName) { _targetName = targetName; } @@ -46,9 +31,17 @@ public: /// a qtMessageHandler that can be hooked up to a target that links to Qt /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); + + static void addRepeatedMessageRegex(const QRegExp& regex) { getInstance()._repeatedMessageRegexes.append(regex); } private: - static HifiSockAddr _logstashSocket; + static Logging& getInstance(); + Logging(); + + void flushRepeatedMessages(); + static QString _targetName; + QList _repeatedMessageRegexes; + QHash _repeatMessageCountHash; }; #endif // hifi_Logging_h diff --git a/libraries/shared/src/VerboseLoggingHelper.cpp b/libraries/shared/src/VerboseLoggingHelper.cpp deleted file mode 100644 index ae014f425d..0000000000 --- a/libraries/shared/src/VerboseLoggingHelper.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// VerboseLoggingHelper.cpp -// libraries/shared/src -// -// Created by Stephen Birarda on 2014-10-28. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "VerboseLoggingHelper.h" - -VerboseLoggingHelper& VerboseLoggingHelper::getInstance() { - static VerboseLoggingHelper sharedInstance; - return sharedInstance; -} - -VerboseLoggingHelper::VerboseLoggingHelper() { - // setup our timer to flush the verbose logs every 5 seconds - _timer = new QTimer(this); - connect(_timer, &QTimer::timeout, this, &VerboseLoggingHelper::flushMessages); - _timer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000); -} - -void VerboseLoggingHelper::flushMessages() { - QHash::iterator message = _messageCountHash.begin(); - while (message != _messageCountHash.end()) { - qDebug() << qPrintable(message.key().arg(message.value())) - << "in last" << VERBOSE_LOG_INTERVAL_SECONDS << "seconds."; - message = _messageCountHash.erase(message); - } -} \ No newline at end of file diff --git a/libraries/shared/src/VerboseLoggingHelper.h b/libraries/shared/src/VerboseLoggingHelper.h deleted file mode 100644 index 368dfa51e6..0000000000 --- a/libraries/shared/src/VerboseLoggingHelper.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// VerboseLoggingHelper.h -// libraries/shared/src -// -// Created by Stephen Birarda on 2014-10-28. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_VerboseLoggingHelper_h -#define hifi_VerboseLoggingHelper_h - -#include -#include -#include - -const int VERBOSE_LOG_INTERVAL_SECONDS = 5; - -class VerboseLoggingHelper : public QObject { - Q_OBJECT -public: - static VerboseLoggingHelper& getInstance(); - - void addMessage(const QString& message) { _messageCountHash[message] += 1; } -private: - VerboseLoggingHelper(); - - void flushMessages(); - - QTimer* _timer; - QHash _messageCountHash; -}; - -#endif // hifi_VerboseLoggingHelper_h \ No newline at end of file From d3bbd251db27cc517002d41fbd6fe4c5debfd243 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 13:59:23 -0700 Subject: [PATCH 12/21] move Logging to LogHandler --- assignment-client/src/AssignmentClient.cpp | 6 +-- .../src/AssignmentClientMonitor.cpp | 4 +- assignment-client/src/audio/AudioMixer.cpp | 2 +- assignment-client/src/avatars/AvatarMixer.cpp | 2 +- assignment-client/src/main.cpp | 4 +- assignment-client/src/octree/OctreeServer.cpp | 4 +- domain-server/src/main.cpp | 4 +- ice-server/src/main.cpp | 4 +- interface/src/Application.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 3 +- libraries/networking/src/NodeList.cpp | 3 +- .../networking/src/ThreadedAssignment.cpp | 5 ++- .../Logging.cpp => shared/src/LogHandler.cpp} | 41 ++++++++++--------- .../src/Logging.h => shared/src/LogHandler.h} | 30 +++++++------- 14 files changed, 60 insertions(+), 54 deletions(-) rename libraries/{networking/src/Logging.cpp => shared/src/LogHandler.cpp} (78%) rename libraries/{networking/src/Logging.h => shared/src/LogHandler.h} (63%) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index b30cd355d1..e7ac7577b9 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -51,7 +51,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : connect(&_shutdownEventListener, SIGNAL(receivedCloseEvent()), SLOT(quit())); // set the logging target to the the CHILD_TARGET_NAME - Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); + LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); const QVariantMap argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments()); @@ -218,7 +218,7 @@ void AssignmentClient::handleAuthenticationRequest() { void AssignmentClient::assignmentCompleted() { // reset the logging target to the the CHILD_TARGET_NAME - Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); + LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); qDebug("Assignment finished or never started - waiting for new assignment."); diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index af09ff1535..02a4ff04f0 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include +#include #include "AssignmentClientMonitor.h" @@ -21,7 +21,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int num QCoreApplication(argc, argv) { // start the Logging class with the parent's target name - Logging::setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); + LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); _childArguments = arguments(); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 8d87638434..cc834798d7 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include #include diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 93f38e3608..3ec7c5cfbf 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 5e103cf767..3bf6990a74 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include +#include #include #include "Assignment.h" @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) { #endif // use the verbose message handler in Logging - qInstallMessageHandler(Logging::verboseMessageHandler); + qInstallMessageHandler(LogHandler::verboseMessageHandler); const char* numForksString = getCmdOption(argc, (const char**)argv, NUM_FORKS_PARAMETER); diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index d0a17287cb..121cac0273 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include "../AssignmentClient.h" @@ -923,7 +923,7 @@ void OctreeServer::run() { beforeRun(); // after payload has been processed - qInstallMessageHandler(Logging::verboseMessageHandler); + qInstallMessageHandler(LogHandler::verboseMessageHandler); const char* STATUS_PORT = "--statusPort"; const char* statusPort = getCmdOption(_argc, _argv, STATUS_PORT); diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 82e4bf7cab..ba80e6fce0 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -17,7 +17,7 @@ #include -#include +#include #include #include "DomainServer.h" @@ -27,7 +27,7 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); #endif - qInstallMessageHandler(Logging::verboseMessageHandler); + qInstallMessageHandler(LogHandler::verboseMessageHandler); int currentExitCode = 0; diff --git a/ice-server/src/main.cpp b/ice-server/src/main.cpp index 21c8b563b1..2326984668 100644 --- a/ice-server/src/main.cpp +++ b/ice-server/src/main.cpp @@ -11,7 +11,7 @@ #include -#include +#include #include "IceServer.h" @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); #endif - qInstallMessageHandler(Logging::verboseMessageHandler); + qInstallMessageHandler(LogHandler::verboseMessageHandler); IceServer iceServer(argc, argv); return iceServer.exec(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f0bd2fb66c..e1088136c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 46ab4f4b0b..48a94e5444 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -19,10 +19,11 @@ #include #include +#include + #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" -#include "Logging.h" #include "LimitedNodeList.h" #include "PacketHeaders.h" #include "SharedUtil.h" diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index feeb13500a..ff3b86880d 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -15,10 +15,11 @@ #include #include +#include + #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" -#include "Logging.h" #include "NodeList.h" #include "PacketHeaders.h" #include "SharedUtil.h" diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 6d2e366499..52644a9a4e 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -14,7 +14,8 @@ #include #include -#include "Logging.h" +#include + #include "ThreadedAssignment.h" ThreadedAssignment::ThreadedAssignment(const QByteArray& packet) : @@ -54,7 +55,7 @@ void ThreadedAssignment::setFinished(bool isFinished) { void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeType, bool shouldSendStats) { // change the logging target name while the assignment is running - Logging::setTargetName(targetName); + LogHandler::getInstance().setTargetName(targetName); NodeList* nodeList = NodeList::getInstance(); nodeList->setOwnerType(nodeType); diff --git a/libraries/networking/src/Logging.cpp b/libraries/shared/src/LogHandler.cpp similarity index 78% rename from libraries/networking/src/Logging.cpp rename to libraries/shared/src/LogHandler.cpp index bb704729af..123b418562 100644 --- a/libraries/networking/src/Logging.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -1,9 +1,10 @@ // -// Logging.cpp -// libraries/networking/src +// LogHandler.cpp +// libraries/shared/src // -// Created by Stephen Birarda on 6/11/13. -// Copyright 2013 High Fidelity, Inc. +// Created by Stephen Birarda on 2014-10-28. +// Migrated from Logging.cpp created on 6/11/13 +// Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -18,19 +19,17 @@ #include -#include "Logging.h" +#include "LogHandler.h" -QString Logging::_targetName = QString(); - -Logging& Logging::getInstance() { - static Logging staticInstance; +LogHandler& LogHandler::getInstance() { + static LogHandler staticInstance; return staticInstance; } -Logging::Logging() { +LogHandler::LogHandler() { // setup our timer to flush the verbose logs every 5 seconds QTimer* logFlushTimer = new QTimer(this); - connect(logFlushTimer, &QTimer::timeout, this, &Logging::flushRepeatedMessages); + connect(logFlushTimer, &QTimer::timeout, this, &LogHandler::flushRepeatedMessages); logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000); } @@ -52,34 +51,34 @@ const char* stringForLogType(QtMsgType msgType) { // the following will produce 2000-10-02 13:55:36 -0700 const char DATE_STRING_FORMAT[] = "%Y-%m-%d %H:%M:%S %z"; -void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { +void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { if (message.isEmpty()) { return; } // log prefix is in the following format // [DEBUG] [TIMESTAMP] [PID:PARENT_PID] [TARGET] logged string - + QString prefixString = QString("[%1]").arg(stringForLogType(type)); - + time_t rawTime; time(&rawTime); struct tm* localTime = localtime(&rawTime); - + char dateString[100]; strftime(dateString, sizeof(dateString), DATE_STRING_FORMAT, localTime); - + prefixString.append(QString(" [%1]").arg(dateString)); - + prefixString.append(QString(" [%1").arg(getpid())); - + pid_t parentProcessID = getppid(); if (parentProcessID != 0) { prefixString.append(QString(":%1]").arg(parentProcessID)); } else { prefixString.append("]"); } - + if (!getInstance()._targetName.isEmpty()) { prefixString.append(QString(" [%1]").arg(getInstance()._targetName)); } @@ -87,9 +86,11 @@ void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& co fprintf(stdout, "%s %s\n", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData()); } -void Logging::flushRepeatedMessages() { +void LogHandler::flushRepeatedMessages() { QHash::iterator message = _repeatMessageCountHash.begin(); while (message != _repeatMessageCountHash.end()) { message = _repeatMessageCountHash.erase(message); } } + + diff --git a/libraries/networking/src/Logging.h b/libraries/shared/src/LogHandler.h similarity index 63% rename from libraries/networking/src/Logging.h rename to libraries/shared/src/LogHandler.h index 458cbf90e8..e89a739c6a 100644 --- a/libraries/networking/src/Logging.h +++ b/libraries/shared/src/LogHandler.h @@ -1,16 +1,17 @@ // -// Logging.h -// libraries/networking/src +// LogHandler.cpp +// libraries/shared/src // -// Created by Stephen Birarda on 6/11/13. -// Copyright 2013 High Fidelity, Inc. +// Created by Stephen Birarda on 2014-10-28. +// Migrated from Logging.cpp created on 6/11/13 +// Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_Logging_h -#define hifi_Logging_h +#ifndef hifi_LogHandler_h +#define hifi_LogHandler_h #include #include @@ -21,27 +22,28 @@ const int VERBOSE_LOG_INTERVAL_SECONDS = 5; /// Handles custom message handling and sending of stats/logs to Logstash instance -class Logging : public QObject { +class LogHandler : public QObject { Q_OBJECT public: + static LogHandler& getInstance(); + /// sets the target name to output via the verboseMessageHandler, called once before logging begins /// \param targetName the desired target name to output in logs - static void setTargetName(const QString& targetName) { _targetName = targetName; } - + void setTargetName(const QString& targetName) { _targetName = targetName; } + /// a qtMessageHandler that can be hooked up to a target that links to Qt /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); - static void addRepeatedMessageRegex(const QRegExp& regex) { getInstance()._repeatedMessageRegexes.append(regex); } + void addRepeatedMessageRegex(const QRegExp& regex) { _repeatedMessageRegexes.append(regex); } private: - static Logging& getInstance(); - Logging(); + LogHandler(); void flushRepeatedMessages(); - static QString _targetName; + QString _targetName; QList _repeatedMessageRegexes; QHash _repeatMessageCountHash; }; -#endif // hifi_Logging_h +#endif // hifi_LogHandler_h \ No newline at end of file From 8e3102266a587897c5f35f3bafc19d938c2e00a3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 14:23:34 -0700 Subject: [PATCH 13/21] use the LogHandler in Interface --- interface/src/Application.cpp | 10 ++- libraries/networking/src/LimitedNodeList.cpp | 3 + libraries/shared/src/LogHandler.cpp | 66 ++++++++++++++------ libraries/shared/src/LogHandler.h | 10 ++- 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e1088136c4..16d8062303 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -116,12 +116,10 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D const QString DEFAULT_SCRIPTS_JS_URL = "http://public.highfidelity.io/scripts/defaultScripts.js"; void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { - if (message.size() > 0) { - QString dateString = QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime).toString(Qt::ISODate); - QString formattedMessage = QString("[%1] %2\n").arg(dateString).arg(message); - - fprintf(stdout, "%s", qPrintable(formattedMessage)); - Application::getInstance()->getLogger()->addMessage(qPrintable(formattedMessage)); + QString logMessage = LogHandler::getInstance().printMessage(type, context, message); + + if (!logMessage.isEmpty()) { + Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage)); } } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 48a94e5444..600427a733 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -212,6 +212,9 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { << uuidFromPacketHeader(packet); } } else { + static QString repeatedMessage + = LogHandler::getInstance().addRepeatedMessageRegex("Packet of type \\d+ received from unknown node with UUID"); + qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet)); } diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 123b418562..078cdf5ab6 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -17,6 +17,7 @@ #define pid_t int // hack to build #endif +#include #include #include "LogHandler.h" @@ -26,7 +27,9 @@ LogHandler& LogHandler::getInstance() { return staticInstance; } -LogHandler::LogHandler() { +LogHandler::LogHandler() : + _shouldOutputPID(false) +{ // setup our timer to flush the verbose logs every 5 seconds QTimer* logFlushTimer = new QTimer(this); connect(logFlushTimer, &QTimer::timeout, this, &LogHandler::flushRepeatedMessages); @@ -51,9 +54,33 @@ const char* stringForLogType(QtMsgType msgType) { // the following will produce 2000-10-02 13:55:36 -0700 const char DATE_STRING_FORMAT[] = "%Y-%m-%d %H:%M:%S %z"; -void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { +void LogHandler::flushRepeatedMessages() { + QHash::iterator message = _repeatMessageCountHash.begin(); + while (message != _repeatMessageCountHash.end()) { + message = _repeatMessageCountHash.erase(message); + } +} + +QString LogHandler::printMessage(QtMsgType type, const QMessageLogContext& context, const QString& message) { + if (message.isEmpty()) { - return; + return QString(); + } + + if (type == QtDebugMsg) { + // for debug messages, check if this matches any of our regexes for repeated log messages + foreach(const QString& regexString, getInstance()._repeatedMessageRegexes) { + QRegExp repeatRegex(regexString); + if (repeatRegex.indexIn(message) != -1) { + + // we have a match - add 1 to the count of repeats for this message and set this as the last repeated message + _repeatMessageCountHash[regexString] += 1; + _lastRepeatedMessage[regexString] = message; + + // return out, we're not printing this one + return QString(); + } + } } // log prefix is in the following format @@ -70,27 +97,26 @@ void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& prefixString.append(QString(" [%1]").arg(dateString)); - prefixString.append(QString(" [%1").arg(getpid())); - - pid_t parentProcessID = getppid(); - if (parentProcessID != 0) { - prefixString.append(QString(":%1]").arg(parentProcessID)); - } else { - prefixString.append("]"); + if (_shouldOutputPID) { + prefixString.append(QString(" [%1").arg(getpid())); + + pid_t parentProcessID = getppid(); + if (parentProcessID != 0) { + prefixString.append(QString(":%1]").arg(parentProcessID)); + } else { + prefixString.append("]"); + } } - if (!getInstance()._targetName.isEmpty()) { - prefixString.append(QString(" [%1]").arg(getInstance()._targetName)); + if (!_targetName.isEmpty()) { + prefixString.append(QString(" [%1]").arg(_targetName)); } - fprintf(stdout, "%s %s\n", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData()); + QString logMessage = QString("%1 %2").arg(prefixString, message); + fprintf(stdout, "%s\n", qPrintable(logMessage)); + return logMessage; } -void LogHandler::flushRepeatedMessages() { - QHash::iterator message = _repeatMessageCountHash.begin(); - while (message != _repeatMessageCountHash.end()) { - message = _repeatMessageCountHash.erase(message); - } +void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { + getInstance().printMessage(type, context, message); } - - diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index e89a739c6a..abc39b7040 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -31,19 +31,25 @@ public: /// \param targetName the desired target name to output in logs void setTargetName(const QString& targetName) { _targetName = targetName; } + void setShouldOutputPID(bool shouldOutputPID) { _shouldOutputPID = shouldOutputPID; } + + QString printMessage(QtMsgType type, const QMessageLogContext& context, const QString &message); + /// a qtMessageHandler that can be hooked up to a target that links to Qt /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); - void addRepeatedMessageRegex(const QRegExp& regex) { _repeatedMessageRegexes.append(regex); } + const QString& addRepeatedMessageRegex(const QString& regexString) { return *_repeatedMessageRegexes.insert(regexString); } private: LogHandler(); void flushRepeatedMessages(); QString _targetName; - QList _repeatedMessageRegexes; + bool _shouldOutputPID; + QSet _repeatedMessageRegexes; QHash _repeatMessageCountHash; + QHash _lastRepeatedMessage; }; #endif // hifi_LogHandler_h \ No newline at end of file From 424793b90515a759cd9fd9b5223bd194867e1db4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 14:49:14 -0700 Subject: [PATCH 14/21] complete output of suppressed repeated messages to log --- interface/src/Application.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 2 +- libraries/shared/src/LogHandler.cpp | 17 +++++++++++++---- libraries/shared/src/LogHandler.h | 10 +++++++++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 16d8062303..141ba20416 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -116,7 +116,7 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D const QString DEFAULT_SCRIPTS_JS_URL = "http://public.highfidelity.io/scripts/defaultScripts.js"; void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { - QString logMessage = LogHandler::getInstance().printMessage(type, context, message); + QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message); if (!logMessage.isEmpty()) { Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage)); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 600427a733..5c4dc6cea2 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -216,7 +216,7 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { = LogHandler::getInstance().addRepeatedMessageRegex("Packet of type \\d+ received from unknown node with UUID"); qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" - << uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet)); + << qPrintable(uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet))); } } else { return true; diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 078cdf5ab6..aa377b5683 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -36,7 +36,7 @@ LogHandler::LogHandler() : logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000); } -const char* stringForLogType(QtMsgType msgType) { +const char* stringForLogType(LogMsgType msgType) { switch (msgType) { case QtDebugMsg: return "DEBUG"; @@ -46,6 +46,8 @@ const char* stringForLogType(QtMsgType msgType) { return "FATAL"; case QtWarningMsg: return "WARNING"; + case LogSuppressed: + return "SUPPRESS"; default: return "UNKNOWN"; } @@ -57,17 +59,24 @@ const char DATE_STRING_FORMAT[] = "%Y-%m-%d %H:%M:%S %z"; void LogHandler::flushRepeatedMessages() { QHash::iterator message = _repeatMessageCountHash.begin(); while (message != _repeatMessageCountHash.end()) { + QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"") + .arg(message.value()).arg(message.key()).arg(_lastRepeatedMessage.value(message.key())); + + QMessageLogContext emptyContext; + printMessage(LogSuppressed, emptyContext, repeatMessage); + + _lastRepeatedMessage.remove(message.key()); message = _repeatMessageCountHash.erase(message); } } -QString LogHandler::printMessage(QtMsgType type, const QMessageLogContext& context, const QString& message) { +QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& context, const QString& message) { if (message.isEmpty()) { return QString(); } - if (type == QtDebugMsg) { + if (type == LogDebug) { // for debug messages, check if this matches any of our regexes for repeated log messages foreach(const QString& regexString, getInstance()._repeatedMessageRegexes) { QRegExp repeatRegex(regexString); @@ -118,5 +127,5 @@ QString LogHandler::printMessage(QtMsgType type, const QMessageLogContext& conte } void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { - getInstance().printMessage(type, context, message); + getInstance().printMessage((LogMsgType) type, context, message); } diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index abc39b7040..f8f06b0033 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -21,6 +21,14 @@ const int VERBOSE_LOG_INTERVAL_SECONDS = 5; +enum LogMsgType { + LogDebug, + LogWarning, + LogCritical, + LogFatal, + LogSuppressed +}; + /// Handles custom message handling and sending of stats/logs to Logstash instance class LogHandler : public QObject { Q_OBJECT @@ -33,7 +41,7 @@ public: void setShouldOutputPID(bool shouldOutputPID) { _shouldOutputPID = shouldOutputPID; } - QString printMessage(QtMsgType type, const QMessageLogContext& context, const QString &message); + QString printMessage(LogMsgType type, const QMessageLogContext& context, const QString &message); /// a qtMessageHandler that can be hooked up to a target that links to Qt /// prints various process, message type, and time information From c4538836c16918ab05d3d558e7d3a30105bc74bb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 14:51:47 -0700 Subject: [PATCH 15/21] always output the first matching repeated log message --- libraries/shared/src/LogHandler.cpp | 31 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index aa377b5683..9a081e429d 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -59,11 +59,14 @@ const char DATE_STRING_FORMAT[] = "%Y-%m-%d %H:%M:%S %z"; void LogHandler::flushRepeatedMessages() { QHash::iterator message = _repeatMessageCountHash.begin(); while (message != _repeatMessageCountHash.end()) { - QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"") - .arg(message.value()).arg(message.key()).arg(_lastRepeatedMessage.value(message.key())); - QMessageLogContext emptyContext; - printMessage(LogSuppressed, emptyContext, repeatMessage); + if (message.value() > 0) { + QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"") + .arg(message.value()).arg(message.key()).arg(_lastRepeatedMessage.value(message.key())); + + QMessageLogContext emptyContext; + printMessage(LogSuppressed, emptyContext, repeatMessage); + } _lastRepeatedMessage.remove(message.key()); message = _repeatMessageCountHash.erase(message); @@ -82,12 +85,20 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont QRegExp repeatRegex(regexString); if (repeatRegex.indexIn(message) != -1) { - // we have a match - add 1 to the count of repeats for this message and set this as the last repeated message - _repeatMessageCountHash[regexString] += 1; - _lastRepeatedMessage[regexString] = message; - - // return out, we're not printing this one - return QString(); + if (!_repeatMessageCountHash.contains(regexString)) { + // we have a match but didn't have this yet - output the first one + _repeatMessageCountHash[regexString] = 0; + + // break the foreach so we output the first match + break; + } else { + // we have a match - add 1 to the count of repeats for this message and set this as the last repeated message + _repeatMessageCountHash[regexString] += 1; + _lastRepeatedMessage[regexString] = message; + + // return out, we're not printing this one + return QString(); + } } } } From 2816e8f11403965344699cf7f834d155387b5d99 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 15:32:23 -0700 Subject: [PATCH 16/21] fix location DataWebDialog missing InterfaceLocation object --- interface/src/Menu.cpp | 4 ++-- libraries/networking/src/AddressManager.cpp | 4 ++++ libraries/networking/src/AddressManager.h | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 274afd4bca..0bebe06b1c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1315,7 +1315,7 @@ void Menu::displayNameLocationResponse(const QString& errorString) { void Menu::toggleLocationList() { if (!_userLocationsDialog) { JavascriptObjectMap locationObjectMap; - locationObjectMap.insert("InterfaceLocation", LocationScriptingInterface::getInstance()); + locationObjectMap.insert("InterfaceLocation", &AddressManager::getInstance()); _userLocationsDialog = DataWebDialog::dialogForPath("/user/locations", locationObjectMap); } @@ -1359,7 +1359,7 @@ void Menu::nameLocation() { if (!_newLocationDialog) { JavascriptObjectMap locationObjectMap; - locationObjectMap.insert("InterfaceLocation", LocationScriptingInterface::getInstance()); + locationObjectMap.insert("InterfaceLocation", &AddressManager::getInstance()); _newLocationDialog = DataWebDialog::dialogForPath("/user/locations/new", locationObjectMap); } diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 1201a8973f..b4765dc362 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -71,6 +71,10 @@ const QString AddressManager::currentPath(bool withOrientation) const { } } +QString AddressManager::getDomainID() const { + return NodeList::getInstance()->getDomainHandler().getUUID().toString(); +} + const JSONCallbackParameters& AddressManager::apiCallbackParameters() { static bool hasSetupParameters = false; static JSONCallbackParameters callbackParams; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 8a25464223..d6ecdc9fc6 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -31,6 +31,7 @@ class AddressManager : public QObject { Q_PROPERTY(QString protocol READ getProtocol) Q_PROPERTY(QString hostname READ getCurrentDomain) Q_PROPERTY(QString pathname READ currentPath) + Q_PROPERTY(QString domainID READ getDomainID) public: static AddressManager& getInstance(); @@ -41,6 +42,7 @@ public: const QString currentPath(bool withOrientation = true) const; const QString& getCurrentDomain() const { return _currentDomain; } + QString getDomainID() const; void attemptPlaceNameLookup(const QString& lookupString); From 33c247918e96d0bf6b9f4ef1d9f60e3e394c4325 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 15:37:42 -0700 Subject: [PATCH 17/21] fix for domainID wrapped in braces --- libraries/networking/src/AddressManager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index b4765dc362..6113cadb06 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "NodeList.h" @@ -72,7 +73,8 @@ const QString AddressManager::currentPath(bool withOrientation) const { } QString AddressManager::getDomainID() const { - return NodeList::getInstance()->getDomainHandler().getUUID().toString(); + const QUuid& domainID = NodeList::getInstance()->getDomainHandler().getUUID(); + return domainID.isNull() ? "" : uuidStringWithoutCurlyBraces(domainID); } const JSONCallbackParameters& AddressManager::apiCallbackParameters() { From 6ba0845767d94afabfe67e6057671b1bdd829cec Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 15:39:25 -0700 Subject: [PATCH 18/21] fix warnings that were bugging Xcode --- interface/src/Menu.cpp | 1 - interface/src/gpu/Batch.cpp | 2 ++ interface/src/renderer/Model.cpp | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 0bebe06b1c..4e453bfde2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1266,7 +1266,6 @@ void Menu::changeVSync() { } void Menu::changeRenderTargetFramerate(QAction* action) { bool vsynOn = Application::getInstance()->isVSyncOn(); - unsigned int framerate = Application::getInstance()->getRenderTargetFramerate(); QString text = action->text(); if (text == MenuOption::RenderTargetFramerateUnlimited) { diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index 054bc09846..b7db58ea30 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -111,6 +111,8 @@ void Batch::runCommand(Command com, uint32 offset) { CASE_COMMAND(glColor4f); CASE_COMMAND(glMaterialf); CASE_COMMAND(glMaterialfv); + default: + break; } } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index e949e9a811..cdec00aee2 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1737,7 +1737,8 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl mesh.texCoords.size() * sizeof(glm::vec2) + (mesh.blendshapes.isEmpty() ? vertexCount * 2 * sizeof(glm::vec3) : 0); //skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4); - GLBATCH(glVertexAttribPointer)(skinLocations->clusterIndices, 4, GL_FLOAT, GL_TRUE, 0, (const void*) offset); + GLBATCH(glVertexAttribPointer)(skinLocations->clusterIndices, 4, GL_FLOAT, GL_TRUE, 0, + reinterpret_cast(offset)); //skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT, // offset + vertexCount * sizeof(glm::vec4), 4); GLBATCH(glVertexAttribPointer)(skinLocations->clusterWeights, 4, GL_FLOAT, GL_TRUE, 0, (const void*) (offset + vertexCount * sizeof(glm::vec4))); From 01de6305e943828588fd6d74b7b135122634b3fa Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 15:42:03 -0700 Subject: [PATCH 19/21] add time header for date in log entry --- libraries/shared/src/LogHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 9a081e429d..7b06b77ae8 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -10,6 +10,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #ifdef _WIN32 #include #define getpid _getpid From 992396ba63da824065072ecc2877d0578aadf186 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 15:48:06 -0700 Subject: [PATCH 20/21] add ctime for strftime call --- libraries/shared/src/LogHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 7b06b77ae8..88afba8c07 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -11,6 +11,7 @@ // #include +#include #ifdef _WIN32 #include From 9af097967ddd8e4fee8fcb59b21bd455eb1abd9a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Oct 2014 15:56:30 -0700 Subject: [PATCH 21/21] remove ctime since windows build did not fail without it --- libraries/shared/src/LogHandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 88afba8c07..7b06b77ae8 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -11,7 +11,6 @@ // #include -#include #ifdef _WIN32 #include