From 62c76d0332baedf401eb88d75bb69f2d35c30eab Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 20 Aug 2015 14:55:51 +0200 Subject: [PATCH] registerListenerForTypes optimisations --- assignment-client/src/audio/AudioMixer.cpp | 11 ++- .../src/octree/OctreePacketProcessor.cpp | 9 +-- libraries/networking/src/PacketReceiver.cpp | 69 +++++++++---------- libraries/networking/src/PacketReceiver.h | 10 ++- 4 files changed, 48 insertions(+), 51 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 664088084d..c1d0cc2215 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -96,14 +96,11 @@ AudioMixer::AudioMixer(NLPacket& packet) : // SOON auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - - QSet nodeAudioPackets { - PacketType::MicrophoneAudioNoEcho, PacketType::MicrophoneAudioWithEcho, - PacketType::InjectAudio, PacketType::SilentAudioFrame, - PacketType::AudioStreamStats - }; - packetReceiver.registerListenerForTypes(nodeAudioPackets, this, "handleNodeAudioPacket"); + packetReceiver.registerListenerForTypes({ PacketType::MicrophoneAudioNoEcho, PacketType::MicrophoneAudioWithEcho, + PacketType::InjectAudio, PacketType::SilentAudioFrame, + PacketType::AudioStreamStats }, + this, "handleNodeAudioPacket"); packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 9bf845cccd..5b8ff78fad 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -18,13 +18,10 @@ OctreePacketProcessor::OctreePacketProcessor() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - - QSet types { - PacketType::OctreeStats, PacketType::EntityData, - PacketType::EntityErase, PacketType::OctreeStats - }; - packetReceiver.registerDirectListenerForTypes(types, this, "handleOctreePacket"); + packetReceiver.registerDirectListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, + PacketType::EntityErase, PacketType::OctreeStats }, + this, "handleOctreePacket"); } void OctreePacketProcessor::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index e7fff8e679..7a9a3b1ddd 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -19,49 +19,48 @@ #include "NodeList.h" #include "SharedUtil.h" -PacketReceiver::PacketReceiver(QObject* parent) : - QObject(parent), - _packetListenerMap() -{ +PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent) { qRegisterMetaType>(); } -bool PacketReceiver::registerListenerForTypes(const QSet& types, QObject* listener, const char* slot) { - QSet nonSourcedTypes; - QSet sourcedTypes; - - foreach(PacketType type, types) { - if (NON_SOURCED_PACKETS.contains(type)) { - nonSourcedTypes << type; - } else { - sourcedTypes << type; - } - } - - Q_ASSERT(listener); - - if (nonSourcedTypes.size() > 0) { - QMetaMethod nonSourcedMethod = matchingMethodForListener(*nonSourcedTypes.begin(), listener, slot); - if (nonSourcedMethod.isValid()) { - foreach(PacketType type, nonSourcedTypes) { - registerVerifiedListener(type, listener, nonSourcedMethod); - } - } else { +bool PacketReceiver::registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot) { + Q_ASSERT_X(!types.empty(), "PacketReceiver::registerListenerForTypes", "No types to register"); + Q_ASSERT_X(listener, "PacketReceiver::registerListenerForTypes", "No object to register"); + Q_ASSERT_X(slot, "PacketReceiver::registerListenerForTypes", "No slot to register"); + + // Partition types based on whether they are sourced or not (non sourced in front) + auto middle = std::partition(std::begin(types), std::end(types), [](PacketType type) { + return NON_SOURCED_PACKETS.contains(type); + }); + + QMetaMethod nonSourcedMethod, sourcedMethod; + + // Check we have a valid method for non sourced types if any + if (middle != std::begin(types)) { + nonSourcedMethod = matchingMethodForListener(*std::begin(types), listener, slot); + if (!nonSourcedMethod.isValid()) { return false; } } - - if (sourcedTypes.size() > 0) { - QMetaMethod sourcedMethod = matchingMethodForListener(*sourcedTypes.begin(), listener, slot); - if (sourcedMethod.isValid()) { - foreach(PacketType type, sourcedTypes) { - registerVerifiedListener(type, listener, sourcedMethod); - } - } else { + + // Check we have a valid method for sourced types if any + if (middle != std::end(types)) { + sourcedMethod = matchingMethodForListener(*middle, listener, slot); + if (!sourcedMethod.isValid()) { return false; } } + // Register non sourced types + std::for_each(std::begin(types), middle, [this, &listener, &nonSourcedMethod](PacketType type) { + registerVerifiedListener(type, listener, nonSourcedMethod); + }); + + // Register sourced types + std::for_each(middle, std::end(types), [this, &listener, &sourcedMethod](PacketType type) { + registerVerifiedListener(type, listener, sourcedMethod); + }); + return true; } @@ -77,10 +76,10 @@ void PacketReceiver::registerDirectListener(PacketType type, QObject* listener, } } -void PacketReceiver::registerDirectListenerForTypes(const QSet& types, +void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types, QObject* listener, const char* slot) { // just call register listener for types to start - bool success = registerListenerForTypes(types, listener, slot); + bool success = registerListenerForTypes(std::move(types), listener, slot); if (success) { _directConnectSetMutex.lock(); diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index b5a4501476..9965eccdc2 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -13,6 +13,8 @@ #ifndef hifi_PacketReceiver_h #define hifi_PacketReceiver_h +#include + #include #include #include @@ -30,6 +32,8 @@ class OctreePacketProcessor; class PacketReceiver : public QObject { Q_OBJECT public: + using PacketTypeList = std::vector; + PacketReceiver(QObject* parent = 0); PacketReceiver(const PacketReceiver&) = delete; @@ -42,8 +46,8 @@ public: void resetCounters() { _inPacketCount = 0; _inByteCount = 0; } - bool registerListenerForTypes(const QSet& types, QObject* listener, const char* slot); - bool registerMessageListener(PacketType types, QObject* listener, const char* slot); + bool registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot); + bool registerMessageListener(PacketType type, QObject* listener, const char* slot); bool registerListener(PacketType type, QObject* listener, const char* slot); void unregisterListener(QObject* listener); @@ -56,7 +60,7 @@ signals: private: // these are brutal hacks for now - ideally GenericThread / ReceivedPacketProcessor // should be changed to have a true event loop and be able to handle our QMetaMethod::invoke - void registerDirectListenerForTypes(const QSet& types, QObject* listener, const char* slot); + void registerDirectListenerForTypes(PacketTypeList types, QObject* listener, const char* slot); void registerDirectListener(PacketType type, QObject* listener, const char* slot); QMetaMethod matchingMethodForListener(PacketType type, QObject* object, const char* slot) const;