move ignore set handling to NodeList

This commit is contained in:
Stephen Birarda 2016-07-11 15:12:14 -07:00
parent 6b6513d5f9
commit 609900f246
7 changed files with 66 additions and 37 deletions

View file

@ -70,15 +70,15 @@ AvatarManager::AvatarManager(QObject* parent) :
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer"); qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); auto nodeList = DependencyManager::get<NodeList>();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar"); packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar");
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
// when we hear that the user has ignored an avatar by session UUID // when we hear that the user has ignored an avatar by session UUID
// immediately remove that avatar instead of waiting for the absence of packets from avatar mixer // immediately remove that avatar instead of waiting for the absence of packets from avatar mixer
auto usersScriptingInterface = DependencyManager::get<UsersScriptingInterface>(); connect(nodeList.data(), &NodeList::ignoredNode, this, &AvatarManager::removeAvatar);
connect(usersScriptingInterface.data(), &UsersScriptingInterface::ignoredNode, this, &AvatarManager::removeAvatar);
} }
AvatarManager::~AvatarManager() { AvatarManager::~AvatarManager() {

View file

@ -19,7 +19,9 @@
#include "AvatarHashMap.h" #include "AvatarHashMap.h"
AvatarHashMap::AvatarHashMap() { AvatarHashMap::AvatarHashMap() {
connect(DependencyManager::get<NodeList>().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);
} }
QVector<QUuid> AvatarHashMap::getAvatarIdentifiers() { QVector<QUuid> AvatarHashMap::getAvatarIdentifiers() {

View file

@ -19,12 +19,14 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <glm/glm.hpp>
#include <DependencyManager.h> #include <DependencyManager.h>
#include <NLPacket.h> #include <NLPacket.h>
#include <Node.h> #include <Node.h>
#include "AvatarData.h" #include "AvatarData.h"
#include <glm/glm.hpp>
class AvatarHashMap : public QObject, public Dependency { class AvatarHashMap : public QObject, public Dependency {
Q_OBJECT Q_OBJECT

View file

@ -215,6 +215,11 @@ void NodeList::reset() {
_numNoReplyDomainCheckIns = 0; _numNoReplyDomainCheckIns = 0;
// lock and clear our set of ignored IDs
_ignoredSetLock.lockForWrite();
_ignoredNodeIDs.clear();
_ignoredSetLock.unlock();
// refresh the owner UUID to the NULL UUID // refresh the owner UUID to the NULL UUID
setSessionUUID(QUuid()); setSessionUUID(QUuid());
@ -692,3 +697,43 @@ void NodeList::sendKeepAlivePings() {
sendPacket(constructPingPacket(), *node); sendPacket(constructPingPacket(), *node);
}); });
} }
void NodeList::ignoreNodeBySessionID(const QUuid& nodeID) {
// enumerate the nodes to send a reliable ignore packet to each that can leverage it
if (!nodeID.isNull() && _sessionUUID != nodeID) {
eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool {
if (node->getType() == NodeType::AudioMixer || node->getType() == NodeType::AvatarMixer) {
return true;
} else {
return false;
}
}, [&nodeID, this](const SharedNodePointer& destinationNode) {
// create a reliable NLPacket with space for the ignore UUID
auto ignorePacket = NLPacket::create(PacketType::NodeIgnoreRequest, NUM_BYTES_RFC4122_UUID, true);
// write the node ID to the packet
ignorePacket->write(nodeID.toRfc4122());
qDebug() << "Sending packet to ignore node" << uuidStringWithoutCurlyBraces(nodeID);
// send off this ignore packet reliably to the matching node
sendPacket(std::move(ignorePacket), *destinationNode);
});
QReadLocker setLocker { &_ignoredSetLock };
// add this nodeID to our set of ignored IDs
_ignoredNodeIDs.insert(nodeID);
emit ignoredNode(nodeID);
} else {
qWarning() << "UsersScriptingInterface::ignore called with an invalid ID or an ID which matches the current session ID.";
}
}
bool NodeList::isIgnoringNode(const QUuid& nodeID) const {
QReadLocker setLocker { &_ignoredSetLock };
return _ignoredNodeIDs.find(nodeID) != _ignoredNodeIDs.cend();
}

View file

@ -20,6 +20,8 @@
#include <unistd.h> // not on windows, not needed for mac or windows #include <unistd.h> // not on windows, not needed for mac or windows
#endif #endif
#include <tbb/concurrent_unordered_set.h>
#include <QtCore/QElapsedTimer> #include <QtCore/QElapsedTimer>
#include <QtCore/QMutex> #include <QtCore/QMutex>
#include <QtCore/QSet> #include <QtCore/QSet>
@ -68,6 +70,9 @@ public:
void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; } void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
void ignoreNodeBySessionID(const QUuid& nodeID);
bool isIgnoringNode(const QUuid& nodeID) const;
public slots: public slots:
void reset(); void reset();
void sendDomainServerCheckIn(); void sendDomainServerCheckIn();
@ -92,6 +97,8 @@ public slots:
signals: signals:
void limitOfSilentDomainCheckInsReached(); void limitOfSilentDomainCheckInsReached();
void receivedDomainServerList(); void receivedDomainServerList();
void ignoredNode(const QUuid& nodeID);
private slots: private slots:
void stopKeepalivePingTimer(); void stopKeepalivePingTimer();
void sendPendingDSPathQuery(); void sendPendingDSPathQuery();
@ -129,6 +136,9 @@ private:
bool _isShuttingDown { false }; bool _isShuttingDown { false };
QTimer _keepAlivePingTimer; QTimer _keepAlivePingTimer;
mutable QReadWriteLock _ignoredSetLock;
tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDs;
#if (PR_BUILD || DEV_BUILD) #if (PR_BUILD || DEV_BUILD)
bool _shouldSendNewerVersion { false }; bool _shouldSendNewerVersion { false };
#endif #endif

View file

@ -14,34 +14,6 @@
#include <NodeList.h> #include <NodeList.h>
void UsersScriptingInterface::ignore(const QUuid& nodeID) { void UsersScriptingInterface::ignore(const QUuid& nodeID) {
// setup the ignore packet we send to all nodes (that currently handle it) // ask the NodeList to ignore this user (based on the session ID of their node)
// to ignore the data (audio/avatar) for this user DependencyManager::get<NodeList>()->ignoreNodeBySessionID(nodeID);
// enumerate the nodes to send a reliable ignore packet to each that can leverage it
auto nodeList = DependencyManager::get<NodeList>();
if (!nodeID.isNull() && nodeList->getSessionUUID() != nodeID) {
nodeList->eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool {
if (node->getType() == NodeType::AudioMixer || node->getType() == NodeType::AvatarMixer) {
return true;
} else {
return false;
}
}, [&nodeID, &nodeList](const SharedNodePointer& destinationNode) {
// create a reliable NLPacket with space for the ignore UUID
auto ignorePacket = NLPacket::create(PacketType::NodeIgnoreRequest, NUM_BYTES_RFC4122_UUID, true);
// write the node ID to the packet
ignorePacket->write(nodeID.toRfc4122());
qDebug() << "Sending packet to ignore node" << uuidStringWithoutCurlyBraces(nodeID);
// send off this ignore packet reliably to the matching node
nodeList->sendPacket(std::move(ignorePacket), *destinationNode);
});
emit ignoredNode(nodeID);
} else {
qWarning() << "UsersScriptingInterface::ignore called with an invalid ID or an ID which matches the current session ID.";
}
} }

View file

@ -22,8 +22,6 @@ class UsersScriptingInterface : public QObject, public Dependency {
public slots: public slots:
void ignore(const QUuid& nodeID); void ignore(const QUuid& nodeID);
signals:
void ignoredNode(const QUuid& nodeID);
}; };