resolve conflicts on merge with upstream/master

This commit is contained in:
Stephen Birarda 2014-01-23 14:43:04 -08:00
commit 9ab1fc4c2c
23 changed files with 122 additions and 127 deletions

View file

@ -807,7 +807,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
pthread_create(&::animateVoxelThread, NULL, animateVoxels, NULL); pthread_create(&::animateVoxelThread, NULL, animateVoxels, NULL);
NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_VOXEL_SERVER, 1); NodeList::getInstance()->addNodeTypeToInterestSet(NODE_TYPE_VOXEL_SERVER);
QTimer* domainServerTimer = new QTimer(this); QTimer* domainServerTimer = new QTimer(this);
connect(domainServerTimer, SIGNAL(timeout()), nodeList, SLOT(sendDomainServerCheckIn())); connect(domainServerTimer, SIGNAL(timeout()), nodeList, SLOT(sendDomainServerCheckIn()));

View file

@ -52,13 +52,7 @@ void Agent::run() {
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
nodeList->setOwnerType(NODE_TYPE_AGENT); nodeList->setOwnerType(NODE_TYPE_AGENT);
// XXXBHG - this seems less than ideal. There might be classes (like jurisdiction listeners, that need access to nodeList->addSetOfNodeTypesToNodeInterestSet(QSet<NODE_TYPE>() << NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER);
// other node types, but for them to get access to those node types, we have to add them here. It seems like
// NodeList should support adding types of interest
const NODE_TYPE AGENT_NODE_TYPES_OF_INTEREST[] = { NODE_TYPE_VOXEL_SERVER, NODE_TYPE_PARTICLE_SERVER,
NODE_TYPE_AUDIO_MIXER, NODE_TYPE_AVATAR_MIXER };
nodeList->setNodeTypesOfInterest(AGENT_NODE_TYPES_OF_INTEREST, sizeof(AGENT_NODE_TYPES_OF_INTEREST));
// figure out the URL for the script for this agent assignment // figure out the URL for the script for this agent assignment
QString scriptURLString("http://%1:8080/assignment/%2"); QString scriptURLString("http://%1:8080/assignment/%2");

View file

@ -241,8 +241,7 @@ void AudioMixer::run() {
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
const char AUDIO_MIXER_NODE_TYPES_OF_INTEREST[2] = { NODE_TYPE_AGENT, NODE_TYPE_AUDIO_INJECTOR }; nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
nodeList->setNodeTypesOfInterest(AUDIO_MIXER_NODE_TYPES_OF_INTEREST, sizeof(AUDIO_MIXER_NODE_TYPES_OF_INTEREST));
nodeList->linkedDataCreateCallback = attachNewBufferToNode; nodeList->linkedDataCreateCallback = attachNewBufferToNode;

View file

@ -168,7 +168,7 @@ void AvatarMixer::run() {
commonInit(AVATAR_MIXER_LOGGING_NAME, NODE_TYPE_AVATAR_MIXER); commonInit(AVATAR_MIXER_LOGGING_NAME, NODE_TYPE_AVATAR_MIXER);
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
nodeList->setNodeTypesOfInterest(&NODE_TYPE_AGENT, 1); nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
nodeList->linkedDataCreateCallback = attachAvatarDataToNode; nodeList->linkedDataCreateCallback = attachAvatarDataToNode;

View file

@ -18,8 +18,8 @@ function vMinus(a, b) {
// First, load two percussion sounds to be used on the sticks // First, load two percussion sounds to be used on the sticks
var drum1 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/MusicalInstruments/drums/snare.raw"); var drum1 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Drums/RackTomHi.raw");
var drum2 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/MusicalInstruments/drums/snare.raw"); var drum2 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Drums/RackTomLo.raw");
// State Machine: // State Machine:
// 0 = not triggered // 0 = not triggered

View file

@ -42,7 +42,7 @@ Voxels.setVoxel(position.x, 0, position.z, 0.5, 0, 0, 255);
var totalParticles = 0; var totalParticles = 0;
function makeFountain() { function makeFountain() {
if (Math.random() < 0.06) { if (Math.random() < 0.10) {
//print("Made particle!\n"); //print("Made particle!\n");
var properties = { var properties = {
position: position, position: position,
@ -51,9 +51,9 @@ function makeFountain() {
velocity: { x: (Math.random() * 1.0 - 0.5), velocity: { x: (Math.random() * 1.0 - 0.5),
y: (1.0 + (Math.random() * 2.0)), y: (1.0 + (Math.random() * 2.0)),
z: (Math.random() * 1.0 - 0.5) }, z: (Math.random() * 1.0 - 0.5) },
gravity: { x: 0, y: -0.5, z: 0 }, gravity: { x: 0, y: -0.1, z: 0 },
damping: 0.25, damping: 0.25,
lifetime: 2 lifetime: 1
} }
Particles.addParticle(properties); Particles.addParticle(properties);

View file

@ -134,8 +134,10 @@ function checkControllerSide(whichSide) {
gravity: { x: 0, y: 0, z: 0}, gravity: { x: 0, y: 0, z: 0},
inHand: true, inHand: true,
radius: 0.05, radius: 0.05,
damping: 0.999,
color: { red: 255, green: 0, blue: 0 }, color: { red: 255, green: 0, blue: 0 },
lifetime: 10 // 10 seconds
lifetime: 10 // 10 seconds - same as default, not needed but here as an example
}; };
newParticle = Particles.addParticle(properties); newParticle = Particles.addParticle(properties);

View file

@ -109,7 +109,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_window(new QMainWindow(desktop())), _window(new QMainWindow(desktop())),
_glWidget(new GLCanvas()), _glWidget(new GLCanvas()),
_nodeThread(new QThread(this)), _nodeThread(new QThread(this)),
_datagramProcessor(new DatagramProcessor()), _datagramProcessor(),
_frameCount(0), _frameCount(0),
_fps(120.0f), _fps(120.0f),
_justStarted(true), _justStarted(true),
@ -173,20 +173,20 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
listenPort = atoi(portStr); listenPort = atoi(portStr);
} }
// put the NodeList and datagram processing on the node thread // start the nodeThread so its event loop is running
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort); _nodeThread->start();
nodeList->moveToThread(_nodeThread);
_datagramProcessor->moveToThread(_nodeThread);
// connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), _datagramProcessor, SLOT(processDatagrams()));
// make sure the node thread is given highest priority // make sure the node thread is given highest priority
_nodeThread->setPriority(QThread::TimeCriticalPriority); _nodeThread->setPriority(QThread::TimeCriticalPriority);
// start the nodeThread so its event loop is running // put the NodeList and datagram processing on the node thread
_nodeThread->start(); NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
nodeList->moveToThread(_nodeThread);
_datagramProcessor.moveToThread(_nodeThread);
// connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), &_datagramProcessor, SLOT(processDatagrams()));
// put the audio processing on a separate thread // put the audio processing on a separate thread
QThread* audioThread = new QThread(this); QThread* audioThread = new QThread(this);
@ -227,12 +227,12 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
#endif #endif
// tell the NodeList instance who to tell the domain server we care about // tell the NodeList instance who to tell the domain server we care about
const char nodeTypesOfInterest[] = {NODE_TYPE_AUDIO_MIXER, NODE_TYPE_AVATAR_MIXER, NODE_TYPE_VOXEL_SERVER, nodeList->addSetOfNodeTypesToNodeInterestSet(QSet<NODE_TYPE>() << NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER
NODE_TYPE_PARTICLE_SERVER, NODE_TYPE_METAVOXEL_SERVER}; << NODE_TYPE_VOXEL_SERVER << NODE_TYPE_PARTICLE_SERVER
nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); << NODE_TYPE_METAVOXEL_SERVER);
// move the silentNodeTimer to the _nodeThread // move the silentNodeTimer to the _nodeThread
QTimer* silentNodeTimer = new QTimer(this); QTimer* silentNodeTimer = new QTimer();
connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
silentNodeTimer->moveToThread(_nodeThread); silentNodeTimer->moveToThread(_nodeThread);
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000);
@ -278,17 +278,35 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
Application::~Application() { Application::~Application() {
qInstallMessageHandler(NULL); qInstallMessageHandler(NULL);
// make sure we don't call the idle timer any more // make sure we don't call the idle timer any more
delete idleTimer; delete idleTimer;
Menu::getInstance()->saveSettings();
_rearMirrorTools->saveSettings(_settings);
_settings->sync();
// let the avatar mixer know we're out
MyAvatar::sendKillAvatar();
// ask the datagram processing thread to quit and wait until it is done // ask the datagram processing thread to quit and wait until it is done
_nodeThread->thread()->quit(); _nodeThread->quit();
_nodeThread->thread()->wait(); _nodeThread->wait();
// ask the audio thread to quit and wait until it is done // ask the audio thread to quit and wait until it is done
_audio.thread()->quit(); _audio.thread()->quit();
_audio.thread()->wait(); _audio.thread()->wait();
_voxelProcessor.terminate();
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
_particleEditSender.terminate();
if (_persistThread) {
_persistThread->terminate();
_persistThread->deleteLater();
_persistThread = NULL;
}
storeSizeAndPosition(); storeSizeAndPosition();
saveScripts(); saveScripts();
@ -373,9 +391,6 @@ void Application::initializeGL() {
qDebug("Voxel parsing thread created."); qDebug("Voxel parsing thread created.");
} }
// call terminate before exiting
connect(this, SIGNAL(aboutToQuit()), SLOT(terminate()));
// call our timer function every second // call our timer function every second
QTimer* timer = new QTimer(this); QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(timer())); connect(timer, SIGNAL(timeout()), SLOT(timer()));
@ -1325,11 +1340,11 @@ void Application::timer() {
_fps = (float)_frameCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f); _fps = (float)_frameCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);
_packetsPerSecond = (float) _datagramProcessor->getPacketCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f); _packetsPerSecond = (float) _datagramProcessor.getPacketCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);
_bytesPerSecond = (float) _datagramProcessor->getByteCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f); _bytesPerSecond = (float) _datagramProcessor.getByteCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);
_frameCount = 0; _frameCount = 0;
_datagramProcessor->resetCounters(); _datagramProcessor.resetCounters();
gettimeofday(&_timerStart, NULL); gettimeofday(&_timerStart, NULL);
@ -1408,28 +1423,6 @@ void Application::idle() {
} }
} }
void Application::terminate() {
// Close serial port
// close(serial_fd);
Menu::getInstance()->saveSettings();
_rearMirrorTools->saveSettings(_settings);
_settings->sync();
// let the avatar mixer know we're out
_myAvatar.sendKillAvatar();
_voxelProcessor.terminate();
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
_particleEditSender.terminate();
if (_persistThread) {
_persistThread->terminate();
_persistThread->deleteLater();
_persistThread = NULL;
}
}
void Application::checkBandwidthMeterClick() { void Application::checkBandwidthMeterClick() {
// ... to be called upon button release // ... to be called upon button release
@ -1931,16 +1924,9 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3&
glm::vec3 rayOrigin, rayDirection; glm::vec3 rayOrigin, rayDirection;
_viewFrustum.computePickRay(0.5f, 0.5f, rayOrigin, rayDirection); _viewFrustum.computePickRay(0.5f, 0.5f, rayOrigin, rayDirection);
lookAtSpot = rayOrigin + rayDirection * FAR_AWAY_STARE; lookAtSpot = rayOrigin + rayDirection * FAR_AWAY_STARE;
} else {
} else if (!_avatarManager.getLookAtTargetAvatar()) { // just look in direction of the mouse ray
if (_isHoverVoxel) { lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE;
// Look at the hovered voxel
lookAtSpot = getMouseVoxelWorldCoordinates(_hoverVoxel);
} else {
// Just look in direction of the mouse ray
lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE;
}
} }
if (_faceshift.isActive()) { if (_faceshift.isActive()) {
// deflect using Faceshift gaze data // deflect using Faceshift gaze data
@ -2796,10 +2782,10 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
if (!selfAvatarOnly) { if (!selfAvatarOnly) {
// draw a red sphere // draw a red sphere
float sphereRadius = 0.25f; float originSphereRadius = 0.05f;
glColor3f(1,0,0); glColor3f(1,0,0);
glPushMatrix(); glPushMatrix();
glutSolidSphere(sphereRadius, 15, 15); glutSolidSphere(originSphereRadius, 15, 15);
glPopMatrix(); glPopMatrix();
// disable specular lighting for ground and voxels // disable specular lighting for ground and voxels

View file

@ -230,7 +230,6 @@ public slots:
private slots: private slots:
void timer(); void timer();
void idle(); void idle();
void terminate();
void setFullscreen(bool fullscreen); void setFullscreen(bool fullscreen);
void setEnable3DTVMode(bool enable3DTVMode); void setEnable3DTVMode(bool enable3DTVMode);
@ -329,7 +328,7 @@ private:
BandwidthMeter _bandwidthMeter; BandwidthMeter _bandwidthMeter;
QThread* _nodeThread; QThread* _nodeThread;
DatagramProcessor* _datagramProcessor; DatagramProcessor _datagramProcessor;
QNetworkAccessManager* _networkAccessManager; QNetworkAccessManager* _networkAccessManager;
QSettings* _settings; QSettings* _settings;

View file

@ -443,6 +443,15 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
QByteArray outputBuffer; QByteArray outputBuffer;
outputBuffer.resize(numRequiredOutputSamples * sizeof(int16_t)); outputBuffer.resize(numRequiredOutputSamples * sizeof(int16_t));
if (!_ringBuffer.isStarved() && _audioOutput->bytesFree() == _audioOutput->bufferSize()) {
// we don't have any audio data left in the output buffer
// we just starved
qDebug() << "Audio output just starved.";
_ringBuffer.setIsStarved(true);
_numFramesDisplayStarve = 10;
}
// if there is anything in the ring buffer, decide what to do // if there is anything in the ring buffer, decide what to do
if (_ringBuffer.samplesAvailable() > 0) { if (_ringBuffer.samplesAvailable() > 0) {
if (!_ringBuffer.isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO if (!_ringBuffer.isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO
@ -515,12 +524,6 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
} }
} }
} else if (_audioOutput->bytesFree() == _audioOutput->bufferSize()) {
// we don't have any audio data left in the output buffer, and the ring buffer from
// the network has nothing in it either - we just starved
qDebug() << "Audio output just starved.";
_ringBuffer.setIsStarved(true);
_numFramesDisplayStarve = 10;
} }
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size()); Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size());

View file

@ -332,27 +332,29 @@ void renderWorldBox() {
glVertex3f(TREE_SCALE, 0, TREE_SCALE); glVertex3f(TREE_SCALE, 0, TREE_SCALE);
glVertex3f(TREE_SCALE, 0, 0); glVertex3f(TREE_SCALE, 0, 0);
glEnd(); glEnd();
// Draw marker dots at very end // Draw meter markers along the 3 axis to help with measuring things
const float MARKER_DISTANCE = 1.f;
const float MARKER_RADIUS = 0.05f;
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
glPushMatrix(); glPushMatrix();
glTranslatef(TREE_SCALE, 0, 0); glTranslatef(MARKER_DISTANCE, 0, 0);
glColor3fv(red); glColor3fv(red);
glutSolidSphere(0.125, 10, 10); glutSolidSphere(MARKER_RADIUS, 10, 10);
glPopMatrix(); glPopMatrix();
glPushMatrix(); glPushMatrix();
glTranslatef(0, TREE_SCALE, 0); glTranslatef(0, MARKER_DISTANCE, 0);
glColor3fv(green); glColor3fv(green);
glutSolidSphere(0.125, 10, 10); glutSolidSphere(MARKER_RADIUS, 10, 10);
glPopMatrix(); glPopMatrix();
glPushMatrix(); glPushMatrix();
glTranslatef(0, 0, TREE_SCALE); glTranslatef(0, 0, MARKER_DISTANCE);
glColor3fv(blue); glColor3fv(blue);
glutSolidSphere(0.125, 10, 10); glutSolidSphere(MARKER_RADIUS, 10, 10);
glPopMatrix(); glPopMatrix();
glPushMatrix(); glPushMatrix();
glColor3fv(gray); glColor3fv(gray);
glTranslatef(TREE_SCALE, 0, TREE_SCALE); glTranslatef(MARKER_DISTANCE, 0, MARKER_DISTANCE);
glutSolidSphere(0.125, 10, 10); glutSolidSphere(MARKER_RADIUS, 10, 10);
glPopMatrix(); glPopMatrix();
} }

View file

@ -569,8 +569,7 @@ void OctreeServer::run() {
nodeList->setOwnerType(getMyNodeType()); nodeList->setOwnerType(getMyNodeType());
// we need to ask the DS about agents so we can ping/reply with them // we need to ask the DS about agents so we can ping/reply with them
const char nodeTypesOfInterest[] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER}; nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stdout, NULL, _IOLBF, 0);

View file

@ -23,6 +23,9 @@ JurisdictionListener::JurisdictionListener(NODE_TYPE type, PacketSenderNotify* n
connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &JurisdictionListener::nodeKilled); connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &JurisdictionListener::nodeKilled);
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)", type); //qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)", type);
// tell our NodeList we want to hear about nodes with our node type
NodeList::getInstance()->addNodeTypeToInterestSet(type);
} }
void JurisdictionListener::nodeKilled(SharedNodePointer node) { void JurisdictionListener::nodeKilled(SharedNodePointer node) {

View file

@ -682,7 +682,7 @@ void Particle::update(const uint64_t& now) {
const uint64_t REALLY_OLD = 30 * USECS_PER_SECOND; // 30 seconds const uint64_t REALLY_OLD = 30 * USECS_PER_SECOND; // 30 seconds
bool isReallyOld = ((now - _created) > REALLY_OLD); bool isReallyOld = ((now - _created) > REALLY_OLD);
bool isInHand = getInHand(); bool isInHand = getInHand();
bool shouldDie = getShouldDie() || (!isInHand && isStopped && isReallyOld); bool shouldDie = (getAge() > getLifetime()) || getShouldDie() || (!isInHand && isStopped && isReallyOld);
setShouldDie(shouldDie); setShouldDie(shouldDie);
runUpdateScript(); // allow the javascript to alter our state runUpdateScript(); // allow the javascript to alter our state

View file

@ -42,7 +42,7 @@ const uint16_t PACKET_CONTAINS_INHAND = 128;
const uint16_t PACKET_CONTAINS_SCRIPT = 256; const uint16_t PACKET_CONTAINS_SCRIPT = 256;
const uint16_t PACKET_CONTAINS_SHOULDDIE = 512; const uint16_t PACKET_CONTAINS_SHOULDDIE = 512;
const float DEFAULT_LIFETIME = 60.0f * 60.0f * 24.0f; // particles live for 1 day by default const float DEFAULT_LIFETIME = 10.0f; // particles live for 10 seconds by default
const float DEFAULT_DAMPING = 0.99f; const float DEFAULT_DAMPING = 0.99f;
const float DEFAULT_RADIUS = 0.1f / TREE_SCALE; const float DEFAULT_RADIUS = 0.1f / TREE_SCALE;
const float MINIMUM_PARTICLE_ELEMENT_SIZE = (1.0f / 100000.0f) / TREE_SCALE; // smallest size container const float MINIMUM_PARTICLE_ELEMENT_SIZE = (1.0f / 100000.0f) / TREE_SCALE; // smallest size container

View file

@ -276,7 +276,7 @@ void ParticleCollisionSystem::applyHardCollision(Particle* particle, float elast
void ParticleCollisionSystem::updateCollisionSound(Particle* particle, const glm::vec3 &penetration, float frequency) { void ParticleCollisionSystem::updateCollisionSound(Particle* particle, const glm::vec3 &penetration, float frequency) {
// consider whether to have the collision make a sound // consider whether to have the collision make a sound
const float AUDIBLE_COLLISION_THRESHOLD = 0.1f; const float AUDIBLE_COLLISION_THRESHOLD = 0.3f;
const float COLLISION_LOUDNESS = 1.f; const float COLLISION_LOUDNESS = 1.f;
const float DURATION_SCALING = 0.004f; const float DURATION_SCALING = 0.004f;
const float NOISE_SCALING = 0.1f; const float NOISE_SCALING = 0.1f;

View file

@ -391,17 +391,26 @@ bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned cha
// called by the server when it knows all nodes have been sent deleted packets // called by the server when it knows all nodes have been sent deleted packets
void ParticleTree::forgetParticlesDeletedBefore(uint64_t sinceTime) { void ParticleTree::forgetParticlesDeletedBefore(uint64_t sinceTime) {
//qDebug() << "forgetParticlesDeletedBefore()"; //qDebug() << "forgetParticlesDeletedBefore()";
QSet<uint64_t> keysToRemove;
_recentlyDeletedParticlesLock.lockForWrite(); _recentlyDeletedParticlesLock.lockForWrite();
QMultiMap<uint64_t, uint32_t>::iterator iterator = _recentlyDeletedParticleIDs.begin(); QMultiMap<uint64_t, uint32_t>::iterator iterator = _recentlyDeletedParticleIDs.begin();
// First find all the keys in the map that are older and need to be deleted
while (iterator != _recentlyDeletedParticleIDs.end()) { while (iterator != _recentlyDeletedParticleIDs.end()) {
//qDebug() << "considering... time/key:" << iterator.key(); //qDebug() << "considering... time/key:" << iterator.key();
if (iterator.key() <= sinceTime) { if (iterator.key() <= sinceTime) {
//qDebug() << "YES older... time/key:" << iterator.key(); //qDebug() << "YES older... time/key:" << iterator.key();
_recentlyDeletedParticleIDs.remove(iterator.key()); keysToRemove << iterator.key();
} }
//qDebug() << "about to ++iterator";
++iterator; ++iterator;
} }
// Now run through the keysToRemove and remove them
foreach (uint64_t value, keysToRemove) {
//qDebug() << "removing the key, _recentlyDeletedParticleIDs.remove(value); time/key:" << value;
_recentlyDeletedParticleIDs.remove(value);
}
_recentlyDeletedParticlesLock.unlock(); _recentlyDeletedParticlesLock.unlock();
//qDebug() << "DONE forgetParticlesDeletedBefore()"; //qDebug() << "DONE forgetParticlesDeletedBefore()";
} }

View file

@ -74,8 +74,6 @@ const char* Node::getTypeName() const {
return NODE_TYPE_NAME_AUDIO_MIXER; return NODE_TYPE_NAME_AUDIO_MIXER;
case NODE_TYPE_AVATAR_MIXER: case NODE_TYPE_AVATAR_MIXER:
return NODE_TYPE_NAME_AVATAR_MIXER; return NODE_TYPE_NAME_AVATAR_MIXER;
case NODE_TYPE_AUDIO_INJECTOR:
return NODE_TYPE_NAME_AUDIO_INJECTOR;
case NODE_TYPE_ANIMATION_SERVER: case NODE_TYPE_ANIMATION_SERVER:
return NODE_TYPE_NAME_ANIMATION_SERVER; return NODE_TYPE_NAME_ANIMATION_SERVER;
case NODE_TYPE_UNASSIGNED: case NODE_TYPE_UNASSIGNED:

View file

@ -61,7 +61,7 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
_nodeSocket(this), _nodeSocket(this),
_ownerType(newOwnerType), _ownerType(newOwnerType),
_nodeTypesOfInterest(NULL), _nodeTypesOfInterest(),
_ownerUUID(QUuid::createUuid()), _ownerUUID(QUuid::createUuid()),
_numNoReplyDomainCheckIns(0), _numNoReplyDomainCheckIns(0),
_assignmentServerSocket(), _assignmentServerSocket(),
@ -75,8 +75,6 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
NodeList::~NodeList() { NodeList::~NodeList() {
delete _nodeTypesOfInterest;
clear(); clear();
} }
@ -189,7 +187,11 @@ int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr,
node->setLastHeardMicrostamp(usecTimestampNow()); node->setLastHeardMicrostamp(usecTimestampNow());
if (!senderSockAddr.isNull()) { if (!senderSockAddr.isNull()) {
activateSocketFromNodeCommunication(senderSockAddr); if (senderSockAddr == node->getPublicSocket()) {
node->activatePublicSocket();
} else if (senderSockAddr == node->getLocalSocket()) {
node->activateLocalSocket();
}
} }
if (node->getActiveSocket() || senderSockAddr.isNull()) { if (node->getActiveSocket() || senderSockAddr.isNull()) {
@ -246,19 +248,18 @@ void NodeList::reset() {
clear(); clear();
_numNoReplyDomainCheckIns = 0; _numNoReplyDomainCheckIns = 0;
delete _nodeTypesOfInterest; _nodeTypesOfInterest.clear();
_nodeTypesOfInterest = NULL;
// refresh the owner UUID // refresh the owner UUID
_ownerUUID = QUuid::createUuid(); _ownerUUID = QUuid::createUuid();
} }
void NodeList::setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest) { void NodeList::addNodeTypeToInterestSet(NODE_TYPE nodeTypeToAdd) {
delete _nodeTypesOfInterest; _nodeTypesOfInterest << nodeTypeToAdd;
}
_nodeTypesOfInterest = new char[numNodeTypesOfInterest + sizeof(char)]; void NodeList::addSetOfNodeTypesToNodeInterestSet(const QSet<NODE_TYPE>& setOfNodeTypes) {
memcpy(_nodeTypesOfInterest, nodeTypesOfInterest, numNodeTypesOfInterest); _nodeTypesOfInterest.unite(setOfNodeTypes);
_nodeTypesOfInterest[numNodeTypesOfInterest] = '\0';
} }
const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442; const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442;
@ -458,7 +459,7 @@ void NodeList::sendDomainServerCheckIn() {
sendSTUNRequest(); sendSTUNRequest();
} else { } else {
// construct the DS check in packet if we need to // construct the DS check in packet if we need to
int numBytesNodesOfInterest = _nodeTypesOfInterest ? strlen((char*) _nodeTypesOfInterest) : 0; int numBytesNodesOfInterest = _nodeTypesOfInterest.size();
const int IP_ADDRESS_BYTES = 4; const int IP_ADDRESS_BYTES = 4;
@ -499,11 +500,8 @@ void NodeList::sendDomainServerCheckIn() {
*(packetPosition++) = numBytesNodesOfInterest; *(packetPosition++) = numBytesNodesOfInterest;
// copy over the bytes for node types of interest, if required // copy over the bytes for node types of interest, if required
if (numBytesNodesOfInterest > 0) { foreach (NODE_TYPE nodeTypeOfInterest, _nodeTypesOfInterest) {
memcpy(packetPosition, *(packetPosition++) = nodeTypeOfInterest;
_nodeTypesOfInterest,
numBytesNodesOfInterest);
packetPosition += numBytesNodesOfInterest;
} }
_nodeSocket.writeDatagram((char*) checkInPacket, packetPosition - checkInPacket, _nodeSocket.writeDatagram((char*) checkInPacket, packetPosition - checkInPacket,
@ -690,7 +688,7 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt
} }
void NodeList::pingInactiveNodes() { void NodeList::pingInactiveNodes() {
foreach (const SharedNodePointer& node, _nodeHash) { foreach (const SharedNodePointer& node, getNodeHash()) {
if (!node->getActiveSocket()) { if (!node->getActiveSocket()) {
// we don't have an active link to this node, ping it to set that up // we don't have an active link to this node, ping it to set that up
pingPublicAndLocalSocketsForInactiveNode(node.data()); pingPublicAndLocalSocketsForInactiveNode(node.data());
@ -727,7 +725,7 @@ void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddre
SharedNodePointer NodeList::soloNodeOfType(char nodeType) { SharedNodePointer NodeList::soloNodeOfType(char nodeType) {
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) { if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) {
foreach (const SharedNodePointer& node, _nodeHash) { foreach (const SharedNodePointer& node, getNodeHash()) {
if (node->getType() == nodeType) { if (node->getType() == nodeType) {
return node; return node;
} }

View file

@ -22,6 +22,7 @@
#endif #endif
#include <QtCore/QMutex> #include <QtCore/QMutex>
#include <QtCore/QSet>
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtCore/QSharedPointer> #include <QtCore/QSharedPointer>
#include <QtNetwork/QHostAddress> #include <QtNetwork/QHostAddress>
@ -87,10 +88,10 @@ public:
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
void clear();
void reset(); void reset();
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest); void addNodeTypeToInterestSet(NODE_TYPE nodeTypeToAdd);
void addSetOfNodeTypesToNodeInterestSet(const QSet<NODE_TYPE>& setOfNodeTypes);
int processDomainServerList(unsigned char *packetData, size_t dataBytes); int processDomainServerList(unsigned char *packetData, size_t dataBytes);
@ -149,7 +150,7 @@ private:
HifiSockAddr _domainSockAddr; HifiSockAddr _domainSockAddr;
QUdpSocket _nodeSocket; QUdpSocket _nodeSocket;
char _ownerType; char _ownerType;
char* _nodeTypesOfInterest; QSet<NODE_TYPE> _nodeTypesOfInterest;
QUuid _ownerUUID; QUuid _ownerUUID;
int _numNoReplyDomainCheckIns; int _numNoReplyDomainCheckIns;
HifiSockAddr _assignmentServerSocket; HifiSockAddr _assignmentServerSocket;
@ -161,6 +162,7 @@ private:
void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData); void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData);
void resetDomainData(char domainField[], const char* domainData); void resetDomainData(char domainField[], const char* domainData);
void domainLookup(); void domainLookup();
void clear();
}; };
#endif /* defined(__hifi__NodeList__) */ #endif /* defined(__hifi__NodeList__) */

View file

@ -25,7 +25,6 @@ const NODE_TYPE NODE_TYPE_ENVIRONMENT_SERVER = 'E';
const NODE_TYPE NODE_TYPE_AGENT = 'I'; const NODE_TYPE NODE_TYPE_AGENT = 'I';
const NODE_TYPE NODE_TYPE_AUDIO_MIXER = 'M'; const NODE_TYPE NODE_TYPE_AUDIO_MIXER = 'M';
const NODE_TYPE NODE_TYPE_AVATAR_MIXER = 'W'; const NODE_TYPE NODE_TYPE_AVATAR_MIXER = 'W';
const NODE_TYPE NODE_TYPE_AUDIO_INJECTOR = 'A';
const NODE_TYPE NODE_TYPE_ANIMATION_SERVER = 'a'; const NODE_TYPE NODE_TYPE_ANIMATION_SERVER = 'a';
const NODE_TYPE NODE_TYPE_UNASSIGNED = 1; const NODE_TYPE NODE_TYPE_UNASSIGNED = 1;

View file

@ -68,4 +68,6 @@ void VoxelServer::beforeRun() {
qDebug("Using Minimal Environment=%s", debug::valueOf(_sendMinimalEnvironment)); qDebug("Using Minimal Environment=%s", debug::valueOf(_sendMinimalEnvironment));
} }
qDebug("Sending environments=%s", debug::valueOf(_sendEnvironments)); qDebug("Sending environments=%s", debug::valueOf(_sendEnvironments));
NodeList::getInstance()->addNodeTypeToInterestSet(NODE_TYPE_ANIMATION_SERVER);
} }

View file

@ -19,7 +19,7 @@
/// handles scripting of voxel commands from JS passed to assigned clients /// handles scripting of voxel commands from JS passed to assigned clients
class VoxelsScriptingInterface : public OctreeScriptingInterface { class VoxelsScriptingInterface : public OctreeScriptingInterface {
Q_OBJECT Q_OBJECT
public: public:
VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); } VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); }
virtual NODE_TYPE getServerNodeType() const { return NODE_TYPE_VOXEL_SERVER; } virtual NODE_TYPE getServerNodeType() const { return NODE_TYPE_VOXEL_SERVER; }