transition listener registration from member string name to member string pointer

This commit is contained in:
Heather Anderson 2020-08-09 14:57:00 -07:00
parent e74cbee6cb
commit 2e5244663e
32 changed files with 343 additions and 251 deletions

View file

@ -112,11 +112,12 @@ Agent::Agent(ReceivedMessage& message) :
packetReceiver.registerListenerForTypes(
{ PacketType::MixedAudio, PacketType::SilentAudioFrame },
this, "handleAudioPacket");
PacketReceiver::makeUnsourcedListenerReference<Agent>(this, &Agent::handleAudioPacket));
packetReceiver.registerListenerForTypes(
{ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
this, "handleOctreePacket");
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
PacketReceiver::makeSourcedListenerReference<Agent>(this, &Agent::handleOctreePacket));
packetReceiver.registerListener(PacketType::SelectedAudioFormat,
PacketReceiver::makeUnsourcedListenerReference<Agent>(this, &Agent::handleSelectedAudioFormat));
// 100Hz timer for audio
const int TARGET_INTERVAL_MSEC = 10; // 10ms

View file

@ -118,8 +118,10 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
setUpStatusToMonitor();
}
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket");
packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket");
packetReceiver.registerListener(PacketType::CreateAssignment,
PacketReceiver::makeUnsourcedListenerReference<AssignmentClient>(this, &AssignmentClient::handleCreateAssignmentPacket));
packetReceiver.registerListener(PacketType::StopNode,
PacketReceiver::makeUnsourcedListenerReference<AssignmentClient>(this, &AssignmentClient::handleStopNodePacket));
}
void AssignmentClient::stopAssignmentClient() {

View file

@ -72,7 +72,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
auto nodeList = DependencyManager::set<LimitedNodeList>(listenPort);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket");
packetReceiver.registerListener(PacketType::AssignmentClientStatus,
PacketReceiver::makeUnsourcedListenerReference<AssignmentClientMonitor>(this, &AssignmentClientMonitor::handleChildStatusPacket));
adjustOSResources(std::max(_numAssignmentClientForks, _maxAssignmentClientForks));
// use QProcess to fork off a process for each of the child assignment clients

View file

@ -308,7 +308,8 @@ AssetServer::AssetServer(ReceivedMessage& message) :
// Queue all requests until the Asset Server is fully setup
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, this, "queueRequests");
packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation },
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::queueRequests));
#ifdef Q_OS_WIN
updateConsumedCores();
@ -464,10 +465,14 @@ void AssetServer::completeSetup() {
qCDebug(asset_server) << "Overriding temporary queuing packet handler.";
// We're fully setup, override the request queueing handler and replay all requests
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet");
packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo");
packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload");
packetReceiver.registerListener(PacketType::AssetMappingOperation, this, "handleAssetMappingOperation");
packetReceiver.registerListener(PacketType::AssetGet,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetGet));
packetReceiver.registerListener(PacketType::AssetGetInfo,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetGetInfo));
packetReceiver.registerListener(PacketType::AssetUpload,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetUpload));
packetReceiver.registerListener(PacketType::AssetMappingOperation,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetMappingOperation));
replayRequests();
}

View file

@ -101,20 +101,23 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
PacketType::InjectorGainSet,
PacketType::AudioSoloRequest,
PacketType::StopInjector },
this, "queueAudioPacket");
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::queueAudioPacket)
);
// packets whose consequences are global should be processed on the main thread
packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket");
packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::MuteEnvironment,
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::handleMuteEnvironmentPacket));
packetReceiver.registerListener(PacketType::NodeMuteRequest,
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::handleNodeMuteRequestPacket));
packetReceiver.registerListener(PacketType::KillAvatar,
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::handleKillAvatarPacket));
packetReceiver.registerListenerForTypes({
PacketType::ReplicatedMicrophoneAudioNoEcho,
PacketType::ReplicatedMicrophoneAudioWithEcho,
PacketType::ReplicatedInjectAudio,
PacketType::ReplicatedSilentAudioFrame
},
this, "queueReplicatedAudioPacket"
PacketType::ReplicatedSilentAudioFrame },
PacketReceiver::makeUnsourcedListenerReference<AudioMixer>(this, &AudioMixer::queueReplicatedAudioPacket)
);
connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);

View file

@ -71,26 +71,38 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &AvatarMixer::handleAvatarKilled);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket");
packetReceiver.registerListener(PacketType::AdjustAvatarSorting, this, "handleAdjustAvatarSorting");
packetReceiver.registerListener(PacketType::AvatarQuery, this, "handleAvatarQueryPacket");
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket");
packetReceiver.registerListener(PacketType::SetAvatarTraits, this, "queueIncomingPacket");
packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck, this, "queueIncomingPacket");
packetReceiver.registerListener(PacketType::AvatarData,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListener(PacketType::AdjustAvatarSorting,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleAdjustAvatarSorting));
packetReceiver.registerListener(PacketType::AvatarQuery,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleAvatarQueryPacket));
packetReceiver.registerListener(PacketType::AvatarIdentity,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleAvatarIdentityPacket));
packetReceiver.registerListener(PacketType::KillAvatar,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleKillAvatarPacket));
packetReceiver.registerListener(PacketType::NodeIgnoreRequest,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleNodeIgnoreRequestPacket));
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleRadiusIgnoreRequestPacket));
packetReceiver.registerListener(PacketType::RequestsDomainListData,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleRequestsDomainListDataPacket));
packetReceiver.registerListener(PacketType::SetAvatarTraits,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
this, "handleOctreePacket");
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "queueIncomingPacket");
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleOctreePacket));
packetReceiver.registerListener(PacketType::ChallengeOwnership,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListenerForTypes({
PacketType::ReplicatedAvatarIdentity,
PacketType::ReplicatedKillAvatar
}, this, "handleReplicatedPacket");
}, PacketReceiver::makeUnsourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleReplicatedPacket));
packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData, this, "handleReplicatedBulkAvatarPacket");
packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData,
PacketReceiver::makeUnsourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleReplicatedBulkAvatarPacket));
auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &AvatarMixer::handlePacketVersionMismatch);

View file

@ -59,8 +59,7 @@ EntityServer::EntityServer(ReceivedMessage& message) :
PacketType::ChallengeOwnership,
PacketType::ChallengeOwnershipRequest,
PacketType::ChallengeOwnershipReply },
this,
"handleEntityPacket");
PacketReceiver::makeSourcedListenerReference<EntityServer>(this, &EntityServer::handleEntityPacket));
connect(&_dynamicDomainVerificationTimer, &QTimer::timeout, this, &EntityServer::startDynamicDomainVerification);
_dynamicDomainVerificationTimer.setSingleShot(true);

View file

@ -25,9 +25,12 @@ MessagesMixer::MessagesMixer(ReceivedMessage& message) : ThreadedAssignment(mess
{
connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &MessagesMixer::nodeKilled);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessages");
packetReceiver.registerListener(PacketType::MessagesSubscribe, this, "handleMessagesSubscribe");
packetReceiver.registerListener(PacketType::MessagesUnsubscribe, this, "handleMessagesUnsubscribe");
packetReceiver.registerListener(PacketType::MessagesData,
PacketReceiver::makeSourcedListenerReference<MessagesMixer>(this, &MessagesMixer::handleMessages));
packetReceiver.registerListener(PacketType::MessagesSubscribe,
PacketReceiver::makeSourcedListenerReference<MessagesMixer>(this, &MessagesMixer::handleMessagesSubscribe));
packetReceiver.registerListener(PacketType::MessagesUnsubscribe,
PacketReceiver::makeSourcedListenerReference<MessagesMixer>(this, &MessagesMixer::handleMessagesUnsubscribe));
}
void MessagesMixer::nodeKilled(SharedNodePointer killedNode) {

View file

@ -1122,8 +1122,10 @@ void OctreeServer::run() {
void OctreeServer::domainSettingsRequestComplete() {
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket");
packetReceiver.registerListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket");
packetReceiver.registerListener(PacketType::OctreeDataNack,
PacketReceiver::makeSourcedListenerReference<OctreeServer>(this, &OctreeServer::handleOctreeDataNackPacket));
packetReceiver.registerListener(getMyQueryMessageType(),
PacketReceiver::makeSourcedListenerReference<OctreeServer>(this, &OctreeServer::handleOctreeQueryPacket));
qDebug(octree_server) << "Received domain settings";

View file

@ -83,13 +83,18 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
this, "handleOctreePacket");
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleOctreePacket));
packetReceiver.registerListener(PacketType::SelectedAudioFormat,
PacketReceiver::makeUnsourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleSelectedAudioFormat));
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
packetReceiver.registerListener(PacketType::ReloadEntityServerScript,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleReloadEntityServerScriptPacket));
packetReceiver.registerListener(PacketType::EntityScriptGetStatus,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleEntityScriptGetStatusPacket));
packetReceiver.registerListener(PacketType::EntityServerScriptLog,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleEntityServerScriptLogPacket));
packetReceiver.registerListener(PacketType::EntityScriptCallMethod,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleEntityScriptCallMethodPacket));
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
auto timer = new QTimer(this);

View file

@ -17,7 +17,8 @@
#include <openssl/x509.h>
#include <random>
#include <QDataStream>
#include <QtCore/QDataStream>
#include <QtCore/QMetaMethod>
#include <AccountManager.h>
#include <Assignment.h>

View file

@ -765,32 +765,51 @@ void DomainServer::setupNodeListAndAssignments() {
// register as the packet receiver for the types we want
PacketReceiver& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket");
packetReceiver.registerListener(PacketType::DomainListRequest, this, "processListRequestPacket");
packetReceiver.registerListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket");
packetReceiver.registerListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket");
packetReceiver.registerListener(PacketType::DomainDisconnectRequest, this, "processNodeDisconnectRequestPacket");
packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacket");
packetReceiver.registerListener(PacketType::RequestAssignment,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processRequestAssignmentPacket));
packetReceiver.registerListener(PacketType::DomainListRequest,
PacketReceiver::makeSourcedListenerReference<DomainServer>(this, &DomainServer::processListRequestPacket));
packetReceiver.registerListener(PacketType::DomainServerPathQuery,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processPathQueryPacket));
packetReceiver.registerListener(PacketType::NodeJsonStats,
PacketReceiver::makeSourcedListenerReference<DomainServer>(this, &DomainServer::processNodeJSONStatsPacket));
packetReceiver.registerListener(PacketType::DomainDisconnectRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processNodeDisconnectRequestPacket));
packetReceiver.registerListener(PacketType::AvatarZonePresence,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processAvatarZonePresencePacket));
// NodeList won't be available to the settings manager when it is created, so call registerListener here
packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket");
packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket");
packetReceiver.registerListener(PacketType::UsernameFromIDRequest, &_settingsManager, "processUsernameFromIDRequestPacket");
packetReceiver.registerListener(PacketType::DomainSettingsRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainServerSettingsManager>(&_settingsManager, &DomainServerSettingsManager::processSettingsRequestPacket));
packetReceiver.registerListener(PacketType::NodeKickRequest,
PacketReceiver::makeSourcedListenerReference<DomainServerSettingsManager>(&_settingsManager, &DomainServerSettingsManager::processNodeKickRequestPacket));
packetReceiver.registerListener(PacketType::UsernameFromIDRequest,
PacketReceiver::makeSourcedListenerReference<DomainServerSettingsManager>(&_settingsManager, &DomainServerSettingsManager::processUsernameFromIDRequestPacket));
// register the gatekeeper for the packets it needs to receive
packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket");
packetReceiver.registerListener(PacketType::ICEPing, &_gatekeeper, "processICEPingPacket");
packetReceiver.registerListener(PacketType::ICEPingReply, &_gatekeeper, "processICEPingReplyPacket");
packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_gatekeeper, "processICEPeerInformationPacket");
packetReceiver.registerListener(PacketType::DomainConnectRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processConnectRequestPacket));
packetReceiver.registerListener(PacketType::ICEPing,
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processICEPingPacket));
packetReceiver.registerListener(PacketType::ICEPingReply,
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processICEPingReplyPacket));
packetReceiver.registerListener(PacketType::ICEServerPeerInformation,
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processICEPeerInformationPacket));
packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied, this, "processICEServerHeartbeatDenialPacket");
packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK, this, "processICEServerHeartbeatACK");
packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processICEServerHeartbeatDenialPacket));
packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processICEServerHeartbeatACK));
packetReceiver.registerListener(PacketType::OctreeDataFileRequest, this, "processOctreeDataRequestMessage");
packetReceiver.registerListener(PacketType::OctreeDataPersist, this, "processOctreeDataPersistMessage");
packetReceiver.registerListener(PacketType::OctreeDataFileRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processOctreeDataRequestMessage));
packetReceiver.registerListener(PacketType::OctreeDataPersist,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processOctreeDataPersistMessage));
packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacementRequest");
packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, this, "handleDomainContentReplacementFromURLRequest");
packetReceiver.registerListener(PacketType::OctreeFileReplacement,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::handleOctreeFileReplacementRequest));
packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::handleDomainContentReplacementFromURLRequest));
// set a custom packetVersionMatch as the verify packet operator for the udt::Socket
nodeList->setPacketFilterOperator(&DomainServer::isPacketVerified);

View file

@ -211,6 +211,8 @@ private:
/// guard read/write access from multiple threads to settings
QReadWriteLock _settingsLock { QReadWriteLock::Recursive };
friend class DomainServer;
};
#endif // hifi_DomainServerSettingsManager_h

View file

@ -288,8 +288,10 @@ Wallet::Wallet() {
auto& packetReceiver = nodeList->getPacketReceiver();
_passphrase = new QString("");
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket");
packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest, this, "handleChallengeOwnershipPacket");
packetReceiver.registerListener(PacketType::ChallengeOwnership,
PacketReceiver::makeSourcedListenerReference<Wallet>(this, &Wallet::handleChallengeOwnershipPacket));
packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest,
PacketReceiver::makeSourcedListenerReference<Wallet>(this, &Wallet::handleChallengeOwnershipPacket));
connect(ledger.data(), &Ledger::accountResult, this, [](QJsonObject result) {
auto wallet = DependencyManager::get<Wallet>();

View file

@ -25,7 +25,8 @@ OctreePacketProcessor::OctreePacketProcessor():
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
const PacketReceiver::PacketTypeList octreePackets =
{ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase, PacketType::EntityQueryInitialResultsComplete };
packetReceiver.registerDirectListenerForTypes(octreePackets, this, "handleOctreePacket");
packetReceiver.registerDirectListenerForTypes(octreePackets,
PacketReceiver::makeSourcedListenerReference<OctreePacketProcessor>(this, &OctreePacketProcessor::handleOctreePacket));
}
OctreePacketProcessor::~OctreePacketProcessor() { }

View file

@ -42,7 +42,8 @@ ScreenshareScriptingInterface::ScreenshareScriptingInterface() {
// This packet listener handles the packet containing information about the latest zone ID in which we are allowed to share.
auto nodeList = DependencyManager::get<NodeList>();
PacketReceiver& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacketOnClient");
packetReceiver.registerListener(PacketType::AvatarZonePresence,
PacketReceiver::makeUnsourcedListenerReference<ScreenshareScriptingInterface>(this, &ScreenshareScriptingInterface::processAvatarZonePresencePacketOnClient));
};
ScreenshareScriptingInterface::~ScreenshareScriptingInterface() {

View file

@ -9,7 +9,8 @@
//
#include "DomainConnectionModel.h"
#include <QLoggingCategory>
#include <QtCore/QLoggingCategory>
#include <QtCore/QMetaMethod>
#include <NodeList.h>
#include <NumericalConstants.h>

View file

@ -81,7 +81,8 @@ ContextOverlayInterface::ContextOverlayInterface() {
auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::ChallengeOwnershipReply, this, "handleChallengeOwnershipReplyPacket");
packetReceiver.registerListener(PacketType::ChallengeOwnershipReply,
PacketReceiver::makeSourcedListenerReference<ContextOverlayInterface>(this, &ContextOverlayInterface::handleChallengeOwnershipReplyPacket));
_challengeOwnershipTimeoutTimer.setSingleShot(true);
}

View file

@ -369,13 +369,20 @@ AudioClient::AudioClient() {
auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::AudioStreamStats, &_stats, "processStreamStatsPacket");
packetReceiver.registerListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket");
packetReceiver.registerListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket");
packetReceiver.registerListener(PacketType::MixedAudio, this, "handleAudioDataPacket");
packetReceiver.registerListener(PacketType::NoisyMute, this, "handleNoisyMutePacket");
packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket");
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
packetReceiver.registerListener(PacketType::AudioStreamStats,
PacketReceiver::makeSourcedListenerReference<AudioIOStats>(&_stats, &AudioIOStats::processStreamStatsPacket));
packetReceiver.registerListener(PacketType::AudioEnvironment,
PacketReceiver::makeUnsourcedListenerReference<AudioClient>(this, &AudioClient::handleAudioEnvironmentDataPacket));
packetReceiver.registerListener(PacketType::SilentAudioFrame,
PacketReceiver::makeUnsourcedListenerReference<AudioClient>(this, &AudioClient::handleAudioDataPacket));
packetReceiver.registerListener(PacketType::MixedAudio,
PacketReceiver::makeUnsourcedListenerReference<AudioClient>(this, &AudioClient::handleAudioDataPacket));
packetReceiver.registerListener(PacketType::NoisyMute,
PacketReceiver::makeUnsourcedListenerReference<AudioClient>(this, &AudioClient::handleNoisyMutePacket));
packetReceiver.registerListener(PacketType::MuteEnvironment,
PacketReceiver::makeUnsourcedListenerReference<AudioClient>(this, &AudioClient::handleMuteEnvironmentPacket));
packetReceiver.registerListener(PacketType::SelectedAudioFormat,
PacketReceiver::makeUnsourcedListenerReference<AudioClient>(this, &AudioClient::handleSelectedAudioFormat));
auto& domainHandler = nodeList->getDomainHandler();
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] {

View file

@ -123,10 +123,14 @@ AvatarHashMap::AvatarHashMap() {
auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar");
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
packetReceiver.registerListener(PacketType::BulkAvatarTraits, this, "processBulkAvatarTraits");
packetReceiver.registerListener(PacketType::BulkAvatarData,
PacketReceiver::makeSourcedListenerReference<AvatarHashMap>(this, &AvatarHashMap::processAvatarDataPacket));
packetReceiver.registerListener(PacketType::KillAvatar,
PacketReceiver::makeSourcedListenerReference<AvatarHashMap>(this, &AvatarHashMap::processKillAvatar));
packetReceiver.registerListener(PacketType::AvatarIdentity,
PacketReceiver::makeSourcedListenerReference<AvatarHashMap>(this, &AvatarHashMap::processAvatarIdentityPacket));
packetReceiver.registerListener(PacketType::BulkAvatarTraits,
PacketReceiver::makeSourcedListenerReference<AvatarHashMap>(this, &AvatarHashMap::processBulkAvatarTraits));
connect(nodeList.data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);

View file

@ -28,7 +28,8 @@ ClientTraitsHandler::ClientTraitsHandler(AvatarData* owningAvatar) :
}
});
nodeList->getPacketReceiver().registerListener(PacketType::SetAvatarTraits, this, "processTraitOverride");
nodeList->getPacketReceiver().registerListener(PacketType::SetAvatarTraits,
PacketReceiver::makeSourcedListenerReference<ClientTraitsHandler>(this, &ClientTraitsHandler::processTraitOverride));
}
void ClientTraitsHandler::markTraitUpdated(AvatarTraits::TraitType updatedTrait) {

View file

@ -26,7 +26,8 @@
EntityEditPacketSender::EntityEditPacketSender() {
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerDirectListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket");
packetReceiver.registerDirectListener(PacketType::EntityEditNack,
PacketReceiver::makeSourcedListenerReference<EntityEditPacketSender>(this, &EntityEditPacketSender::processEntityEditNackPacket));
}
void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {

View file

@ -14,7 +14,8 @@
EntityScriptServerLogClient::EntityScriptServerLogClient() {
auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
packetReceiver.registerListener(PacketType::EntityServerScriptLog,
PacketReceiver::makeSourcedListenerReference<EntityScriptServerLogClient>(this, &EntityScriptServerLogClient::handleEntityServerScriptLogPacket));
QObject::connect(nodeList.data(), &NodeList::nodeActivated, this, &EntityScriptServerLogClient::nodeActivated);
QObject::connect(nodeList.data(), &NodeList::nodeKilled, this, &EntityScriptServerLogClient::nodeKilled);

View file

@ -59,7 +59,8 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
connect(nodeList.data(), &NodeList::canGetAndSetPrivateUserDataChanged, this, &EntityScriptingInterface::canGetAndSetPrivateUserDataChanged);
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
packetReceiver.registerListener(PacketType::EntityScriptCallMethod,
PacketReceiver::makeSourcedListenerReference<EntityScriptingInterface>(this, &EntityScriptingInterface::handleEntityScriptCallMethodPacket));
}
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,

View file

@ -43,10 +43,14 @@ AssetClient::AssetClient() {
auto nodeList = DependencyManager::get<LimitedNodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::AssetMappingOperationReply, this, "handleAssetMappingOperationReply");
packetReceiver.registerListener(PacketType::AssetGetInfoReply, this, "handleAssetGetInfoReply");
packetReceiver.registerListener(PacketType::AssetGetReply, this, "handleAssetGetReply", true);
packetReceiver.registerListener(PacketType::AssetUploadReply, this, "handleAssetUploadReply");
packetReceiver.registerListener(PacketType::AssetMappingOperationReply,
PacketReceiver::makeSourcedListenerReference<AssetClient>(this, &AssetClient::handleAssetMappingOperationReply));
packetReceiver.registerListener(PacketType::AssetGetInfoReply,
PacketReceiver::makeSourcedListenerReference<AssetClient>(this, &AssetClient::handleAssetGetInfoReply));
packetReceiver.registerListener(PacketType::AssetGetReply,
PacketReceiver::makeSourcedListenerReference<AssetClient>(this, &AssetClient::handleAssetGetReply), true);
packetReceiver.registerListener(PacketType::AssetUploadReply,
PacketReceiver::makeSourcedListenerReference<AssetClient>(this, &AssetClient::handleAssetUploadReply));
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &AssetClient::handleNodeKilled);
connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset,

View file

@ -34,7 +34,8 @@ EntityScriptClient::EntityScriptClient() {
auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply, this, "handleGetScriptStatusReply");
packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply,
PacketReceiver::makeSourcedListenerReference<EntityScriptClient>(this, &EntityScriptClient::handleGetScriptStatusReply));
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptClient::handleNodeKilled);
connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset,

View file

@ -28,7 +28,8 @@ MessagesClient::MessagesClient() {
});
auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessagesPacket");
packetReceiver.registerListener(PacketType::MessagesData,
PacketReceiver::makeSourcedListenerReference<MessagesClient>(this, &MessagesClient::handleMessagesPacket));
connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &MessagesClient::handleNodeActivated);
}

View file

@ -139,20 +139,34 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort)
startSTUNPublicSocketUpdate();
auto& packetReceiver = getPacketReceiver();
packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList");
packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket");
packetReceiver.registerListener(PacketType::PingReply, this, "processPingReplyPacket");
packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket");
packetReceiver.registerListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode");
packetReceiver.registerListener(PacketType::DomainServerConnectionToken, this, "processDomainServerConnectionTokenPacket");
packetReceiver.registerListener(PacketType::DomainConnectionDenied, &_domainHandler, "processDomainServerConnectionDeniedPacket");
packetReceiver.registerListener(PacketType::DomainSettings, &_domainHandler, "processSettingsPacketList");
packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_domainHandler, "processICEResponsePacket");
packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, &_domainHandler, "processDTLSRequirementPacket");
packetReceiver.registerListener(PacketType::ICEPingReply, &_domainHandler, "processICEPingReplyPacket");
packetReceiver.registerListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathResponse");
packetReceiver.registerListener(PacketType::DomainServerRemovedNode, this, "processDomainServerRemovedNode");
packetReceiver.registerListener(PacketType::UsernameFromIDReply, this, "processUsernameFromIDReply");
packetReceiver.registerListener(PacketType::DomainList,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processDomainServerList));
packetReceiver.registerListener(PacketType::Ping,
PacketReceiver::makeSourcedListenerReference<NodeList>(this, &NodeList::processPingPacket));
packetReceiver.registerListener(PacketType::PingReply,
PacketReceiver::makeSourcedListenerReference<NodeList>(this, &NodeList::processPingReplyPacket));
packetReceiver.registerListener(PacketType::ICEPing,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processICEPingPacket));
packetReceiver.registerListener(PacketType::DomainServerAddedNode,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processDomainServerAddedNode));
packetReceiver.registerListener(PacketType::DomainServerConnectionToken,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processDomainServerConnectionTokenPacket));
packetReceiver.registerListener(PacketType::DomainConnectionDenied,
PacketReceiver::makeUnsourcedListenerReference<DomainHandler>(&_domainHandler, &DomainHandler::processDomainServerConnectionDeniedPacket));
packetReceiver.registerListener(PacketType::DomainSettings,
PacketReceiver::makeUnsourcedListenerReference<DomainHandler>(&_domainHandler, &DomainHandler::processSettingsPacketList));
packetReceiver.registerListener(PacketType::ICEServerPeerInformation,
PacketReceiver::makeUnsourcedListenerReference<DomainHandler>(&_domainHandler, &DomainHandler::processICEResponsePacket));
packetReceiver.registerListener(PacketType::DomainServerRequireDTLS,
PacketReceiver::makeUnsourcedListenerReference<DomainHandler>(&_domainHandler, &DomainHandler::processDTLSRequirementPacket));
packetReceiver.registerListener(PacketType::ICEPingReply,
PacketReceiver::makeUnsourcedListenerReference<DomainHandler>(&_domainHandler, &DomainHandler::processICEPingReplyPacket));
packetReceiver.registerListener(PacketType::DomainServerPathResponse,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processDomainServerPathResponse));
packetReceiver.registerListener(PacketType::DomainServerRemovedNode,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processDomainServerRemovedNode));
packetReceiver.registerListener(PacketType::UsernameFromIDReply,
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processUsernameFromIDReply));
}
qint64 NodeList::sendStats(QJsonObject statsObject, HifiSockAddr destination) {

View file

@ -12,7 +12,8 @@
#include "PacketReceiver.h"
#include <QMutexLocker>
#include <QtCore/QMetaObject>
#include <QtCore/QMutexLocker>
#include "DependencyManager.h"
#include "NetworkLogging.h"
@ -25,85 +26,56 @@ PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent) {
qRegisterMetaType<QSharedPointer<ReceivedMessage>>();
}
bool PacketReceiver::registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot) {
bool PacketReceiver::ListenerReference::invokeWithQt(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>& sourceNode) {
return QMetaObject::invokeMethod(getObject(), [=]() {
this->invokeDirectly(receivedMessagePointer, sourceNode);
});
}
bool PacketReceiver::registerListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener) {
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");
Q_ASSERT_X(listener, "PacketReceiver::registerListenerForTypes", "No listener 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 PacketTypeEnum::getNonSourcedPackets().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;
}
}
// 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);
std::for_each(std::begin(types), std::end(types), [this, &listener](PacketType type) {
registerVerifiedListener(type, listener);
});
return true;
}
void PacketReceiver::registerDirectListener(PacketType type, QObject* listener, const char* slot) {
Q_ASSERT_X(listener, "PacketReceiver::registerDirectListener", "No object to register");
Q_ASSERT_X(slot, "PacketReceiver::registerDirectListener", "No slot to register");
void PacketReceiver::registerDirectListener(PacketType type, const ListenerReferencePointer& listener) {
Q_ASSERT_X(listener, "PacketReceiver::registerDirectListener", "No listener to register");
bool success = registerListener(type, listener, slot);
bool success = registerListener(type, listener);
if (success) {
QMutexLocker locker(&_directConnectSetMutex);
// if we successfully registered, add this object to the set of objects that are directly connected
_directlyConnectedObjects.insert(listener);
_directlyConnectedObjects.insert(listener->getObject());
}
}
void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types,
QObject* listener, const char* slot) {
Q_ASSERT_X(listener, "PacketReceiver::registerDirectListenerForTypes", "No object to register");
Q_ASSERT_X(slot, "PacketReceiver::registerDirectListenerForTypes", "No slot to register");
void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener) {
Q_ASSERT_X(listener, "PacketReceiver::registerDirectListenerForTypes", "No listener to register");
// just call register listener for types to start
bool success = registerListenerForTypes(std::move(types), listener, slot);
bool success = registerListenerForTypes(std::move(types), listener);
if (success) {
QMutexLocker locker(&_directConnectSetMutex);
// if we successfully registered, add this object to the set of objects that are directly connected
_directlyConnectedObjects.insert(listener);
_directlyConnectedObjects.insert(listener->getObject());
}
}
bool PacketReceiver::registerListener(PacketType type, QObject* listener, const char* slot,
bool deliverPending) {
Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No object to register");
Q_ASSERT_X(slot, "PacketReceiver::registerListener", "No slot to register");
bool PacketReceiver::registerListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending) {
Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No listener to register");
QMetaMethod matchingMethod = matchingMethodForListener(type, listener, slot);
bool matchingMethod = matchingMethodForListener(type, listener);
if (matchingMethod.isValid()) {
if (matchingMethod) {
qCDebug(networking) << "Registering a packet listener for packet list type" << type;
registerVerifiedListener(type, listener, matchingMethod, deliverPending);
registerVerifiedListener(type, listener, deliverPending);
return true;
} else {
qCWarning(networking) << "FAILED to Register a packet listener for packet list type" << type;
@ -111,62 +83,23 @@ bool PacketReceiver::registerListener(PacketType type, QObject* listener, const
}
}
QMetaMethod PacketReceiver::matchingMethodForListener(PacketType type, QObject* object, const char* slot) const {
Q_ASSERT_X(object, "PacketReceiver::matchingMethodForListener", "No object to call");
Q_ASSERT_X(slot, "PacketReceiver::matchingMethodForListener", "No slot to call");
bool PacketReceiver::matchingMethodForListener(PacketType type, const ListenerReferencePointer& listener) const {
Q_ASSERT_X(listener, "PacketReceiver::matchingMethodForListener", "No listener to call");
// normalize the slot with the expected parameters
static const QString SIGNATURE_TEMPLATE("%1(%2)");
static const QString NON_SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer<ReceivedMessage>";
bool isSourced = listener->isSourced();
bool isNonSourcedPacket = PacketTypeEnum::getNonSourcedPackets().contains(type);
QSet<QString> possibleSignatures {
SIGNATURE_TEMPLATE.arg(slot, NON_SOURCED_MESSAGE_LISTENER_PARAMETERS)
};
if (!PacketTypeEnum::getNonSourcedPackets().contains(type)) {
static const QString SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer<ReceivedMessage>,QSharedPointer<Node>";
static const QString TYPEDEF_SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer<ReceivedMessage>,SharedNodePointer";
// a sourced packet must take the shared pointer to the ReceivedMessage but optionally could include
// a shared pointer to the node
possibleSignatures << SIGNATURE_TEMPLATE.arg(slot, TYPEDEF_SOURCED_MESSAGE_LISTENER_PARAMETERS);
possibleSignatures << SIGNATURE_TEMPLATE.arg(slot, SOURCED_MESSAGE_LISTENER_PARAMETERS);
assert(!isSourced || !isNonSourcedPacket);
if (isSourced && isNonSourcedPacket) {
qCDebug(networking) << "PacketReceiver::registerListener cannot support a sourced listener for type" << type;
return false;
}
int methodIndex = -1;
foreach(const QString& signature, possibleSignatures) {
QByteArray normalizedSlot =
QMetaObject::normalizedSignature(signature.toStdString().c_str());
// does the constructed normalized method exist?
methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.toStdString().c_str());
if (methodIndex >= 0) {
break;
}
}
if (methodIndex < 0) {
qCDebug(networking) << "PacketReceiver::registerListener expected a slot with one of the following signatures:"
<< possibleSignatures.toList() << "- but such a slot was not found."
<< "Could not complete listener registration for type" << type;
}
Q_ASSERT(methodIndex >= 0);
// return the converted QMetaMethod
if (methodIndex >= 0) {
return object->metaObject()->method(methodIndex);
} else {
// if somehow (scripting?) something bad gets in here at runtime that doesn't hit the asserts above
// return a non-valid QMetaMethod
return QMetaMethod();
}
return true;
}
void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object, const QMetaMethod& slot, bool deliverPending) {
Q_ASSERT_X(object, "PacketReceiver::registerVerifiedListener", "No object to register");
void PacketReceiver::registerVerifiedListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending) {
Q_ASSERT_X(listener, "PacketReceiver::registerVerifiedListener", "No listener to register");
QMutexLocker locker(&_packetListenerLock);
if (_messageListenerMap.contains(type)) {
@ -175,7 +108,7 @@ void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object,
}
// add the mapping
_messageListenerMap[type] = { QPointer<QObject>(object), slot, deliverPending };
_messageListenerMap[type] = { listener, deliverPending };
}
void PacketReceiver::unregisterListener(QObject* listener) {
@ -188,7 +121,7 @@ void PacketReceiver::unregisterListener(QObject* listener) {
auto it = _messageListenerMap.begin();
while (it != _messageListenerMap.end()) {
if (it.value().object == listener) {
if (it.value().listener->getObject() == listener) {
it = _messageListenerMap.erase(it);
} else {
++it;
@ -261,7 +194,7 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
QMutexLocker packetListenerLocker(&_packetListenerLock);
auto it = _messageListenerMap.find(receivedMessage->getType());
if (it != _messageListenerMap.end() && it->method.isValid()) {
if (it != _messageListenerMap.end() && !it->listener.isNull()) {
auto listener = it.value();
@ -271,36 +204,19 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
bool success = false;
Qt::ConnectionType connectionType;
bool isDirectConnect = false;
// check if this is a directly connected listener
{
QMutexLocker directConnectLocker(&_directConnectSetMutex);
connectionType = _directlyConnectedObjects.contains(listener.object) ? Qt::DirectConnection : Qt::AutoConnection;
isDirectConnect = _directlyConnectedObjects.contains(listener.listener->getObject());
}
QMetaMethod metaMethod = listener.method;
static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer<Node>");
static const QByteArray SHARED_NODE_NORMALIZED = QMetaObject::normalizedType("SharedNodePointer");
// one final check on the QPointer before we go to invoke
if (listener.object) {
if (metaMethod.parameterTypes().contains(SHARED_NODE_NORMALIZED)) {
success = metaMethod.invoke(listener.object,
connectionType,
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage),
Q_ARG(SharedNodePointer, matchingNode));
} else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) {
success = metaMethod.invoke(listener.object,
connectionType,
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage),
Q_ARG(QSharedPointer<Node>, matchingNode));
if (listener.listener->getObject()) {
if (isDirectConnect) {
success = listener.listener->invokeDirectly(receivedMessage, matchingNode);
} else {
success = metaMethod.invoke(listener.object,
connectionType,
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage));
success = listener.listener->invokeWithQt(receivedMessage, matchingNode);
}
} else {
qCDebug(networking).nospace() << "Listener for packet " << receivedMessage->getType()
@ -310,19 +226,19 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
// if it exists, remove the listener from _directlyConnectedObjects
{
QMutexLocker directConnectLocker(&_directConnectSetMutex);
_directlyConnectedObjects.remove(listener.object);
_directlyConnectedObjects.remove(listener.listener->getObject());
}
}
if (!success) {
qCDebug(networking).nospace() << "Error delivering packet " << receivedMessage->getType() << " to listener "
<< listener.object << "::" << qPrintable(listener.method.methodSignature());
<< listener.listener->getObject();
}
} else if (it == _messageListenerMap.end()) {
qCWarning(networking) << "No listener found for packet type" << receivedMessage->getType();
// insert a dummy listener so we don't print this again
_messageListenerMap.insert(receivedMessage->getType(), { nullptr, QMetaMethod(), false });
_messageListenerMap.insert(receivedMessage->getType(), { ListenerReferencePointer(), false });
}
}

View file

@ -16,8 +16,6 @@
#include <vector>
#include <unordered_map>
#include <QtCore/QMap>
#include <QtCore/QMetaMethod>
#include <QtCore/QMutex>
#include <QtCore/QObject>
#include <QtCore/QPointer>
@ -29,6 +27,7 @@
#include "udt/PacketHeaders.h"
class EntityEditPacketSender;
class Node;
class OctreePacketProcessor;
namespace std {
@ -42,6 +41,22 @@ namespace std {
class PacketReceiver : public QObject {
Q_OBJECT
public:
class ListenerReference {
public:
virtual bool invokeDirectly(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>& sourceNode) = 0;
bool invokeWithQt(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>& sourceNode);
virtual bool isSourced() const = 0;
virtual QObject* getObject() const = 0;
};
typedef QSharedPointer<ListenerReference> ListenerReferencePointer;
template<class T>
static ListenerReferencePointer makeUnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer<ReceivedMessage>));
template <class T>
static ListenerReferencePointer makeSourcedListenerReference(T* target, void (T::*slot)(QSharedPointer<ReceivedMessage>, QSharedPointer<Node>));
public:
using PacketTypeList = std::vector<PacketType>;
@ -55,8 +70,8 @@ public:
// If deliverPending is false, ReceivedMessage will only be delivered once all packets for the message have
// been received. If deliverPending is true, ReceivedMessage will be delivered as soon as the first packet
// for the message is received.
bool registerListener(PacketType type, QObject* listener, const char* slot, bool deliverPending = false);
bool registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot);
bool registerListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending = false);
bool registerListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener);
void unregisterListener(QObject* listener);
void handleVerifiedPacket(std::unique_ptr<udt::Packet> packet);
@ -64,9 +79,34 @@ public:
void handleMessageFailure(HifiSockAddr from, udt::Packet::MessageNumber messageNumber);
private:
template <class T>
class UnsourcedListenerReference : public ListenerReference {
public:
inline UnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer<ReceivedMessage>));
virtual bool invokeDirectly(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>& sourceNode);
virtual bool isSourced() const { return false; }
virtual QObject* getObject() const { return _target; }
private:
QPointer<T> _target;
void (T::*_slot)(QSharedPointer<ReceivedMessage>);
};
template <class T>
class SourcedListenerReference : public ListenerReference {
public:
inline SourcedListenerReference(T* target, void (T::*slot)(QSharedPointer<ReceivedMessage>, QSharedPointer<Node>));
virtual bool invokeDirectly(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>& sourceNode);
virtual bool isSourced() const { return true; }
virtual QObject* getObject() const { return _target; }
private:
QPointer<T> _target;
void (T::*_slot)(QSharedPointer<ReceivedMessage>, QSharedPointer<Node>);
};
struct Listener {
QPointer<QObject> object;
QMetaMethod method;
ListenerReferencePointer listener;
bool deliverPending;
};
@ -74,11 +114,11 @@ 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(PacketTypeList types, QObject* listener, const char* slot);
void registerDirectListener(PacketType type, QObject* listener, const char* slot);
void registerDirectListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener);
void registerDirectListener(PacketType type, const ListenerReferencePointer& listener);
QMetaMethod matchingMethodForListener(PacketType type, QObject* object, const char* slot) const;
void registerVerifiedListener(PacketType type, QObject* listener, const QMetaMethod& slot, bool deliverPending = false);
bool matchingMethodForListener(PacketType type, const ListenerReferencePointer& listener) const;
void registerVerifiedListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending = false);
QMutex _packetListenerLock;
QHash<PacketType, Listener> _messageListenerMap;
@ -93,4 +133,42 @@ private:
friend class OctreePacketProcessor;
};
template <class T>
PacketReceiver::ListenerReferencePointer PacketReceiver::makeUnsourcedListenerReference(T* target, void (T::* slot)(QSharedPointer<ReceivedMessage>)) {
return QSharedPointer<UnsourcedListenerReference<T>>::create(target, slot);
}
template <class T>
PacketReceiver::ListenerReferencePointer PacketReceiver::makeSourcedListenerReference(T* target, void (T::* slot)(QSharedPointer<ReceivedMessage>, QSharedPointer<Node>)) {
return QSharedPointer<SourcedListenerReference<T>>::create(target, slot);
}
template <class T>
PacketReceiver::UnsourcedListenerReference<T>::UnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer<ReceivedMessage>)) :
_target(target),_slot(slot) {
}
template <class T>
bool PacketReceiver::UnsourcedListenerReference<T>::invokeDirectly(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>&) {
if (_target.isNull()) {
return false;
}
(_target->*_slot)(receivedMessagePointer);
return true;
}
template <class T>
PacketReceiver::SourcedListenerReference<T>::SourcedListenerReference(T* target, void (T::*slot)(QSharedPointer<ReceivedMessage>, QSharedPointer<Node>)) :
_target(target),_slot(slot) {
}
template <class T>
bool PacketReceiver::SourcedListenerReference<T>::invokeDirectly(const QSharedPointer<ReceivedMessage>& receivedMessagePointer, const QSharedPointer<Node>& sourceNode) {
if (_target.isNull()) {
return false;
}
(_target->*_slot)(receivedMessagePointer, sourceNode);
return true;
}
#endif // hifi_PacketReceiver_h

View file

@ -16,8 +16,9 @@
#include <cmath>
#include <assert.h>
#include <QThread>
#include <QTimer>
#include <QtCore/QMetaMethod>
#include <QtCore/QThread>
#include <QtCore/QTimer>
#include <SharedUtil.h>
#include <shared/QtHelpers.h>

View file

@ -64,7 +64,8 @@ void OctreePersistThread::start() {
cleanupOldReplacementBackups();
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::OctreeDataFileReply, this, "handleOctreeDataFileReply");
packetReceiver.registerListener(PacketType::OctreeDataFileReply,
PacketReceiver::makeUnsourcedListenerReference<OctreePersistThread>(this, &OctreePersistThread::handleOctreeDataFileReply));
auto nodeList = DependencyManager::get<NodeList>();
const DomainHandler& domainHandler = nodeList->getDomainHandler();