mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +02:00
change NodeList container to QHash with QSharedPointer
This commit is contained in:
parent
0e25c85eef
commit
7d1a64ca8c
35 changed files with 355 additions and 737 deletions
|
@ -182,15 +182,13 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
|
|||
}
|
||||
|
||||
void AudioMixer::prepareMixForListeningNode(Node* node) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
AvatarAudioRingBuffer* nodeRingBuffer = ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer();
|
||||
|
||||
// zero out the client mix for this node
|
||||
memset(_clientSamples, 0, sizeof(_clientSamples));
|
||||
|
||||
// loop through all other nodes that have sufficient audio to mix
|
||||
for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) {
|
||||
foreach(SharedNodePointer otherNode, NodeList::getInstance()->getNodeHash()) {
|
||||
if (otherNode->getLinkedData()) {
|
||||
|
||||
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
|
||||
|
@ -200,7 +198,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) {
|
|||
PositionalAudioRingBuffer* otherNodeBuffer = otherNodeClientData->getRingBuffers()[i];
|
||||
|
||||
if ((*otherNode != *node
|
||||
|| otherNodeBuffer->shouldLoopbackForNode())
|
||||
|| otherNodeBuffer->shouldLoopbackForNode())
|
||||
&& otherNodeBuffer->willBeAddedToMix()) {
|
||||
addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer);
|
||||
}
|
||||
|
@ -220,10 +218,10 @@ void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSock
|
|||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
Node* matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
SharedNodePointer matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (matchingNode) {
|
||||
nodeList->updateNodeWithData(matchingNode, senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
|
||||
if (!matchingNode->getActiveSocket()) {
|
||||
// we don't have an active socket for this node, but they're talking to us
|
||||
|
@ -264,14 +262,14 @@ void AudioMixer::run() {
|
|||
if (_isFinished) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData()) {
|
||||
((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES);
|
||||
}
|
||||
}
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket() && node->getLinkedData()
|
||||
&& ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) {
|
||||
prepareMixForListeningNode(&(*node));
|
||||
|
@ -284,12 +282,13 @@ void AudioMixer::run() {
|
|||
}
|
||||
|
||||
// push forward the next output pointers for any audio buffers we used
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData()) {
|
||||
((AudioMixerClientData*) node->getLinkedData())->pushBuffersAfterFrameSend();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||
|
||||
if (usecToSleep > 0) {
|
||||
|
|
|
@ -67,7 +67,7 @@ void broadcastAvatarData() {
|
|||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT && node->getActiveSocket()) {
|
||||
|
||||
// reset packet pointers for this node
|
||||
|
@ -76,7 +76,7 @@ void broadcastAvatarData() {
|
|||
|
||||
// this is an AGENT we have received head data from
|
||||
// send back a packet with other active node data to this node
|
||||
for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) {
|
||||
foreach(SharedNodePointer otherNode, nodeList->getNodeHash()) {
|
||||
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) {
|
||||
|
||||
unsigned char* avatarDataEndpoint = addNodeToBroadcastPacket((unsigned char*)&avatarDataBuffer[0],
|
||||
|
@ -109,13 +109,11 @@ void broadcastAvatarData() {
|
|||
|
||||
packetsSent++;
|
||||
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||
|
@ -128,11 +126,11 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
|
|||
NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
// add or update the node in our list
|
||||
Node* avatarNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
SharedNodePointer avatarNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (avatarNode) {
|
||||
// parse positional data from an node
|
||||
nodeList->updateNodeWithData(avatarNode, senderSockAddr,
|
||||
nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr,
|
||||
(unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
} else {
|
||||
break;
|
||||
|
@ -144,7 +142,7 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
|
|||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
// let everyone else know about the update
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getActiveSocket() && node->getUUID() != nodeUUID) {
|
||||
nodeList->getNodeSocket().writeDatagram(dataByteArray,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
|
|
|
@ -77,7 +77,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
// Start the web server.
|
||||
mg_start(&callbacks, NULL, options);
|
||||
|
||||
nodeList->addHook(this);
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||
|
||||
if (!_staticAssignmentFile.exists() || _voxelServerConfig) {
|
||||
|
||||
|
@ -171,10 +171,10 @@ void DomainServer::readAvailableDatagrams() {
|
|||
nodeLocalAddress,
|
||||
nodeUUID)))
|
||||
{
|
||||
Node* checkInNode = nodeList->addOrUpdateNode(nodeUUID,
|
||||
nodeType,
|
||||
nodePublicAddress,
|
||||
nodeLocalAddress);
|
||||
SharedNodePointer checkInNode = nodeList->addOrUpdateNode(nodeUUID,
|
||||
nodeType,
|
||||
nodePublicAddress,
|
||||
nodeLocalAddress);
|
||||
|
||||
if (matchingStaticAssignment) {
|
||||
// this was a newly added node with a matching static assignment
|
||||
|
@ -201,7 +201,7 @@ void DomainServer::readAvailableDatagrams() {
|
|||
|
||||
if (numInterestTypes > 0) {
|
||||
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getUUID() != nodeUUID &&
|
||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||
|
||||
|
@ -318,9 +318,7 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
|||
QJsonObject assignedNodesJSON;
|
||||
|
||||
// enumerate the NodeList to find the assigned nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData()) {
|
||||
// add the node using the UUID as the key
|
||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
|
@ -372,10 +370,10 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
|||
// enumerate the NodeList to find the assigned nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
// add the node using the UUID as the key
|
||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
nodesJSON[uuidString] = jsonObjectForNode(&(*node));
|
||||
nodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||
}
|
||||
|
||||
rootJSON["nodes"] = nodesJSON;
|
||||
|
@ -410,14 +408,14 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
|||
QUuid deleteUUID = QUuid(QString(ri->uri + strlen(URI_NODE) + sizeof('/')));
|
||||
|
||||
if (!deleteUUID.isNull()) {
|
||||
Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
||||
SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
||||
|
||||
if (nodeToKill) {
|
||||
// start with a 200 response
|
||||
mg_printf(connection, "%s", RESPONSE_200);
|
||||
|
||||
// we have a valid UUID and node - kill the node that has this assignment
|
||||
NodeList::getInstance()->killNode(nodeToKill);
|
||||
NodeList::getInstance()->killNodeWithUUID(deleteUUID);
|
||||
|
||||
// successfully processed request
|
||||
return 1;
|
||||
|
@ -494,10 +492,6 @@ void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignme
|
|||
}
|
||||
}
|
||||
|
||||
void DomainServer::nodeAdded(Node* node) {
|
||||
|
||||
}
|
||||
|
||||
void DomainServer::nodeKilled(Node* node) {
|
||||
// if this node has linked data it was from an assignment
|
||||
if (node->getLinkedData()) {
|
||||
|
@ -741,7 +735,7 @@ bool DomainServer::checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePu
|
|||
const QUuid& checkInUUID) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData()
|
||||
&& nodePublicSocket == node->getPublicSocket()
|
||||
&& nodeLocalSocket == node->getLocalSocket()
|
||||
|
@ -773,7 +767,7 @@ void DomainServer::addStaticAssignmentsBackToQueueAfterRestart() {
|
|||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData()) {
|
||||
Assignment* linkedAssignment = (Assignment*) node->getLinkedData();
|
||||
if (linkedAssignment->getUUID() == _staticAssignments[i].getUUID()) {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000;
|
||||
|
||||
class DomainServer : public QCoreApplication, public NodeListHook {
|
||||
class DomainServer : public QCoreApplication {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DomainServer(int argc, char* argv[]);
|
||||
|
@ -31,10 +31,10 @@ public:
|
|||
|
||||
static void setDomainServerInstance(DomainServer* domainServer);
|
||||
|
||||
/// Called by NodeList to inform us that a node has been added.
|
||||
void nodeAdded(Node* node);
|
||||
public slots:
|
||||
/// Called by NodeList to inform us that a node has been killed.
|
||||
void nodeKilled(Node* node);
|
||||
|
||||
private:
|
||||
static int civetwebRequestHandler(struct mg_connection *connection);
|
||||
static void civetwebUploadHandler(struct mg_connection *connection, const char *path);
|
||||
|
|
|
@ -173,9 +173,11 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
connect(audioThread, SIGNAL(started()), &_audio, SLOT(start()));
|
||||
|
||||
audioThread->start();
|
||||
|
||||
nodeList->addHook(&_voxels);
|
||||
nodeList->addHook(this);
|
||||
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||
connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), &_voxels, SLOT(nodeAdded(SharedNodePointer)));
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), &_voxels, SLOT(nodeKilled(SharedNodePointer)));
|
||||
|
||||
nodeList->addDomainListener(this);
|
||||
|
||||
// network receive thread and voxel parsing thread are both controlled by the --nonblocking command line
|
||||
|
@ -263,8 +265,6 @@ Application::~Application() {
|
|||
_audio.thread()->wait();
|
||||
|
||||
storeSizeAndPosition();
|
||||
NodeList::getInstance()->removeHook(&_voxels);
|
||||
NodeList::getInstance()->removeHook(this);
|
||||
NodeList::getInstance()->removeDomainListener(this);
|
||||
|
||||
_sharedVoxelSystem.changeTree(new VoxelTree);
|
||||
|
@ -1441,7 +1441,7 @@ void Application::terminate() {
|
|||
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
|
||||
// record the packet for stats-tracking
|
||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AVATARS).updateValue(dataBytes);
|
||||
Node* avatarMixerNode = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
SharedNodePointer avatarMixerNode = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
if (avatarMixerNode) {
|
||||
avatarMixerNode->recordBytesReceived(dataBytes);
|
||||
}
|
||||
|
@ -1458,7 +1458,7 @@ static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& da
|
|||
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// make sure the node exists
|
||||
Node* node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||
if (!node || !node->getLinkedData()) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1985,16 +1985,16 @@ void Application::updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, cons
|
|||
Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
||||
glm::vec3& eyePosition, QUuid& nodeUUID = DEFAULT_NODE_ID_REF) {
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* avatar = (Avatar*)node->getLinkedData();
|
||||
float distance;
|
||||
|
||||
if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) {
|
||||
// rescale to compensate for head embiggening
|
||||
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) *
|
||||
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
|
||||
|
||||
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
|
||||
|
||||
_lookatIndicatorScale = avatar->getHead().getScale();
|
||||
_lookatOtherPosition = avatar->getHead().getPosition();
|
||||
nodeUUID = avatar->getOwningNode()->getUUID();
|
||||
|
@ -2002,6 +2002,7 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2026,71 +2027,6 @@ void Application::renderLookatIndicator(glm::vec3 pointOfInterest) {
|
|||
renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS);
|
||||
}
|
||||
|
||||
void maybeBeginFollowIndicator(bool& began) {
|
||||
if (!began) {
|
||||
Application::getInstance()->getGlowEffect()->begin();
|
||||
glLineWidth(5);
|
||||
glBegin(GL_LINES);
|
||||
began = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::renderFollowIndicator() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// initialize lazily so that we don't enable the glow effect unnecessarily
|
||||
bool began = false;
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) {
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||
Avatar* leader = NULL;
|
||||
|
||||
if (!avatar->getLeaderUUID().isNull()) {
|
||||
if (avatar->getLeaderUUID() == NodeList::getInstance()->getOwnerUUID()) {
|
||||
leader = &_myAvatar;
|
||||
} else {
|
||||
for (NodeList::iterator it = nodeList->begin(); it != nodeList->end(); ++it) {
|
||||
if(it->getUUID() == avatar->getLeaderUUID()
|
||||
&& it->getType() == NODE_TYPE_AGENT) {
|
||||
leader = (Avatar*) it->getLinkedData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leader != NULL) {
|
||||
maybeBeginFollowIndicator(began);
|
||||
glColor3f(1.f, 0.f, 0.f);
|
||||
glVertex3f((avatar->getHead().getPosition().x + avatar->getPosition().x) / 2.f,
|
||||
(avatar->getHead().getPosition().y + avatar->getPosition().y) / 2.f,
|
||||
(avatar->getHead().getPosition().z + avatar->getPosition().z) / 2.f);
|
||||
glColor3f(0.f, 1.f, 0.f);
|
||||
glVertex3f((leader->getHead().getPosition().x + leader->getPosition().x) / 2.f,
|
||||
(leader->getHead().getPosition().y + leader->getPosition().y) / 2.f,
|
||||
(leader->getHead().getPosition().z + leader->getPosition().z) / 2.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_myAvatar.getLeadingAvatar() != NULL) {
|
||||
maybeBeginFollowIndicator(began);
|
||||
glColor3f(1.f, 0.f, 0.f);
|
||||
glVertex3f((_myAvatar.getHead().getPosition().x + _myAvatar.getPosition().x) / 2.f,
|
||||
(_myAvatar.getHead().getPosition().y + _myAvatar.getPosition().y) / 2.f,
|
||||
(_myAvatar.getHead().getPosition().z + _myAvatar.getPosition().z) / 2.f);
|
||||
glColor3f(0.f, 1.f, 0.f);
|
||||
glVertex3f((_myAvatar.getLeadingAvatar()->getHead().getPosition().x + _myAvatar.getLeadingAvatar()->getPosition().x) / 2.f,
|
||||
(_myAvatar.getLeadingAvatar()->getHead().getPosition().y + _myAvatar.getLeadingAvatar()->getPosition().y) / 2.f,
|
||||
(_myAvatar.getLeadingAvatar()->getHead().getPosition().z + _myAvatar.getLeadingAvatar()->getPosition().z) / 2.f);
|
||||
}
|
||||
|
||||
if (began) {
|
||||
glEnd();
|
||||
_glowEffect.end();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::renderHighlightVoxel(VoxelDetail voxel) {
|
||||
glDisable(GL_LIGHTING);
|
||||
glPushMatrix();
|
||||
|
@ -2108,9 +2044,8 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) {
|
|||
void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) {
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
node->lock();
|
||||
if (node->getLinkedData()) {
|
||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||
|
@ -2739,39 +2674,36 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
|||
|
||||
unsigned char voxelQueryPacket[MAX_PACKET_SIZE];
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
||||
int totalServers = 0;
|
||||
int inViewServers = 0;
|
||||
int unknownJurisdictionServers = 0;
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
||||
totalServers++;
|
||||
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
|
||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||
// can get the jurisdiction...
|
||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||
unknownJurisdictionServers++;
|
||||
} else {
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||
|
||||
|
||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||
inViewServers++;
|
||||
}
|
||||
|
@ -2804,18 +2736,20 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
|||
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
||||
qDebug("perServerPPS: %d perUnknownServer: %d\n", perServerPPS, perUnknownServer);
|
||||
}
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
||||
|
||||
|
||||
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
|
||||
bool inView = false;
|
||||
bool unknownView = false;
|
||||
|
||||
|
||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||
// can get the jurisdiction...
|
||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||
|
@ -2825,15 +2759,15 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
|||
}
|
||||
} else {
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||
inView = true;
|
||||
|
@ -2846,15 +2780,15 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (inView) {
|
||||
_voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS);
|
||||
} else if (unknownView) {
|
||||
if (wantExtraDebugging) {
|
||||
qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
|
||||
<< perUnknownServer << " to send us jurisdiction.\n";
|
||||
<< perUnknownServer << " to send us jurisdiction.\n";
|
||||
}
|
||||
|
||||
|
||||
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
|
||||
// If there's only one server, then don't do this, and just let the normal voxel query pass through
|
||||
// as expected... this way, we will actually get a valid scene if there is one to be seen
|
||||
|
@ -2878,24 +2812,24 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
|||
}
|
||||
// set up the packet for sending...
|
||||
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
||||
|
||||
|
||||
// insert packet type/version and node UUID
|
||||
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
|
||||
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
||||
endOfVoxelQueryPacket += ownerUUID.size();
|
||||
|
||||
|
||||
// encode the query data...
|
||||
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
||||
|
||||
|
||||
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
|
||||
|
||||
|
||||
// make sure we still have an active socket
|
||||
if (node->getActiveSocket()) {
|
||||
nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength,
|
||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||
}
|
||||
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
||||
}
|
||||
|
@ -3252,12 +3186,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... renderFollowIndicator...");
|
||||
renderFollowIndicator();
|
||||
}
|
||||
|
||||
// render transmitter pick ray, if non-empty
|
||||
if (_transmitterPickStart != _transmitterPickEnd) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
|
@ -3384,12 +3312,12 @@ void Application::displayOverlay() {
|
|||
glPointSize(1.0f);
|
||||
char nodes[100];
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
int totalAvatars = 0, totalServers = 0;
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++;
|
||||
}
|
||||
|
||||
sprintf(nodes, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars);
|
||||
drawtext(_glWidget->width() - 150, 20, 0.10, 0, 1.0, 0, nodes, 1, 0, 0);
|
||||
}
|
||||
|
@ -3489,8 +3417,8 @@ void Application::displayStats() {
|
|||
int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0;
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
Node* audioMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
Node* avatarMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
|
||||
pingAudio = audioMixerNode ? audioMixerNode->getPingMs() : 0;
|
||||
pingAvatar = avatarMixerNode ? avatarMixerNode->getPingMs() : 0;
|
||||
|
@ -3499,7 +3427,8 @@ void Application::displayStats() {
|
|||
// Now handle voxel servers, since there could be more than one, we average their ping times
|
||||
unsigned long totalPingVoxel = 0;
|
||||
int voxelServerCount = 0;
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
totalPingVoxel += node->getPingMs();
|
||||
voxelServerCount++;
|
||||
|
@ -3508,6 +3437,7 @@ void Application::displayStats() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (voxelServerCount) {
|
||||
pingVoxel = totalPingVoxel/voxelServerCount;
|
||||
}
|
||||
|
@ -3524,7 +3454,7 @@ void Application::displayStats() {
|
|||
sprintf(avatarStats, "Avatar: pos %.3f, %.3f, %.3f, vel %.1f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, glm::length(_myAvatar.getVelocity()), _myAvatar.getBodyYaw());
|
||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
||||
|
||||
Node* avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
char avatarMixerStats[200];
|
||||
if (avatarMixer) {
|
||||
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
||||
|
@ -3848,10 +3778,10 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
if (!selfAvatarOnly) {
|
||||
// Render avatars of other nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
node->lock();
|
||||
|
||||
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||
if (!avatar->isInitialized()) {
|
||||
|
@ -3860,7 +3790,7 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
avatar->render(false);
|
||||
avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
}
|
||||
|
||||
|
||||
node->unlock();
|
||||
}
|
||||
|
||||
|
@ -4106,18 +4036,6 @@ void Application::eyedropperVoxelUnderCursor() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::toggleFollowMode() {
|
||||
glm::vec3 mouseRayOrigin, mouseRayDirection;
|
||||
_viewFrustum.computePickRay(_pieMenu.getX() / (float)_glWidget->width(),
|
||||
_pieMenu.getY() / (float)_glWidget->height(),
|
||||
mouseRayOrigin, mouseRayDirection);
|
||||
glm::vec3 eyePositionIgnored;
|
||||
QUuid nodeUUIDIgnored;
|
||||
Avatar* leadingAvatar = findLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, eyePositionIgnored, nodeUUIDIgnored);
|
||||
|
||||
_myAvatar.follow(leadingAvatar);
|
||||
}
|
||||
|
||||
void Application::resetSensors() {
|
||||
_headMouseX = _mouseX = _glWidget->width() / 2;
|
||||
_headMouseY = _mouseY = _glWidget->height() / 2;
|
||||
|
@ -4200,11 +4118,7 @@ void Application::domainChanged(QString domain) {
|
|||
updateLocalOctreeCache();
|
||||
}
|
||||
|
||||
void Application::nodeAdded(Node* node) {
|
||||
|
||||
}
|
||||
|
||||
void Application::nodeKilled(Node* node) {
|
||||
void Application::nodeKilled(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
// see if this is the first we've heard of this node...
|
||||
|
@ -4284,7 +4198,7 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m
|
|||
const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
|
||||
|
||||
// Attempt to identify the sender from it's address.
|
||||
Node* serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
if (serverNode) {
|
||||
QUuid nodeUUID = serverNode->getUUID();
|
||||
|
||||
|
@ -4301,7 +4215,7 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m
|
|||
int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) {
|
||||
|
||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||
Node* server = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
SharedNodePointer server = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
||||
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||
// determine which server it belongs to
|
||||
|
|
|
@ -95,7 +95,7 @@ static const float NODE_KILLED_RED = 1.0f;
|
|||
static const float NODE_KILLED_GREEN = 0.0f;
|
||||
static const float NODE_KILLED_BLUE = 0.0f;
|
||||
|
||||
class Application : public QApplication, public NodeListHook, public PacketSenderNotify, public DomainChangeListener {
|
||||
class Application : public QApplication, public PacketSenderNotify, public DomainChangeListener {
|
||||
Q_OBJECT
|
||||
|
||||
friend class VoxelPacketProcessor;
|
||||
|
@ -194,8 +194,7 @@ public:
|
|||
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near,
|
||||
float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
||||
|
||||
virtual void nodeAdded(Node* node);
|
||||
virtual void nodeKilled(Node* node);
|
||||
|
||||
virtual void packetSentNotification(ssize_t length);
|
||||
|
||||
virtual void domainChanged(QString domain);
|
||||
|
@ -214,6 +213,8 @@ public:
|
|||
void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; }
|
||||
|
||||
public slots:
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
||||
void exportVoxels();
|
||||
void importVoxels();
|
||||
|
@ -250,8 +251,6 @@ private slots:
|
|||
|
||||
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
|
||||
|
||||
void toggleFollowMode();
|
||||
|
||||
void closeMirrorView();
|
||||
void restoreMirrorView();
|
||||
void shrinkMirrorView();
|
||||
|
@ -301,7 +300,6 @@ private:
|
|||
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||
|
||||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||
void renderFollowIndicator();
|
||||
void renderHighlightVoxel(VoxelDetail voxel);
|
||||
|
||||
void updateAvatar(float deltaTime);
|
||||
|
|
|
@ -365,9 +365,9 @@ void Audio::handleAudioInput() {
|
|||
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
Node* audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
|
||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer)) {
|
||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
|
||||
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
|
||||
|
||||
glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition();
|
||||
|
|
|
@ -144,14 +144,14 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int
|
|||
Application::getInstance()->getProfile()->setFaceModelURL(QUrl(valueList[i]));
|
||||
} else {
|
||||
// mesh URL for a UUID, find avatar in our list
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||
|
||||
if (avatar->getUUID() == userUUID) {
|
||||
QMetaObject::invokeMethod(&avatar->getHead().getFaceModel(),
|
||||
"setURL", Q_ARG(QUrl, QUrl(valueList[i])));
|
||||
"setURL", Q_ARG(QUrl, QUrl(valueList[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,14 +163,13 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int
|
|||
Application::getInstance()->getProfile()->setSkeletonModelURL(QUrl(valueList[i]));
|
||||
} else {
|
||||
// skeleton URL for a UUID, find avatar in our list
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||
|
||||
if (avatar->getUUID() == userUUID) {
|
||||
QMetaObject::invokeMethod(&avatar->getSkeletonModel(), "setURL",
|
||||
Q_ARG(QUrl, QUrl(valueList[i])));
|
||||
Q_ARG(QUrl, QUrl(valueList[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,6 @@ MetavoxelSystem::MetavoxelSystem() :
|
|||
_buffer(QOpenGLBuffer::VertexBuffer) {
|
||||
}
|
||||
|
||||
MetavoxelSystem::~MetavoxelSystem() {
|
||||
NodeList::getInstance()->removeHook(this);
|
||||
}
|
||||
|
||||
void MetavoxelSystem::init() {
|
||||
if (!_program.isLinked()) {
|
||||
switchToResourcesParentIfRequired();
|
||||
|
@ -39,7 +35,10 @@ void MetavoxelSystem::init() {
|
|||
_pointScaleLocation = _program.uniformLocation("pointScale");
|
||||
}
|
||||
|
||||
NodeList::getInstance()->addHook(this);
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(nodeAdded(SharedNodePointer)));
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||
|
||||
AttributeRegistry::getInstance()->configureScriptEngine(&_scriptEngine);
|
||||
|
||||
|
@ -117,14 +116,14 @@ void MetavoxelSystem::render() {
|
|||
_program.release();
|
||||
}
|
||||
|
||||
void MetavoxelSystem::nodeAdded(Node* node) {
|
||||
void MetavoxelSystem::nodeAdded(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
||||
QMetaObject::invokeMethod(this, "addClient", Q_ARG(const QUuid&, node->getUUID()),
|
||||
Q_ARG(const HifiSockAddr&, node->getLocalSocket()));
|
||||
}
|
||||
}
|
||||
|
||||
void MetavoxelSystem::nodeKilled(Node* node) {
|
||||
void MetavoxelSystem::nodeKilled(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
||||
QMetaObject::invokeMethod(this, "removeClient", Q_ARG(const QUuid&, node->getUUID()));
|
||||
}
|
||||
|
|
|
@ -26,13 +26,11 @@
|
|||
class MetavoxelClient;
|
||||
|
||||
/// Renders a metavoxel tree.
|
||||
class MetavoxelSystem : public QObject, public NodeListHook {
|
||||
class MetavoxelSystem : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
MetavoxelSystem();
|
||||
~MetavoxelSystem();
|
||||
|
||||
void init();
|
||||
|
||||
|
@ -41,9 +39,9 @@ public:
|
|||
void simulate(float deltaTime);
|
||||
void render();
|
||||
|
||||
virtual void nodeAdded(Node* node);
|
||||
virtual void nodeKilled(Node* node);
|
||||
|
||||
public slots:
|
||||
void nodeAdded(SharedNodePointer node);
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
private:
|
||||
|
||||
Q_INVOKABLE void addClient(const QUuid& uuid, const HifiSockAddr& address);
|
||||
|
|
|
@ -57,12 +57,13 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
|
|||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
app->trackIncomingVoxelPacket(packetData, messageLength, senderSockAddr, wasStatsPacket);
|
||||
|
||||
Node* serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
if (serverNode && serverNode->getActiveSocket() && *serverNode->getActiveSocket() == senderSockAddr) {
|
||||
|
||||
switch(packetData[0]) {
|
||||
case PACKET_TYPE_PARTICLE_DATA: {
|
||||
app->_particles.processDatagram(QByteArray((char*) packetData, messageLength), senderSockAddr, serverNode);
|
||||
app->_particles.processDatagram(QByteArray((char*) packetData, messageLength),
|
||||
senderSockAddr, serverNode.data());
|
||||
} break;
|
||||
|
||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||
|
|
|
@ -1604,13 +1604,13 @@ void VoxelSystem::falseColorizeBySource() {
|
|||
};
|
||||
|
||||
// create a bunch of colors we'll use during colorization
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
uint16_t nodeID = VoxelTreeElement::getSourceNodeUUIDKey(node->getUUID());
|
||||
int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS;
|
||||
args.colors[nodeID] = groupColors[groupColor];
|
||||
|
||||
|
||||
if (groupColors[groupColor].red > 0) {
|
||||
groupColors[groupColor].red = ((groupColors[groupColor].red - MIN_COLOR)/2) + MIN_COLOR;
|
||||
}
|
||||
|
@ -1620,7 +1620,7 @@ void VoxelSystem::falseColorizeBySource() {
|
|||
if (groupColors[groupColor].blue > 0) {
|
||||
groupColors[groupColor].blue = ((groupColors[groupColor].blue - MIN_COLOR)/2) + MIN_COLOR;
|
||||
}
|
||||
|
||||
|
||||
voxelServerCount++;
|
||||
}
|
||||
}
|
||||
|
@ -2683,7 +2683,7 @@ void VoxelSystem::falseColorizeOccludedV2() {
|
|||
setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
void VoxelSystem::nodeAdded(Node* node) {
|
||||
void VoxelSystem::nodeAdded(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
qDebug("VoxelSystem... voxel server %s added...\n", node->getUUID().toString().toLocal8Bit().constData());
|
||||
_voxelServerCount++;
|
||||
|
@ -2704,7 +2704,7 @@ bool VoxelSystem::killSourceVoxelsOperation(OctreeElement* element, void* extraD
|
|||
return true;
|
||||
}
|
||||
|
||||
void VoxelSystem::nodeKilled(Node* node) {
|
||||
void VoxelSystem::nodeKilled(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
_voxelServerCount--;
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
|
|
@ -37,8 +37,7 @@ struct VoxelShaderVBOData
|
|||
};
|
||||
|
||||
|
||||
class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook,
|
||||
public NodeListHook {
|
||||
class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook {
|
||||
Q_OBJECT
|
||||
|
||||
friend class VoxelHideShowThread;
|
||||
|
@ -112,8 +111,6 @@ public:
|
|||
|
||||
virtual void elementDeleted(OctreeElement* element);
|
||||
virtual void elementUpdated(OctreeElement* element);
|
||||
virtual void nodeAdded(Node* node);
|
||||
virtual void nodeKilled(Node* node);
|
||||
|
||||
bool treeIsBusy() const { return _treeIsBusy; }
|
||||
|
||||
|
@ -124,6 +121,9 @@ signals:
|
|||
void importProgress(int progress);
|
||||
|
||||
public slots:
|
||||
void nodeAdded(SharedNodePointer node);
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
void collectStatsForTreesAndVBOs();
|
||||
|
||||
// Methods that recurse tree
|
||||
|
|
|
@ -95,7 +95,6 @@ Avatar::Avatar(Node* owningNode) :
|
|||
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
|
||||
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||
_isCollisionsOn(true),
|
||||
_leadingAvatar(NULL),
|
||||
_moving(false),
|
||||
_initialized(false),
|
||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||
|
@ -146,27 +145,7 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
|
|||
return computeRotationFromBodyToWorldUp() * getOrientation();
|
||||
}
|
||||
|
||||
void Avatar::follow(Avatar* leadingAvatar) {
|
||||
const float MAX_STRING_LENGTH = 2;
|
||||
|
||||
_leadingAvatar = leadingAvatar;
|
||||
if (_leadingAvatar != NULL) {
|
||||
_leaderUUID = leadingAvatar->getOwningNode()->getUUID();
|
||||
_stringLength = glm::length(_position - _leadingAvatar->getPosition()) / _scale;
|
||||
if (_stringLength > MAX_STRING_LENGTH) {
|
||||
_stringLength = MAX_STRING_LENGTH;
|
||||
}
|
||||
} else {
|
||||
_leaderUUID = QUuid();
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||
|
||||
if (_leadingAvatar && !_leadingAvatar->getOwningNode()->isAlive()) {
|
||||
follow(NULL);
|
||||
}
|
||||
|
||||
if (_scale != _newScale) {
|
||||
setScale(_newScale);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,6 @@ public:
|
|||
|
||||
void init();
|
||||
void simulate(float deltaTime, Transmitter* transmitter);
|
||||
void follow(Avatar* leadingAvatar);
|
||||
void render(bool forceRenderHead);
|
||||
|
||||
//setters
|
||||
|
@ -217,7 +216,6 @@ protected:
|
|||
glm::vec3 _mouseRayOrigin;
|
||||
glm::vec3 _mouseRayDirection;
|
||||
bool _isCollisionsOn;
|
||||
Avatar* _leadingAvatar;
|
||||
float _stringLength;
|
||||
|
||||
bool _moving; ///< set when position is changing
|
||||
|
|
|
@ -368,8 +368,7 @@ void Hand::updateCollisions() {
|
|||
glm::vec3 totalPenetration;
|
||||
|
||||
// check other avatars
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* otherAvatar = (Avatar*)node->getLinkedData();
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||
|
@ -388,21 +387,21 @@ void Hand::updateCollisions() {
|
|||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||
palm.setIsCollidingWithPalm(true);
|
||||
if (!wasColliding) {
|
||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||
PALM_COLLIDE_FREQUENCY,
|
||||
PALM_COLLIDE_DURATION_MAX,
|
||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||
PALM_COLLIDE_FREQUENCY,
|
||||
PALM_COLLIDE_DURATION_MAX,
|
||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||
// add slapback here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,15 +87,6 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
_elapsedTimeMoving += deltaTime;
|
||||
}
|
||||
|
||||
if (_leadingAvatar && !_leadingAvatar->getOwningNode()->isAlive()) {
|
||||
follow(NULL);
|
||||
}
|
||||
|
||||
// Ajust, scale, position and lookAt position when following an other avatar
|
||||
if (_leadingAvatar && _newScale != _leadingAvatar->getScale()) {
|
||||
_newScale = _leadingAvatar->getScale();
|
||||
}
|
||||
|
||||
if (_scale != _newScale) {
|
||||
float scale = (1.f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _newScale;
|
||||
setScale(scale);
|
||||
|
@ -327,9 +318,7 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
|||
estimatedRotation = webcam->getEstimatedRotation();
|
||||
|
||||
} else {
|
||||
if (!_leadingAvatar) {
|
||||
_head.setPitch(_head.getMousePitch());
|
||||
}
|
||||
_head.setPitch(_head.getMousePitch());
|
||||
_head.getVideoFace().clearFrame();
|
||||
|
||||
// restore rotation, lean to neutral positions
|
||||
|
@ -634,47 +623,6 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
|||
_shouldJump = false;
|
||||
}
|
||||
|
||||
|
||||
// Add thrusts from leading avatar
|
||||
const float FOLLOWING_RATE = 0.02f;
|
||||
const float MIN_YAW = 5.0f;
|
||||
const float MIN_PITCH = 1.0f;
|
||||
const float PITCH_RATE = 0.1f;
|
||||
const float MIN_YAW_BEFORE_PITCH = 30.0f;
|
||||
|
||||
if (_leadingAvatar != NULL) {
|
||||
glm::vec3 toTarget = _leadingAvatar->getPosition() - _position;
|
||||
|
||||
if (glm::length(_position - _leadingAvatar->getPosition()) > _scale * _stringLength) {
|
||||
_position += toTarget * FOLLOWING_RATE;
|
||||
} else {
|
||||
toTarget = _leadingAvatar->getHead().getLookAtPosition() - _head.getPosition();
|
||||
}
|
||||
toTarget = glm::vec3(glm::dot(right, toTarget),
|
||||
glm::dot(up , toTarget),
|
||||
glm::dot(front, toTarget));
|
||||
|
||||
float yawAngle = angleBetween(-IDENTITY_FRONT, glm::vec3(toTarget.x, 0.f, toTarget.z));
|
||||
if (glm::abs(yawAngle) > MIN_YAW){
|
||||
if (IDENTITY_RIGHT.x * toTarget.x + IDENTITY_RIGHT.y * toTarget.y + IDENTITY_RIGHT.z * toTarget.z > 0) {
|
||||
_bodyYawDelta -= yawAngle;
|
||||
} else {
|
||||
_bodyYawDelta += yawAngle;
|
||||
}
|
||||
}
|
||||
|
||||
float pitchAngle = glm::abs(90.0f - angleBetween(IDENTITY_UP, toTarget));
|
||||
if (glm::abs(pitchAngle) > MIN_PITCH && yawAngle < MIN_YAW_BEFORE_PITCH){
|
||||
if (IDENTITY_UP.x * toTarget.x + IDENTITY_UP.y * toTarget.y + IDENTITY_UP.z * toTarget.z > 0) {
|
||||
_head.setMousePitch(_head.getMousePitch() + PITCH_RATE * pitchAngle);
|
||||
} else {
|
||||
_head.setMousePitch(_head.getMousePitch() - PITCH_RATE * pitchAngle);
|
||||
}
|
||||
_head.setPitch(_head.getMousePitch());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add thrusts from Transmitter
|
||||
if (transmitter) {
|
||||
transmitter->checkForLostTransmitter();
|
||||
|
@ -873,15 +821,7 @@ void MyAvatar::updateAvatarCollisions(float deltaTime) {
|
|||
// Reset detector for nearest avatar
|
||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||
|
||||
// loop through all the other avatars for potential interactions...
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||
//Avatar *otherAvatar = (Avatar *)node->getLinkedData();
|
||||
//
|
||||
// Placeholder: Add code here when we want to add Avatar<->Avatar collision stuff
|
||||
}
|
||||
}
|
||||
// loop through all the other avatars for potential interactions
|
||||
}
|
||||
|
||||
class SortedAvatar {
|
||||
|
@ -902,10 +842,10 @@ void MyAvatar::updateChatCircle(float deltaTime) {
|
|||
|
||||
// find all circle-enabled members and sort by distance
|
||||
QVector<SortedAvatar> sortedAvatars;
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||
SortedAvatar sortedAvatar;
|
||||
SortedAvatar sortedAvatar;
|
||||
sortedAvatar.avatar = (Avatar*)node->getLinkedData();
|
||||
if (!sortedAvatar.avatar->isChatCirclingEnabled()) {
|
||||
continue;
|
||||
|
@ -914,6 +854,7 @@ void MyAvatar::updateChatCircle(float deltaTime) {
|
|||
sortedAvatars.append(sortedAvatar);
|
||||
}
|
||||
}
|
||||
|
||||
qSort(sortedAvatars.begin(), sortedAvatars.end());
|
||||
|
||||
// compute the accumulated centers
|
||||
|
|
|
@ -51,7 +51,6 @@ public:
|
|||
float getAbsoluteHeadYaw() const;
|
||||
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
|
||||
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
|
||||
Avatar* getLeadingAvatar() const { return _leadingAvatar; }
|
||||
glm::vec3 getGravity() const { return _gravity; }
|
||||
glm::vec3 getUprightHeadPosition() const;
|
||||
glm::vec3 getEyeLevelPosition() const;
|
||||
|
|
|
@ -241,9 +241,10 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
NodeToJurisdictionMap& serverJurisdictions) {
|
||||
|
||||
QLocale locale(QLocale::English);
|
||||
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
||||
if (node->getType() == serverType) {
|
||||
serverCount++;
|
||||
|
@ -261,7 +262,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
std::stringstream serverDetails("");
|
||||
std::stringstream extraDetails("");
|
||||
std::stringstream linkDetails("");
|
||||
|
||||
|
||||
if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
|
||||
serverDetails << "active ";
|
||||
} else {
|
||||
|
@ -270,29 +271,29 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// missing at least one jurisdiction
|
||||
if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) {
|
||||
serverDetails << " unknown jurisdiction ";
|
||||
} else {
|
||||
const JurisdictionMap& map = serverJurisdictions[nodeUUID];
|
||||
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
|
||||
|
||||
if (rootCode) {
|
||||
QString rootCodeHex = octalCodeToHexString(rootCode);
|
||||
|
||||
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
serverDetails << " jurisdiction: "
|
||||
<< rootCodeHex.toLocal8Bit().constData()
|
||||
<< " ["
|
||||
<< rootDetails.x << ", "
|
||||
<< rootDetails.y << ", "
|
||||
<< rootDetails.z << ": "
|
||||
<< rootDetails.s << "] ";
|
||||
serverDetails << " jurisdiction: "
|
||||
<< rootCodeHex.toLocal8Bit().constData()
|
||||
<< " ["
|
||||
<< rootDetails.x << ", "
|
||||
<< rootDetails.y << ", "
|
||||
<< rootDetails.z << ": "
|
||||
<< rootDetails.s << "] ";
|
||||
} else {
|
||||
serverDetails << " jurisdiction has no rootCode";
|
||||
} // root code
|
||||
|
@ -304,7 +305,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats();
|
||||
if (sceneStats->find(nodeUUID) != sceneStats->end()) {
|
||||
VoxelSceneStats& stats = sceneStats->at(nodeUUID);
|
||||
|
||||
|
||||
switch (_extraServerDetails[serverCount-1]) {
|
||||
case MOST: {
|
||||
extraDetails << "<br/>" ;
|
||||
|
@ -312,14 +313,14 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
const unsigned long USECS_PER_MSEC = 1000;
|
||||
float lastFullEncode = stats.getLastFullTotalEncodeTime() / USECS_PER_MSEC;
|
||||
float lastFullSend = stats.getLastFullElapsedTime() / USECS_PER_MSEC;
|
||||
|
||||
|
||||
QString lastFullEncodeString = locale.toString(lastFullEncode);
|
||||
QString lastFullSendString = locale.toString(lastFullSend);
|
||||
|
||||
extraDetails << "<br/>" << "Last Full Scene... " <<
|
||||
"Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " <<
|
||||
"Send Time: " << lastFullSendString.toLocal8Bit().constData() << " ms ";
|
||||
|
||||
|
||||
extraDetails << "<br/>" << "Last Full Scene... " <<
|
||||
"Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " <<
|
||||
"Send Time: " << lastFullSendString.toLocal8Bit().constData() << " ms ";
|
||||
|
||||
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
|
||||
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
|
||||
VoxelSceneStats::ItemInfo& itemInfo = stats.getItemInfo(item);
|
||||
|
@ -330,44 +331,44 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
QString totalString = locale.toString((uint)stats.getTotalElements());
|
||||
QString internalString = locale.toString((uint)stats.getTotalInternal());
|
||||
QString leavesString = locale.toString((uint)stats.getTotalLeaves());
|
||||
|
||||
|
||||
serverDetails << "<br/>" << "Node UUID: " <<
|
||||
nodeUUID.toString().toLocal8Bit().constData() << " ";
|
||||
|
||||
nodeUUID.toString().toLocal8Bit().constData() << " ";
|
||||
|
||||
serverDetails << "<br/>" << "Voxels: " <<
|
||||
totalString.toLocal8Bit().constData() << " total " <<
|
||||
internalString.toLocal8Bit().constData() << " internal " <<
|
||||
leavesString.toLocal8Bit().constData() << " leaves ";
|
||||
|
||||
totalString.toLocal8Bit().constData() << " total " <<
|
||||
internalString.toLocal8Bit().constData() << " internal " <<
|
||||
leavesString.toLocal8Bit().constData() << " leaves ";
|
||||
|
||||
QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets());
|
||||
QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes());
|
||||
QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes());
|
||||
QString incomingOutOfOrderString = locale.toString((uint)stats.getIncomingOutOfOrder());
|
||||
QString incomingLikelyLostString = locale.toString((uint)stats.getIncomingLikelyLost());
|
||||
|
||||
|
||||
int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC;
|
||||
QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage());
|
||||
QString incomingPingTimeString = locale.toString(node->getPingMs());
|
||||
QString incomingClockSkewString = locale.toString(clockSkewInMS);
|
||||
|
||||
|
||||
serverDetails << "<br/>" << "Incoming Packets: " <<
|
||||
incomingPacketsString.toLocal8Bit().constData() <<
|
||||
" Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() <<
|
||||
" Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData();
|
||||
|
||||
incomingPacketsString.toLocal8Bit().constData() <<
|
||||
" Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() <<
|
||||
" Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData();
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
" Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs";
|
||||
|
||||
serverDetails << "<br/>" << "Incoming" <<
|
||||
" Bytes: " << incomingBytesString.toLocal8Bit().constData() <<
|
||||
" Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData();
|
||||
|
||||
" Bytes: " << incomingBytesString.toLocal8Bit().constData() <<
|
||||
" Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData();
|
||||
|
||||
serverDetails << extraDetails.str();
|
||||
if (_extraServerDetails[serverCount-1] == MORE) {
|
||||
linkDetails << " " << " [<a href='most-" << serverCount << "'>most...</a>]";
|
||||
|
@ -376,7 +377,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
linkDetails << " " << " [<a href='more-" << serverCount << "'>less...</a>]";
|
||||
linkDetails << " " << " [<a href='less-" << serverCount << "'>least...</a>]";
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case LESS: {
|
||||
// nothing
|
||||
|
@ -391,7 +392,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
serverDetails << linkDetails.str();
|
||||
_labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str());
|
||||
} // is VOXEL_SERVER
|
||||
} // Node Loop
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelStatsDialog::reject() {
|
||||
|
|
|
@ -103,9 +103,9 @@ void AudioInjector::injectAudio() {
|
|||
|
||||
|
||||
// grab our audio mixer from the NodeList, if it exists
|
||||
Node* audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
|
||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer)) {
|
||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
|
||||
// send off this audio packet
|
||||
nodeList->getNodeSocket().writeDatagram((char*) injectedAudioPacket,
|
||||
(currentPacketPosition - injectedAudioPacket) + bytesToCopy,
|
||||
|
|
|
@ -30,7 +30,6 @@ AvatarData::AvatarData(Node* owningNode) :
|
|||
_bodyPitch(0.0),
|
||||
_bodyRoll(0.0),
|
||||
_newScale(1.0f),
|
||||
_leaderUUID(),
|
||||
_handState(0),
|
||||
_keyState(NO_KEY_DOWN),
|
||||
_isChatCirclingEnabled(false),
|
||||
|
@ -77,10 +76,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
|
||||
// Body scale
|
||||
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _newScale);
|
||||
|
||||
// Follow mode info
|
||||
memcpy(destinationBuffer, _leaderUUID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
||||
destinationBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw);
|
||||
|
@ -200,10 +195,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
// Body scale
|
||||
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _newScale);
|
||||
|
||||
// Follow mode info
|
||||
_leaderUUID = QUuid::fromRfc4122(QByteArray((char*) sourceBuffer, NUM_BYTES_RFC4122_UUID));
|
||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
float headYaw, headPitch, headRoll;
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
||||
|
|
|
@ -100,8 +100,6 @@ public:
|
|||
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
|
||||
|
||||
bool isChatCirclingEnabled() const { return _isChatCirclingEnabled; }
|
||||
|
||||
const QUuid& getLeaderUUID() const { return _leaderUUID; }
|
||||
|
||||
const HeadData* getHeadData() const { return _headData; }
|
||||
const HandData* getHandData() const { return _handData; }
|
||||
|
@ -134,9 +132,6 @@ protected:
|
|||
// Body scale
|
||||
float _newScale;
|
||||
|
||||
// Following mode infos
|
||||
QUuid _leaderUUID;
|
||||
|
||||
// Hand state (are we grabbing something or not)
|
||||
char _handState;
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
|||
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
|
||||
_receivedPacketCount++;
|
||||
|
||||
Node* senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
SharedNodePointer senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
||||
unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
||||
uint64_t sentAt = (*((uint64_t*)(packetData + numBytesPacketHeader + sizeof(sequence))));
|
||||
|
@ -87,7 +87,9 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
|||
_myServer->getOctree()->lockForWrite();
|
||||
uint64_t startProcess = usecTimestampNow();
|
||||
int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType,
|
||||
packetData, packetLength, editData, maxSize, senderNode);
|
||||
packetData,
|
||||
packetLength,
|
||||
editData, maxSize, senderNode.data());
|
||||
_myServer->getOctree()->unlock();
|
||||
uint64_t endProcess = usecTimestampNow();
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ bool OctreeSendThread::process() {
|
|||
|
||||
// don't do any send processing until the initial load of the octree is complete...
|
||||
if (_myServer->isInitialLoadComplete()) {
|
||||
Node* node = NodeList::getInstance()->nodeWithUUID(_nodeUUID);
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(_nodeUUID);
|
||||
|
||||
if (node) {
|
||||
// make sure the node list doesn't kill our node while we're using it
|
||||
|
@ -48,7 +48,7 @@ bool OctreeSendThread::process() {
|
|||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||
printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged));
|
||||
}
|
||||
packetsSent = packetDistributor(node, nodeData, viewFrustumChanged);
|
||||
packetsSent = packetDistributor(node.data(), nodeData, viewFrustumChanged);
|
||||
}
|
||||
|
||||
node->unlock(); // we're done with this node for now.
|
||||
|
|
|
@ -27,11 +27,7 @@ void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeServer::nodeAdded(Node* node) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void OctreeServer::nodeKilled(Node* node) {
|
||||
void OctreeServer::nodeKilled(SharedNodePointer node) {
|
||||
// Use this to cleanup our node
|
||||
if (node->getType() == NODE_TYPE_AGENT) {
|
||||
OctreeQueryNode* nodeData = (OctreeQueryNode*)node->getLinkedData();
|
||||
|
@ -90,9 +86,6 @@ OctreeServer::~OctreeServer() {
|
|||
_persistThread->terminate();
|
||||
delete _persistThread;
|
||||
}
|
||||
|
||||
// tell our NodeList we're done with notifications
|
||||
NodeList::getInstance()->removeHook(this);
|
||||
|
||||
delete _jurisdiction;
|
||||
_jurisdiction = NULL;
|
||||
|
@ -524,10 +517,10 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo
|
|||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesPacketHeader,
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
Node* node = nodeList->nodeWithUUID(nodeUUID);
|
||||
SharedNodePointer node = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (node) {
|
||||
nodeList->updateNodeWithData(node, senderSockAddr, (unsigned char *) dataByteArray.data(),
|
||||
nodeList->updateNodeWithData(node.data(), senderSockAddr, (unsigned char *) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
if (!node->getActiveSocket()) {
|
||||
// we don't have an active socket for this node, but they're talking to us
|
||||
|
@ -612,7 +605,7 @@ void OctreeServer::run() {
|
|||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
// tell our NodeList about our desire to get notifications
|
||||
nodeList->addHook(this);
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||
nodeList->linkedDataCreateCallback = &OctreeServer::attachQueryNodeToNode;
|
||||
|
||||
srand((unsigned)time(0));
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "OctreeInboundPacketProcessor.h"
|
||||
|
||||
/// Handles assignments of type OctreeServer - sending octrees to various clients.
|
||||
class OctreeServer : public ThreadedAssignment, public NodeListHook {
|
||||
class OctreeServer : public ThreadedAssignment {
|
||||
public:
|
||||
OctreeServer(const unsigned char* dataBuffer, int numBytes);
|
||||
~OctreeServer();
|
||||
|
@ -60,15 +60,13 @@ public:
|
|||
virtual int sendSpecialPacket(Node* node) { return 0; }
|
||||
|
||||
static void attachQueryNodeToNode(Node* newNode);
|
||||
|
||||
// NodeListHook
|
||||
virtual void nodeAdded(Node* node);
|
||||
virtual void nodeKilled(Node* node);
|
||||
|
||||
|
||||
public slots:
|
||||
/// runs the voxel server assignment
|
||||
void run();
|
||||
void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
|
||||
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
protected:
|
||||
int _argc;
|
||||
|
|
|
@ -15,29 +15,20 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include "JurisdictionListener.h"
|
||||
|
||||
|
||||
JurisdictionListener::JurisdictionListener(NODE_TYPE type, PacketSenderNotify* notify) :
|
||||
PacketSender(notify, JurisdictionListener::DEFAULT_PACKETS_PER_SECOND)
|
||||
{
|
||||
_nodeType = type;
|
||||
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
nodeList->addHook(this);
|
||||
|
||||
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||
|
||||
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)\n", type);
|
||||
|
||||
}
|
||||
|
||||
JurisdictionListener::~JurisdictionListener() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
nodeList->removeHook(this);
|
||||
}
|
||||
|
||||
void JurisdictionListener::nodeAdded(Node* node) {
|
||||
// nothing to do. But need to implement it.
|
||||
}
|
||||
|
||||
void JurisdictionListener::nodeKilled(Node* node) {
|
||||
void JurisdictionListener::nodeKilled(SharedNodePointer node) {
|
||||
if (_jurisdictions.find(node->getUUID()) != _jurisdictions.end()) {
|
||||
_jurisdictions.erase(_jurisdictions.find(node->getUUID()));
|
||||
}
|
||||
|
@ -52,8 +43,9 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
int nodeCount = 0;
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (nodeList->getNodeActiveSocketOrPing(&(*node)) &&
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
if (nodeList->getNodeActiveSocketOrPing(&(*node)) &&
|
||||
node->getType() == getNodeType()) {
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
PacketSender::queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
||||
|
@ -73,7 +65,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
|
||||
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (node) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
JurisdictionMap map;
|
||||
|
|
|
@ -15,32 +15,32 @@
|
|||
#include <PacketSender.h>
|
||||
#include <ReceivedPacketProcessor.h>
|
||||
|
||||
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
/// Sends out PACKET_TYPE_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
|
||||
/// the PACKET_TYPE_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
|
||||
/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class JurisdictionListener : public NodeListHook, public PacketSender, public ReceivedPacketProcessor {
|
||||
class JurisdictionListener : public PacketSender, public ReceivedPacketProcessor {
|
||||
public:
|
||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||
static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps
|
||||
|
||||
JurisdictionListener(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER, PacketSenderNotify* notify = NULL);
|
||||
~JurisdictionListener();
|
||||
|
||||
virtual bool process();
|
||||
|
||||
NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; };
|
||||
|
||||
/// Called by NodeList to inform us that a node has been added.
|
||||
void nodeAdded(Node* node);
|
||||
/// Called by NodeList to inform us that a node has been killed.
|
||||
void nodeKilled(Node* node);
|
||||
|
||||
NODE_TYPE getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NODE_TYPE type) { _nodeType = type; }
|
||||
|
||||
public slots:
|
||||
/// Called by NodeList to inform us that a node has been killed.
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
protected:
|
||||
/// Callback for processing of received packets. Will process any queued PACKET_TYPE_JURISDICTION and update the
|
||||
/// jurisdiction map member variable
|
||||
|
|
|
@ -32,7 +32,7 @@ JurisdictionSender::~JurisdictionSender() {
|
|||
|
||||
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
if (packetData[0] == PACKET_TYPE_JURISDICTION_REQUEST) {
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (node) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
lockRequestingNodes();
|
||||
|
@ -64,7 +64,7 @@ bool JurisdictionSender::process() {
|
|||
|
||||
QUuid nodeUUID = _nodesRequestingJurisdictions.front();
|
||||
_nodesRequestingJurisdictions.pop();
|
||||
Node* node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (node->getActiveSocket() != NULL) {
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class JurisdictionSender : public PacketSender, public ReceivedPacketProcessor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||
|
||||
|
|
|
@ -57,14 +57,15 @@ bool OctreeEditPacketSender::serversExist() const {
|
|||
bool hasServers = false;
|
||||
bool atLeastOnJurisdictionMissing = false; // assume the best
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
// only send to the NodeTypes that are getMyNodeType()
|
||||
if (node->getType() == getMyNodeType()) {
|
||||
if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
// If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server
|
||||
if (_serverJurisdictions) {
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// missing at least one jurisdiction
|
||||
if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) {
|
||||
atLeastOnJurisdictionMissing = true;
|
||||
|
@ -77,6 +78,7 @@ bool OctreeEditPacketSender::serversExist() const {
|
|||
break; // no point in looking further...
|
||||
}
|
||||
}
|
||||
|
||||
return (hasServers && !atLeastOnJurisdictionMissing);
|
||||
}
|
||||
|
||||
|
@ -84,7 +86,8 @@ bool OctreeEditPacketSender::serversExist() const {
|
|||
// a known nodeID.
|
||||
void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer, ssize_t length) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, nodeList->getNodeHash()) {
|
||||
// only send to the NodeTypes that are getMyNodeType()
|
||||
if (node->getType() == getMyNodeType() &&
|
||||
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
|
||||
|
@ -100,11 +103,11 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
|
|||
uint64_t createdAt = (*((uint64_t*)(buffer + numBytesPacketHeader + sizeof(sequence))));
|
||||
uint64_t queuedAt = usecTimestampNow();
|
||||
uint64_t transitTime = queuedAt - createdAt;
|
||||
qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
|
||||
" - command to node bytes=" << length <<
|
||||
" sequence=" << sequence <<
|
||||
" transitTimeSoFar=" << transitTime << " usecs\n";
|
||||
}
|
||||
qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
|
||||
" - command to node bytes=" << length <<
|
||||
" sequence=" << sequence <<
|
||||
" transitTimeSoFar=" << transitTime << " usecs\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,13 +169,13 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
|
|||
// But we can't really do that with a packed message, since each edit message could be destined
|
||||
// for a different server... So we need to actually manage multiple queued packets... one
|
||||
// for each server
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
// only send to the NodeTypes that are getMyNodeType()
|
||||
if (node->getActiveSocket() != NULL && node->getType() == getMyNodeType()) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
bool isMyJurisdiction = true;
|
||||
// we need to get the jurisdiction for this
|
||||
// we need to get the jurisdiction for this
|
||||
// here we need to get the "pending packet" for this server
|
||||
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
||||
isMyJurisdiction = (map.isMyJurisdiction(octCode, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
|
||||
|
@ -212,15 +215,15 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned c
|
|||
// But we can't really do that with a packed message, since each edit message could be destined
|
||||
// for a different server... So we need to actually manage multiple queued packets... one
|
||||
// for each server
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
// only send to the NodeTypes that are getMyNodeType()
|
||||
if (node->getActiveSocket() != NULL && node->getType() == getMyNodeType()) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
bool isMyJurisdiction = true;
|
||||
|
||||
|
||||
if (_serverJurisdictions) {
|
||||
// we need to get the jurisdiction for this
|
||||
// we need to get the jurisdiction for this
|
||||
// here we need to get the "pending packet" for this server
|
||||
if ((*_serverJurisdictions).find(nodeUUID) != (*_serverJurisdictions).end()) {
|
||||
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
||||
|
@ -232,19 +235,19 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned c
|
|||
if (isMyJurisdiction) {
|
||||
EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID];
|
||||
packetBuffer._nodeUUID = nodeUUID;
|
||||
|
||||
|
||||
// If we're switching type, then we send the last one and start over
|
||||
if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) ||
|
||||
if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) ||
|
||||
(packetBuffer._currentSize + length >= _maxPacketSize)) {
|
||||
releaseQueuedPacket(packetBuffer);
|
||||
initializePacket(packetBuffer, type);
|
||||
}
|
||||
|
||||
|
||||
// If the buffer is empty and not correctly initialized for our type...
|
||||
if (type != packetBuffer._currentType && packetBuffer._currentSize == 0) {
|
||||
initializePacket(packetBuffer, type);
|
||||
}
|
||||
|
||||
|
||||
// This is really the first time we know which server/node this particular edit message
|
||||
// is going to, so we couldn't adjust for clock skew till now. But here's our chance.
|
||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||
|
@ -252,7 +255,7 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned c
|
|||
if (node->getClockSkewUsec() != 0) {
|
||||
adjustEditPacketForClockSkew(codeColorBuffer, length, node->getClockSkewUsec());
|
||||
}
|
||||
|
||||
|
||||
memcpy(&packetBuffer._currentBuffer[packetBuffer._currentSize], codeColorBuffer, length);
|
||||
packetBuffer._currentSize += length;
|
||||
}
|
||||
|
|
|
@ -187,22 +187,22 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
|||
}
|
||||
|
||||
// loop through all the other avatars for potential interactions...
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, NodeList::getInstance()->getNodeHash()) {
|
||||
//qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n";
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||
// TODO: dot collidingPalm and hand velocities and skip collision when they are moving apart.
|
||||
AvatarData* avatar = static_cast<AvatarData*>(node->getLinkedData());
|
||||
//printf("updateCollisionWithAvatars()...avatar=%p\n", avatar);
|
||||
|
||||
|
||||
// check hands...
|
||||
const HandData* handData = avatar->getHandData();
|
||||
|
||||
|
||||
if (handData->findSpherePenetration(center, radius, penetration, collidingPalm)) {
|
||||
// apply a hard collision when ball collides with hand
|
||||
penetration /= (float)(TREE_SCALE);
|
||||
updateCollisionSound(particle, penetration, COLLISION_FREQUENCY);
|
||||
|
||||
|
||||
// determine if the palm that collided was moving, if so, then we add that palm velocity as well...
|
||||
glm::vec3 addedVelocity = NO_ADDED_VELOCITY;
|
||||
if (collidingPalm) {
|
||||
|
@ -210,9 +210,9 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
|||
//printf("collidingPalm Velocity=%f,%f,%f\n", palmVelocity.x, palmVelocity.y, palmVelocity.z);
|
||||
addedVelocity = palmVelocity;
|
||||
}
|
||||
|
||||
|
||||
applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity);
|
||||
|
||||
|
||||
} else if (avatar->findSpherePenetration(center, radius, penetration)) {
|
||||
penetration /= (float)(TREE_SCALE);
|
||||
updateCollisionSound(particle, penetration, COLLISION_FREQUENCY);
|
||||
|
|
|
@ -52,10 +52,9 @@ NodeList* NodeList::getInstance() {
|
|||
}
|
||||
|
||||
NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
||||
_nodeHash(),
|
||||
_domainHostname(DEFAULT_DOMAIN_HOSTNAME),
|
||||
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||
_nodeBuckets(),
|
||||
_numNodes(0),
|
||||
_nodeSocket(),
|
||||
_ownerType(newOwnerType),
|
||||
_nodeTypesOfInterest(NULL),
|
||||
|
@ -108,10 +107,10 @@ void NodeList::setDomainHostname(const QString& domainHostname) {
|
|||
}
|
||||
|
||||
void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
foreach(SharedNodePointer node, _nodeHash) {
|
||||
if (node->getPublicSocket() == nodeAddress ||
|
||||
node->getLocalSocket() == nodeAddress) {
|
||||
|
||||
|
||||
unsigned char* dataAt = packetData + numBytesForPacketHeader(packetData);
|
||||
uint64_t ourOriginalTime = *(uint64_t*)(dataAt);
|
||||
dataAt += sizeof(ourOriginalTime);
|
||||
|
@ -129,15 +128,15 @@ void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *pac
|
|||
node->setClockSkewUsec(clockSkew);
|
||||
|
||||
const bool wantDebug = false;
|
||||
if (wantDebug) {
|
||||
if (wantDebug) {
|
||||
qDebug() << "PING_REPLY from node " << *node << "\n" <<
|
||||
" now: " << now << "\n" <<
|
||||
" ourTime: " << ourOriginalTime << "\n" <<
|
||||
" pingTime: " << pingTime << "\n" <<
|
||||
" oneWayFlightTime: " << oneWayFlightTime << "\n" <<
|
||||
" othersReplyTime: " << othersReplyTime << "\n" <<
|
||||
" othersExprectedReply: " << othersExprectedReply << "\n" <<
|
||||
" clockSkew: " << clockSkew << "\n";
|
||||
" now: " << now << "\n" <<
|
||||
" ourTime: " << ourOriginalTime << "\n" <<
|
||||
" pingTime: " << pingTime << "\n" <<
|
||||
" oneWayFlightTime: " << oneWayFlightTime << "\n" <<
|
||||
" othersReplyTime: " << othersReplyTime << "\n" <<
|
||||
" othersExprectedReply: " << othersExprectedReply << "\n" <<
|
||||
" clockSkew: " << clockSkew << "\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -184,10 +183,9 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char
|
|||
}
|
||||
|
||||
void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) {
|
||||
SharedNodePointer bulkSendNode = nodeWithAddress(senderAddress);
|
||||
|
||||
// find the avatar mixer in our node list and update the lastRecvTime from it
|
||||
Node* bulkSendNode = nodeWithAddress(senderAddress);
|
||||
|
||||
if (bulkSendNode) {
|
||||
|
||||
bulkSendNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||
|
@ -209,14 +207,14 @@ void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned c
|
|||
numTotalBytes - (currentPosition - startPosition));
|
||||
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)currentPosition, NUM_BYTES_RFC4122_UUID));
|
||||
Node* matchingNode = nodeWithUUID(nodeUUID);
|
||||
SharedNodePointer matchingNode = nodeWithUUID(nodeUUID);
|
||||
|
||||
if (!matchingNode) {
|
||||
// we're missing this node, we need to add it to the list
|
||||
matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr());
|
||||
}
|
||||
|
||||
currentPosition += updateNodeWithData(matchingNode,
|
||||
currentPosition += updateNodeWithData(matchingNode.data(),
|
||||
HifiSockAddr(),
|
||||
packetHolder,
|
||||
numTotalBytes - (currentPosition - startPosition));
|
||||
|
@ -253,53 +251,39 @@ int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr,
|
|||
}
|
||||
}
|
||||
|
||||
Node* NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
QSharedPointer<Node> NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr) {
|
||||
// naively returns the first node that has a matching active HifiSockAddr
|
||||
// note that there can be multiple nodes that have a matching active socket, so this isn't a good way to uniquely identify
|
||||
foreach(QSharedPointer<Node> node, _nodeHash) {
|
||||
if (node->getActiveSocket() && *node->getActiveSocket() == senderSockAddr) {
|
||||
return &(*node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return QSharedPointer<Node>(NULL);
|
||||
}
|
||||
|
||||
Node* NodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
if (node->getUUID() == nodeUUID) {
|
||||
return &(*node);
|
||||
}
|
||||
QSharedPointer<Node> NodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
||||
QHash<QUuid, QSharedPointer<Node> >::const_iterator foundIterator = _nodeHash.find(nodeUUID);
|
||||
if (foundIterator != _nodeHash.end()) {
|
||||
return foundIterator.value();
|
||||
} else {
|
||||
return QSharedPointer<Node>(NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int NodeList::getNumAliveNodes() const {
|
||||
int numAliveNodes = 0;
|
||||
|
||||
for (NodeList::iterator node = begin(); node != end(); node++) {
|
||||
if (node->isAlive()) {
|
||||
++numAliveNodes;
|
||||
}
|
||||
}
|
||||
|
||||
return numAliveNodes;
|
||||
}
|
||||
|
||||
void NodeList::clear() {
|
||||
qDebug() << "Clearing the NodeList. Deleting all nodes in list.\n";
|
||||
|
||||
// delete all of the nodes in the list, set the pointers back to NULL and the number of nodes to 0
|
||||
for (int i = 0; i < _numNodes; i++) {
|
||||
Node** nodeBucket = _nodeBuckets[i / NODES_PER_BUCKET];
|
||||
Node* node = nodeBucket[i % NODES_PER_BUCKET];
|
||||
|
||||
node->lock();
|
||||
notifyHooksOfKilledNode(&*node);
|
||||
|
||||
delete node;
|
||||
}
|
||||
NodeHash::iterator nodeItem = _nodeHash.begin();
|
||||
|
||||
_numNodes = 0;
|
||||
// iterate the nodes in the list
|
||||
while (nodeItem != _nodeHash.end()) {
|
||||
// emit our signal to say this node has been killed
|
||||
emit nodeKilled(nodeItem.value());
|
||||
// erase the node from our node hash
|
||||
_nodeHash.erase(nodeItem);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::reset() {
|
||||
|
@ -457,6 +441,14 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes)
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
||||
NodeHash::iterator nodeToKill = _nodeHash.find(nodeUUID);
|
||||
if (nodeToKill != _nodeHash.end()) {
|
||||
emit nodeKilled(nodeToKill.value());
|
||||
_nodeHash.erase(nodeToKill);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
||||
unsigned char packet[MAX_PACKET_SIZE];
|
||||
unsigned char* packetPosition = packet;
|
||||
|
@ -483,9 +475,10 @@ void NodeList::processKillNode(unsigned char* packetData, size_t dataBytes) {
|
|||
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// make sure the node exists
|
||||
Node* node = nodeWithUUID(nodeUUID);
|
||||
if (node) {
|
||||
killNode(node, true);
|
||||
NodeHash::iterator nodeToKill = _nodeHash.find(nodeUUID);
|
||||
if (nodeToKill != _nodeHash.end()) {
|
||||
emit nodeKilled(nodeToKill.value());
|
||||
_nodeHash.erase(nodeToKill);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,26 +674,24 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) {
|
|||
node->getPublicSocket().getAddress(), node->getPublicSocket().getPort());
|
||||
}
|
||||
|
||||
Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||
SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
||||
NodeList::iterator node = end();
|
||||
NodeHash::iterator matchingNodeItem = _nodeHash.find(uuid);
|
||||
|
||||
for (node = begin(); node != end(); node++) {
|
||||
if (node->getUUID() == uuid) {
|
||||
// we already have this node, stop checking
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node == end()) {
|
||||
if (matchingNodeItem == _nodeHash.end()) {
|
||||
// we didn't have this node, so add them
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
|
||||
|
||||
addNodeToList(newNode);
|
||||
NodeHash::iterator addedItem = _nodeHash.insert(newNode->getUUID(), SharedNodePointer(newNode));
|
||||
|
||||
return newNode;
|
||||
qDebug() << "Added" << *newNode << "\n";
|
||||
|
||||
emit nodeAdded(addedItem.value());
|
||||
|
||||
return SharedNodePointer(newNode);
|
||||
} else {
|
||||
node->lock();
|
||||
SharedNodePointer node = matchingNodeItem.value();
|
||||
matchingNodeItem.value()->lock();
|
||||
|
||||
if (node->getType() == NODE_TYPE_AUDIO_MIXER ||
|
||||
node->getType() == NODE_TYPE_VOXEL_SERVER ||
|
||||
|
@ -724,33 +715,17 @@ Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
|||
node->unlock();
|
||||
|
||||
// we had this node already, do nothing for now
|
||||
return &*node;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::addNodeToList(Node* newNode) {
|
||||
// find the correct array to add this node to
|
||||
int bucketIndex = _numNodes / NODES_PER_BUCKET;
|
||||
|
||||
if (!_nodeBuckets[bucketIndex]) {
|
||||
_nodeBuckets[bucketIndex] = new Node*[NODES_PER_BUCKET]();
|
||||
}
|
||||
|
||||
_nodeBuckets[bucketIndex][_numNodes % NODES_PER_BUCKET] = newNode;
|
||||
|
||||
++_numNodes;
|
||||
|
||||
qDebug() << "Added" << *newNode << "\n";
|
||||
|
||||
notifyHooksOfAddedNode(newNode);
|
||||
}
|
||||
|
||||
unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes) {
|
||||
unsigned n = 0;
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, _nodeHash) {
|
||||
// only send to the NodeTypes we are asked to send to.
|
||||
if (memchr(nodeTypes, node->getType(), numNodeTypes)) {
|
||||
if (getNodeActiveSocketOrPing(&(*node))) {
|
||||
if (getNodeActiveSocketOrPing(node.data())) {
|
||||
// we know which socket is good for this node, send there
|
||||
_nodeSocket.writeDatagram((char*) broadcastData, dataBytes,
|
||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||
|
@ -758,14 +733,15 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void NodeList::pingInactiveNodes() {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
foreach(SharedNodePointer node, _nodeHash) {
|
||||
if (!node->getActiveSocket()) {
|
||||
// we don't have an active link to this node, ping it to set that up
|
||||
pingPublicAndLocalSocketsForInactiveNode(&(*node));
|
||||
pingPublicAndLocalSocketsForInactiveNode(node.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -780,7 +756,8 @@ const HifiSockAddr* NodeList::getNodeActiveSocketOrPing(Node* node) {
|
|||
}
|
||||
|
||||
void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddress) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
|
||||
foreach(SharedNodePointer node, _nodeHash) {
|
||||
if (!node->getActiveSocket()) {
|
||||
// check both the public and local addresses for each node to see if we find a match
|
||||
// prioritize the private address so that we prune erroneous local matches
|
||||
|
@ -795,46 +772,35 @@ void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddre
|
|||
}
|
||||
}
|
||||
|
||||
Node* NodeList::soloNodeOfType(char nodeType) {
|
||||
SharedNodePointer NodeList::soloNodeOfType(char nodeType) {
|
||||
|
||||
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
foreach(SharedNodePointer node, _nodeHash) {
|
||||
if (node->getType() == nodeType) {
|
||||
return &(*node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void NodeList::killNode(Node* node, bool mustLockNode) {
|
||||
if (mustLockNode) {
|
||||
node->lock();
|
||||
}
|
||||
|
||||
qDebug() << "Killed " << *node << "\n";
|
||||
|
||||
notifyHooksOfKilledNode(&*node);
|
||||
|
||||
node->setAlive(false);
|
||||
|
||||
if (mustLockNode) {
|
||||
node->unlock();
|
||||
}
|
||||
return SharedNodePointer(NULL);
|
||||
}
|
||||
|
||||
void NodeList::removeSilentNodes() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) {
|
||||
node->lock();
|
||||
NodeHash::iterator nodeItem = _nodeHash.begin();
|
||||
|
||||
while (nodeItem != _nodeHash.end()) {
|
||||
nodeItem.value()->lock();
|
||||
|
||||
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) {
|
||||
if ((usecTimestampNow() - nodeItem.value()->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) {
|
||||
SharedNodePointer node = nodeItem.value();
|
||||
|
||||
// kill this node, don't lock - we already did it
|
||||
nodeList->killNode(&(*node), false);
|
||||
_nodeHash.erase(nodeItem);
|
||||
|
||||
// unlock the node
|
||||
node->unlock();
|
||||
}
|
||||
|
||||
node->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,80 +834,6 @@ void NodeList::saveData(QSettings* settings) {
|
|||
settings->endGroup();
|
||||
}
|
||||
|
||||
NodeList::iterator NodeList::begin() const {
|
||||
Node** nodeBucket = NULL;
|
||||
|
||||
for (int i = 0; i < _numNodes; i++) {
|
||||
if (i % NODES_PER_BUCKET == 0) {
|
||||
nodeBucket = _nodeBuckets[i / NODES_PER_BUCKET];
|
||||
}
|
||||
|
||||
if (nodeBucket[i % NODES_PER_BUCKET]->isAlive()) {
|
||||
return NodeListIterator(this, i);
|
||||
}
|
||||
}
|
||||
|
||||
// there's no alive node to start from - return the end
|
||||
return end();
|
||||
}
|
||||
|
||||
NodeList::iterator NodeList::end() const {
|
||||
return NodeListIterator(this, _numNodes);
|
||||
}
|
||||
|
||||
NodeListIterator::NodeListIterator(const NodeList* nodeList, int nodeIndex) :
|
||||
_nodeIndex(nodeIndex) {
|
||||
_nodeList = nodeList;
|
||||
}
|
||||
|
||||
NodeListIterator& NodeListIterator::operator=(const NodeListIterator& otherValue) {
|
||||
_nodeList = otherValue._nodeList;
|
||||
_nodeIndex = otherValue._nodeIndex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool NodeListIterator::operator==(const NodeListIterator &otherValue) {
|
||||
return _nodeIndex == otherValue._nodeIndex;
|
||||
}
|
||||
|
||||
bool NodeListIterator::operator!=(const NodeListIterator &otherValue) {
|
||||
return !(*this == otherValue);
|
||||
}
|
||||
|
||||
Node& NodeListIterator::operator*() {
|
||||
Node** nodeBucket = _nodeList->_nodeBuckets[_nodeIndex / NODES_PER_BUCKET];
|
||||
return *nodeBucket[_nodeIndex % NODES_PER_BUCKET];
|
||||
}
|
||||
|
||||
Node* NodeListIterator::operator->() {
|
||||
Node** nodeBucket = _nodeList->_nodeBuckets[_nodeIndex / NODES_PER_BUCKET];
|
||||
return nodeBucket[_nodeIndex % NODES_PER_BUCKET];
|
||||
}
|
||||
|
||||
NodeListIterator& NodeListIterator::operator++() {
|
||||
skipDeadAndStopIncrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
NodeList::iterator NodeListIterator::operator++(int) {
|
||||
NodeListIterator newIterator = NodeListIterator(*this);
|
||||
skipDeadAndStopIncrement();
|
||||
return newIterator;
|
||||
}
|
||||
|
||||
void NodeListIterator::skipDeadAndStopIncrement() {
|
||||
while (_nodeIndex != _nodeList->_numNodes) {
|
||||
++_nodeIndex;
|
||||
|
||||
if (_nodeIndex == _nodeList->_numNodes) {
|
||||
break;
|
||||
} else if ((*(*this)).isAlive()) {
|
||||
// skip over the dead nodes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::addDomainListener(DomainChangeListener* listener) {
|
||||
_domainListeners.push_back(listener);
|
||||
QString domain = _domainHostname.isEmpty() ? _domainSockAddr.getAddress().toString() : _domainHostname;
|
||||
|
@ -957,33 +849,6 @@ void NodeList::removeDomainListener(DomainChangeListener* listener) {
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::addHook(NodeListHook* hook) {
|
||||
_hooks.push_back(hook);
|
||||
}
|
||||
|
||||
void NodeList::removeHook(NodeListHook* hook) {
|
||||
for (int i = 0; i < _hooks.size(); i++) {
|
||||
if (_hooks[i] == hook) {
|
||||
_hooks.erase(_hooks.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::notifyHooksOfAddedNode(Node* node) {
|
||||
for (int i = 0; i < _hooks.size(); i++) {
|
||||
//printf("NodeList::notifyHooksOfAddedNode() i=%d\n", i);
|
||||
_hooks[i]->nodeAdded(node);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::notifyHooksOfKilledNode(Node* node) {
|
||||
for (int i = 0; i < _hooks.size(); i++) {
|
||||
//printf("NodeList::notifyHooksOfKilledNode() i=%d\n", i);
|
||||
_hooks[i]->nodeKilled(node);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::notifyDomainChanged() {
|
||||
for (int i = 0; i < _domainListeners.size(); i++) {
|
||||
_domainListeners[i]->domainChanged(_domainHostname);
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
#include <iterator>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include "Node.h"
|
||||
#include "NodeTypes.h"
|
||||
|
@ -43,31 +44,21 @@ const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5;
|
|||
|
||||
class Assignment;
|
||||
class HifiSockAddr;
|
||||
class NodeListIterator;
|
||||
|
||||
// Callers who want to hook add/kill callbacks should implement this class
|
||||
class NodeListHook {
|
||||
public:
|
||||
virtual void nodeAdded(Node* node) = 0;
|
||||
virtual void nodeKilled(Node* node) = 0;
|
||||
};
|
||||
|
||||
class DomainChangeListener {
|
||||
public:
|
||||
virtual void domainChanged(QString domain) = 0;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<Node> SharedNodePointer;
|
||||
typedef QHash<QUuid, SharedNodePointer> NodeHash;
|
||||
|
||||
class NodeList : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static NodeList* createInstance(char ownerType, unsigned short int socketListenPort = 0);
|
||||
static NodeList* getInstance();
|
||||
|
||||
typedef NodeListIterator iterator;
|
||||
|
||||
NodeListIterator begin() const;
|
||||
NodeListIterator end() const;
|
||||
|
||||
NODE_TYPE getOwnerType() const { return _ownerType; }
|
||||
void setOwnerType(NODE_TYPE ownerType) { _ownerType = ownerType; }
|
||||
|
||||
|
@ -88,8 +79,9 @@ public:
|
|||
|
||||
void(*linkedDataCreateCallback)(Node *);
|
||||
|
||||
int size() { return _numNodes; }
|
||||
int getNumAliveNodes() const;
|
||||
const NodeHash& getNodeHash() { return _nodeHash; }
|
||||
|
||||
int size() const { return _nodeHash.size(); }
|
||||
|
||||
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
|
||||
|
||||
|
@ -107,13 +99,13 @@ public:
|
|||
int fillPingReplyPacket(unsigned char* pingBuffer, unsigned char* replyBuffer);
|
||||
void pingPublicAndLocalSocketsForInactiveNode(Node* node);
|
||||
|
||||
void killNodeWithUUID(const QUuid& nodeUUID);
|
||||
void sendKillNode(const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
Node* nodeWithAddress(const HifiSockAddr& senderSockAddr);
|
||||
Node* nodeWithUUID(const QUuid& nodeUUID);
|
||||
SharedNodePointer nodeWithAddress(const HifiSockAddr& senderSockAddr);
|
||||
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID);
|
||||
|
||||
Node* addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
void killNode(Node* node, bool mustLockNode = true);
|
||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
|
||||
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
||||
void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes);
|
||||
|
@ -122,18 +114,11 @@ public:
|
|||
|
||||
unsigned broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
Node* soloNodeOfType(char nodeType);
|
||||
SharedNodePointer soloNodeOfType(char nodeType);
|
||||
|
||||
void loadData(QSettings* settings);
|
||||
void saveData(QSettings* settings);
|
||||
|
||||
friend class NodeListIterator;
|
||||
|
||||
void addHook(NodeListHook* hook);
|
||||
void removeHook(NodeListHook* hook);
|
||||
void notifyHooksOfAddedNode(Node* node);
|
||||
void notifyHooksOfKilledNode(Node* node);
|
||||
|
||||
void addDomainListener(DomainChangeListener* listener);
|
||||
void removeDomainListener(DomainChangeListener* listener);
|
||||
|
||||
|
@ -142,6 +127,9 @@ public slots:
|
|||
void sendDomainServerCheckIn();
|
||||
void pingInactiveNodes();
|
||||
void removeSilentNodes();
|
||||
signals:
|
||||
void nodeAdded(QSharedPointer<Node>);
|
||||
void nodeKilled(QSharedPointer<Node>);
|
||||
private:
|
||||
static NodeList* _sharedInstance;
|
||||
|
||||
|
@ -150,17 +138,14 @@ private:
|
|||
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||
|
||||
void addNodeToList(Node* newNode);
|
||||
|
||||
void sendSTUNRequest();
|
||||
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
||||
|
||||
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
||||
|
||||
NodeHash _nodeHash;
|
||||
QString _domainHostname;
|
||||
HifiSockAddr _domainSockAddr;
|
||||
Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET];
|
||||
int _numNodes;
|
||||
QUdpSocket _nodeSocket;
|
||||
char _ownerType;
|
||||
char* _nodeTypesOfInterest;
|
||||
|
@ -174,7 +159,6 @@ private:
|
|||
void activateSocketFromNodeCommunication(const HifiSockAddr& nodeSockAddr);
|
||||
void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData);
|
||||
|
||||
std::vector<NodeListHook*> _hooks;
|
||||
std::vector<DomainChangeListener*> _domainListeners;
|
||||
|
||||
void resetDomainData(char domainField[], const char* domainData);
|
||||
|
@ -182,27 +166,4 @@ private:
|
|||
void domainLookup();
|
||||
};
|
||||
|
||||
class NodeListIterator : public std::iterator<std::input_iterator_tag, Node> {
|
||||
public:
|
||||
NodeListIterator(const NodeList* nodeList, int nodeIndex);
|
||||
|
||||
int getNodeIndex() { return _nodeIndex; }
|
||||
|
||||
NodeListIterator& operator=(const NodeListIterator& otherValue);
|
||||
|
||||
bool operator==(const NodeListIterator& otherValue);
|
||||
bool operator!= (const NodeListIterator& otherValue);
|
||||
|
||||
Node& operator*();
|
||||
Node* operator->();
|
||||
|
||||
NodeListIterator& operator++();
|
||||
NodeListIterator operator++(int);
|
||||
private:
|
||||
void skipDeadAndStopIncrement();
|
||||
|
||||
const NodeList* _nodeList;
|
||||
int _nodeIndex;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__NodeList__) */
|
||||
|
|
|
@ -18,7 +18,7 @@ ReceivedPacketProcessor::ReceivedPacketProcessor() {
|
|||
|
||||
void ReceivedPacketProcessor::queueReceivedPacket(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||
// Make sure our Node and NodeList knows we've heard from this node.
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(address);
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(address);
|
||||
if (node) {
|
||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue