From 95971b830326026ee02aa878922a9cf3649473fe Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 14:12:42 -0700 Subject: [PATCH 01/18] rename AGENT_TYPE_VOXEL and PACKET_HEADER_DOMAIN_RFD --- animation-server/src/main.cpp | 14 +++++++------- domain-server/src/main.cpp | 6 +++--- libraries/shared/src/Agent.cpp | 6 +++--- libraries/shared/src/AgentList.cpp | 20 ++++++++------------ libraries/shared/src/AgentList.h | 11 +++++++---- libraries/shared/src/AgentTypes.h | 6 ++---- libraries/shared/src/PacketHeaders.h | 2 +- 7 files changed, 31 insertions(+), 34 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index c29521ec7d..9878d2e6a4 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -59,7 +59,7 @@ static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) { printf("sending packet of size=%d\n",sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } @@ -168,7 +168,7 @@ static void renderMovingBug() { if (::shouldShowPacketsPerSecond) { printf("sending packet of size=%d\n", sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } @@ -238,7 +238,7 @@ static void renderMovingBug() { if (::shouldShowPacketsPerSecond) { printf("sending packet of size=%d\n", sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } @@ -345,7 +345,7 @@ static void sendBlinkingStringOfLights() { if (::shouldShowPacketsPerSecond) { printf("sending packet of size=%d\n",sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } @@ -387,7 +387,7 @@ static void sendBlinkingStringOfLights() { if (::shouldShowPacketsPerSecond) { printf("sending packet of size=%d\n",sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } @@ -510,7 +510,7 @@ void sendDanceFloor() { if (::shouldShowPacketsPerSecond) { printf("sending packet of size=%d\n", sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } @@ -607,7 +607,7 @@ static void sendBillboard() { if (::shouldShowPacketsPerSecond) { printf("sending packet of size=%d\n", sizeOut); } - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 968057623f..b38ae5b824 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -98,7 +98,7 @@ int main(int argc, const char * argv[]) while (true) { if (agentList->getAgentSocket()->receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes) && - (packetData[0] == PACKET_HEADER_DOMAIN_RFD || packetData[0] == PACKET_HEADER_DOMAIN_LIST_REQUEST)) { + (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_HEADER_DOMAIN_LIST_REQUEST)) { std::map newestSoloAgents; agentType = packetData[1]; @@ -153,10 +153,10 @@ int main(int argc, const char * argv[]) // grab the ID for this agent so we can send it back with the packet packetAgentID = agent->getAgentID(); - if (packetData[0] == PACKET_HEADER_DOMAIN_RFD + if (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY && memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) { agent->setWakeMicrostamp(timeNow); - } + } } } diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 09fe6a1459..4556f670d6 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -62,7 +62,7 @@ Agent::~Agent() { // Names of Agent Types const char* AGENT_TYPE_NAME_DOMAIN = "Domain"; -const char* AGENT_TYPE_NAME_VOXEL = "Voxel Server"; +const char* AGENT_TYPE_NAME_VOXEL_SERVER = "Voxel Server"; const char* AGENT_TYPE_NAME_INTERFACE = "Client Interface"; const char* AGENT_TYPE_NAME_AUDIO_MIXER = "Audio Mixer"; const char* AGENT_TYPE_NAME_AVATAR_MIXER = "Avatar Mixer"; @@ -74,8 +74,8 @@ const char* Agent::getTypeName() const { switch (this->_type) { case AGENT_TYPE_DOMAIN: return AGENT_TYPE_NAME_DOMAIN; - case AGENT_TYPE_VOXEL: - return AGENT_TYPE_NAME_VOXEL; + case AGENT_TYPE_VOXEL_SERVER: + return AGENT_TYPE_NAME_VOXEL_SERVER; case AGENT_TYPE_AVATAR: return AGENT_TYPE_NAME_INTERFACE; case AGENT_TYPE_AUDIO_MIXER: diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 51ef88794b..53aad60cd3 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -26,7 +26,7 @@ const char SOLO_AGENT_TYPES[3] = { AGENT_TYPE_AVATAR_MIXER, AGENT_TYPE_AUDIO_MIXER, - AGENT_TYPE_VOXEL + AGENT_TYPE_VOXEL_SERVER }; char DOMAIN_HOSTNAME[] = "highfidelity.below92.com"; @@ -60,9 +60,9 @@ AgentList* AgentList::getInstance() { AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : _agentBuckets(), _numAgents(0), - agentSocket(newSocketListenPort), + _agentSocket(newSocketListenPort), _ownerType(newOwnerType), - socketListenPort(newSocketListenPort), + _socketListenPort(newSocketListenPort), _ownerID(UNKNOWN_AGENT_ID), _lastAgentID(0) { pthread_mutex_init(&mutex, 0); @@ -77,10 +77,6 @@ AgentList::~AgentList() { pthread_mutex_destroy(&mutex); } -unsigned int AgentList::getSocketListenPort() { - return socketListenPort; -} - void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { switch (((char *)packetData)[0]) { case PACKET_HEADER_DOMAIN: { @@ -88,7 +84,7 @@ void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetD break; } case PACKET_HEADER_PING: { - agentSocket.send(senderAddress, &PACKET_HEADER_PING_REPLY, 1); + _agentSocket.send(senderAddress, &PACKET_HEADER_PING_REPLY, 1); break; } case PACKET_HEADER_PING_REPLY: { @@ -233,7 +229,7 @@ Agent* AgentList::addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket newAgent->activatePublicSocket(); } - if (newAgent->getType() == AGENT_TYPE_VOXEL || + if (newAgent->getType() == AGENT_TYPE_VOXEL_SERVER || newAgent->getType() == AGENT_TYPE_AVATAR_MIXER || newAgent->getType() == AGENT_TYPE_AUDIO_MIXER) { // this is currently the cheat we use to talk directly to our test servers on EC2 @@ -247,7 +243,7 @@ Agent* AgentList::addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket } else { if (agent->getType() == AGENT_TYPE_AUDIO_MIXER || - agent->getType() == AGENT_TYPE_VOXEL || + agent->getType() == AGENT_TYPE_VOXEL_SERVER || agent->getType() == AGENT_TYPE_ANIMATION_SERVER || agent->getType() == AGENT_TYPE_AUDIO_INJECTOR) { // until the Audio class also uses our agentList, we need to update @@ -281,7 +277,7 @@ void AgentList::broadcastToAgents(unsigned char *broadcastData, size_t dataBytes // only send to the AgentTypes we are asked to send to. if (agent->getActiveSocket() != NULL && memchr(agentTypes, agent->getType(), numAgentTypes)) { // we know which socket is good for this agent, send there - agentSocket.send(agent->getActiveSocket(), broadcastData, dataBytes); + _agentSocket.send(agent->getActiveSocket(), broadcastData, dataBytes); } } } @@ -362,7 +358,7 @@ void *removeSilentAgents(void *args) { for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); ++agent) { if ((checkTimeUSecs - agent->getLastHeardMicrostamp()) > AGENT_SILENCE_THRESHOLD_USECS - && agent->getType() != AGENT_TYPE_VOXEL) { + && agent->getType() != AGENT_TYPE_VOXEL_SERVER) { printLog("Killed "); Agent::printLog(*agent); diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index 3ac7cf1f8d..e5db88569c 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -24,6 +24,7 @@ const int AGENTS_PER_BUCKET = 100; const int MAX_PACKET_SIZE = 1500; const unsigned int AGENT_SOCKET_LISTEN_PORT = 40103; + const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000; extern const char SOLO_AGENT_TYPES[3]; @@ -49,8 +50,6 @@ public: int size() { return _numAgents; } - UDPSocket* getAgentSocket() { return &agentSocket; } - void lock() { pthread_mutex_lock(&mutex); } void unlock() { pthread_mutex_unlock(&mutex); } @@ -78,6 +77,10 @@ public: uint16_t getOwnerID() const { return _ownerID; } void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; } + UDPSocket* getAgentSocket() { return &_agentSocket; } + + unsigned int getSocketListenPort() const { return _socketListenPort; }; + Agent* soloAgentOfType(char agentType); void startSilentAgentRemovalThread(); @@ -100,9 +103,9 @@ private: Agent** _agentBuckets[MAX_NUM_AGENTS / AGENTS_PER_BUCKET]; int _numAgents; - UDPSocket agentSocket; + UDPSocket _agentSocket; char _ownerType; - unsigned int socketListenPort; + unsigned int _socketListenPort; uint16_t _ownerID; uint16_t _lastAgentID; pthread_t removeSilentAgentsThread; diff --git a/libraries/shared/src/AgentTypes.h b/libraries/shared/src/AgentTypes.h index 4f3100fe03..8bc97b5ba3 100644 --- a/libraries/shared/src/AgentTypes.h +++ b/libraries/shared/src/AgentTypes.h @@ -3,11 +3,10 @@ // hifi // // Created by Brad Hefta-Gaub on 2013/04/09 -// +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // // Single byte/character Agent Types used to identify various agents in the system. // For example, an agent whose is 'V' is always a voxel server. -// #ifndef hifi_AgentTypes_h #define hifi_AgentTypes_h @@ -17,9 +16,8 @@ // If you don't then it will make things harder on your co-developers in debugging because the Agent // class won't know the name and will report it as "Unknown". -// Agent Type Codes const char AGENT_TYPE_DOMAIN = 'D'; -const char AGENT_TYPE_VOXEL = 'V'; +const char AGENT_TYPE_VOXEL_SERVER = 'V'; const char AGENT_TYPE_AVATAR = 'I'; const char AGENT_TYPE_AUDIO_MIXER = 'M'; const char AGENT_TYPE_AVATAR_MIXER = 'W'; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index f40c8abea7..89f6fbaf54 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -32,7 +32,7 @@ const PACKET_HEADER PACKET_HEADER_AVATAR_VOXEL_URL = 'U'; const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA_V2 = 'T'; const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e'; const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L'; -const PACKET_HEADER PACKET_HEADER_DOMAIN_RFD = 'C'; +const PACKET_HEADER PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY = 'C'; // These are supported Z-Command From fc27c2c7bb0c05a7f7e9249b59180f22d781d468 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 14:14:13 -0700 Subject: [PATCH 02/18] more renaming for AGENT_TYPE_VOXEL_SERVER --- interface/src/Application.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index acb82412ca..a0bf0ef705 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -418,7 +418,7 @@ static void sendVoxelServerAddScene() { char message[100]; sprintf(message,"%c%s",'Z',"add scene"); int messageSize = strlen(message) + 1; - AgentList::getInstance()->broadcastToAgents((unsigned char*)message, messageSize, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents((unsigned char*)message, messageSize, &AGENT_TYPE_VOXEL_SERVER, 1); } void Application::keyPressEvent(QKeyEvent* event) { @@ -1150,7 +1150,7 @@ static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) { int sizeOut; if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){ - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } @@ -1219,7 +1219,7 @@ bool Application::sendVoxelsOperation(VoxelNode* node, void* extraData) { // if we have room don't have room in the buffer, then send the previously generated message first if (args->bufferInUse + codeAndColorLength > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) { - AgentList::getInstance()->broadcastToAgents(args->messageBuffer, args->bufferInUse, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(args->messageBuffer, args->bufferInUse, &AGENT_TYPE_VOXEL_SERVER, 1); args->bufferInUse = sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int); // reset } @@ -1283,7 +1283,7 @@ void Application::importVoxels() { // If we have voxels left in the packet, then send the packet if (args.bufferInUse > (sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int))) { - AgentList::getInstance()->broadcastToAgents(args.messageBuffer, args.bufferInUse, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(args.messageBuffer, args.bufferInUse, &AGENT_TYPE_VOXEL_SERVER, 1); } if (calculatedOctCode) { @@ -1335,7 +1335,7 @@ void Application::pasteVoxels() { // If we have voxels left in the packet, then send the packet if (args.bufferInUse > (sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int))) { - AgentList::getInstance()->broadcastToAgents(args.messageBuffer, args.bufferInUse, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(args.messageBuffer, args.bufferInUse, &AGENT_TYPE_VOXEL_SERVER, 1); } if (calculatedOctCode) { @@ -1624,7 +1624,7 @@ void Application::updateAvatar(float deltaTime) { endOfBroadcastStringWrite += _myAvatar.getBroadcastData(endOfBroadcastStringWrite); - const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER}; + const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL_SERVER, AGENT_TYPE_AVATAR_MIXER}; AgentList::getInstance()->broadcastToAgents(broadcastString, endOfBroadcastStringWrite - broadcastString, broadcastReceivers, sizeof(broadcastReceivers)); // once in a while, send my voxel url From 17750bd5d2c63d29d65bd0cb386332ec2e2030d5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:00:33 -0700 Subject: [PATCH 03/18] remove ShareAudioFactors struct from audio-mixer --- audio-mixer/src/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 7276a24594..718dae9757 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -70,11 +70,6 @@ void attachNewBufferToAgent(Agent *newAgent) { } } -struct SharedAudioFactors { - float distanceCoefficient; - float effectMix; -}; - int main(int argc, const char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); From 1e05936aead35efad9d1a93e4c9f4b4ae97de053 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:19:12 -0700 Subject: [PATCH 04/18] unthread DS check in, allow agents to tell DS who they want to hear about --- domain-server/src/main.cpp | 14 +++- interface/src/Application.cpp | 8 +- libraries/shared/src/AgentList.cpp | 120 +++++++++++++++-------------- libraries/shared/src/AgentList.h | 32 ++++---- libraries/shared/src/AgentTypes.h | 15 ++-- 5 files changed, 105 insertions(+), 84 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index b38ae5b824..da4852c4d9 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -102,7 +102,7 @@ int main(int argc, const char * argv[]) std::map newestSoloAgents; agentType = packetData[1]; - unpackSocket(packetData + 2, (sockaddr*) &agentLocalAddress); + int numBytesSocket = unpackSocket(packetData + 2, (sockaddr*) &agentLocalAddress); // check the agent public address // if it matches our local address we're on the same box @@ -124,11 +124,19 @@ int main(int argc, const char * argv[]) agentList->increaseAgentID(); } - currentBufferPos = broadcastPacket + 1; + currentBufferPos = broadcastPacket + sizeof(PACKET_HEADER); startPointer = currentBufferPos; + char* agentTypesOfInterest = (char*) currentBufferPos + sizeof(AGENT_TYPE) + numBytesSocket; + int numInterestTypes = strlen(agentTypesOfInterest); + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType)) { + if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType) + && (numInterestTypes > 0 && memchr(agentTypesOfInterest, agent->getType(), strlen(agentTypesOfInterest)))) { + // this is not the agent themselves + // and this is an agent of a type in the passed agent types of interest + // or the agent did not pass us any specific types they are interested in + if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) { // this is an agent of which there can be multiple, just add them to the packet // don't send avatar agents to other avatars, that will come from avatar mixer diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a0bf0ef705..fe65c56424 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -207,10 +207,13 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : WSADATA WsaData; int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData); #endif + + // tell the AgentList instance who to tell the domain server we care about + const unsigned char agentTypesOfInterest[] = {AGENT_TYPE_AUDIO_MIXER, AGENT_TYPE_AVATAR_MIXER, AGENT_TYPE_VOXEL_SERVER}; + AgentList::getInstance()->setAgentTypesOfInterest(agentTypesOfInterest, sizeof(agentTypesOfInterest)); // start the agentList threads AgentList::getInstance()->startSilentAgentRemovalThread(); - AgentList::getInstance()->startDomainServerCheckInThread(); AgentList::getInstance()->startPingUnknownAgentsThread(); _window->setCentralWidget(_glWidget); @@ -749,6 +752,9 @@ void Application::timer() { if (!_serialHeadSensor.active) { _serialHeadSensor.pair(); } + + // ask the agent list to check in with the domain server + AgentList::getInstance()->sendDomainServerCheckIn(); } static glm::vec3 getFaceVector(BoxFace face) { diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 53aad60cd3..982116b39a 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -34,7 +34,6 @@ char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup const int DOMAINSERVER_PORT = 40102; bool silentAgentThreadStopFlag = false; -bool domainServerCheckinStopFlag = false; bool pingUnknownAgentThreadStopFlag = false; AgentList* AgentList::_sharedInstance = NULL; @@ -62,6 +61,7 @@ AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : _numAgents(0), _agentSocket(newSocketListenPort), _ownerType(newOwnerType), + _agentTypesOfInterest(NULL), _socketListenPort(newSocketListenPort), _ownerID(UNKNOWN_AGENT_ID), _lastAgentID(0) { @@ -69,9 +69,10 @@ AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : } AgentList::~AgentList() { + delete _agentTypesOfInterest; + // stop the spawned threads, if they were started stopSilentAgentRemovalThread(); - stopDomainServerCheckInThread(); stopPingUnknownAgentsThread(); pthread_mutex_destroy(&mutex); @@ -177,6 +178,65 @@ Agent* AgentList::agentWithID(uint16_t agentID) { return NULL; } +void AgentList::setAgentTypesOfInterest(const unsigned char* agentTypesOfInterest, int numAgentTypesOfInterest) { + delete _agentTypesOfInterest; + + _agentTypesOfInterest = new unsigned char[numAgentTypesOfInterest + sizeof(char)]; + memcpy(_agentTypesOfInterest, agentTypesOfInterest, numAgentTypesOfInterest); + _agentTypesOfInterest[numAgentTypesOfInterest] = '\0'; +} + +void AgentList::sendDomainServerCheckIn() { + static bool printedDomainServerIP = false; + // Lookup the IP address of the domain server if we need to + if (atoi(DOMAIN_IP) == 0) { + struct hostent* pHostInfo; + if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) { + sockaddr_in tempAddress; + memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); + strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr)); + printLog("Domain Server: %s \n", DOMAIN_HOSTNAME); + } else { + printLog("Failed domain server lookup\n"); + } + } else if (!printedDomainServerIP) { + printLog("Domain Server IP: %s\n", DOMAIN_IP); + printedDomainServerIP = true; + } + + // construct the DS check in packet if we need to + static unsigned char* checkInPacket = NULL; + + if (!checkInPacket) { + int numBytesAgentsOfInterest = _agentTypesOfInterest ? strlen((char*) _agentTypesOfInterest) : NULL; + printf("There are %d AOI\n", numBytesAgentsOfInterest); + // check in packet has header, agent type, port, IP, agent types of interest, null termination + int numPacketBytes = sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE) + sizeof(uint16_t) + (sizeof(char) * 4) + + numBytesAgentsOfInterest + sizeof(char); + printf("Packet as a whole will be %d\n", numPacketBytes); + + checkInPacket = new unsigned char[numPacketBytes]; + + checkInPacket[0] = (memchr(SOLO_AGENT_TYPES, _ownerType, sizeof(SOLO_AGENT_TYPES))) + ? PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY + : PACKET_HEADER_DOMAIN_LIST_REQUEST; + checkInPacket[1] = _ownerType; + + packSocket(checkInPacket + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE), getLocalAddress(), htons(_socketListenPort)); + + // copy over the bytes for agent types of interest, if required + if (numBytesAgentsOfInterest > 0) { + memcpy(checkInPacket + numPacketBytes - sizeof(char) - numBytesAgentsOfInterest, + _agentTypesOfInterest, + numBytesAgentsOfInterest); + } + + checkInPacket[numPacketBytes - 1] = '\0'; + } + + _agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, strlen((char*) checkInPacket)); +} + int AgentList::processDomainServerList(unsigned char *packetData, size_t dataBytes) { int readAgents = 0; @@ -388,62 +448,6 @@ void AgentList::stopSilentAgentRemovalThread() { pthread_join(removeSilentAgentsThread, NULL); } -void *checkInWithDomainServer(void *args) { - - const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; - - // Lookup the IP address of the domain server if we need to - if (atoi(DOMAIN_IP) == 0) { - struct hostent* pHostInfo; - if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) { - sockaddr_in tempAddress; - memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); - strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr)); - printLog("Domain Server: %s \n", DOMAIN_HOSTNAME); - - } else { - printLog("Failed lookup domainserver\n"); - } - } else printLog("Domain Server IP: %s\n", DOMAIN_IP); - - AgentList* parentAgentList = (AgentList*) args; - - timeval lastSend; - in_addr_t localAddress = getLocalAddress(); - unsigned char packet[8]; - - packet[0] = PACKET_HEADER_DOMAIN_RFD; - packet[1] = parentAgentList->getOwnerType(); - - while (!domainServerCheckinStopFlag) { - gettimeofday(&lastSend, NULL); - - packSocket(packet + 2, localAddress, htons(parentAgentList->getSocketListenPort())); - - parentAgentList->getAgentSocket()->send(DOMAIN_IP, DOMAINSERVER_PORT, packet, sizeof(packet)); - - packet[0] = PACKET_HEADER_DOMAIN_LIST_REQUEST; - - double usecToSleep = DOMAIN_SERVER_CHECK_IN_USECS - (usecTimestampNow() - usecTimestamp(&lastSend)); - - if (usecToSleep > 0) { - usleep(usecToSleep); - } - } - - pthread_exit(0); - return NULL; -} - -void AgentList::startDomainServerCheckInThread() { - pthread_create(&checkInWithDomainServerThread, NULL, checkInWithDomainServer, (void*) this); -} - -void AgentList::stopDomainServerCheckInThread() { - domainServerCheckinStopFlag = true; - pthread_join(checkInWithDomainServerThread, NULL); -} - AgentList::iterator AgentList::begin() const { Agent** agentBucket = NULL; diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index e5db88569c..2c07b7c34f 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -26,6 +26,8 @@ const int MAX_PACKET_SIZE = 1500; const unsigned int AGENT_SOCKET_LISTEN_PORT = 40103; const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000; +const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; + extern const char SOLO_AGENT_TYPES[3]; extern char DOMAIN_HOSTNAME[]; @@ -46,6 +48,18 @@ public: AgentListIterator begin() const; AgentListIterator end() const; + char getOwnerType() const { return _ownerType; } + + uint16_t getLastAgentID() const { return _lastAgentID; } + void increaseAgentID() { ++_lastAgentID; } + + uint16_t getOwnerID() const { return _ownerID; } + void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; } + + UDPSocket* getAgentSocket() { return &_agentSocket; } + + unsigned int getSocketListenPort() const { return _socketListenPort; }; + void(*linkedDataCreateCallback)(Agent *); int size() { return _numAgents; } @@ -53,6 +67,8 @@ public: void lock() { pthread_mutex_lock(&mutex); } void unlock() { pthread_mutex_unlock(&mutex); } + void setAgentTypesOfInterest(const unsigned char* agentTypesOfInterest, int numAgentTypesOfInterest); + void sendDomainServerCheckIn(); int processDomainServerList(unsigned char *packetData, size_t dataBytes); Agent* agentWithAddress(sockaddr *senderAddress); @@ -67,26 +83,11 @@ public: int updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes); void broadcastToAgents(unsigned char *broadcastData, size_t dataBytes, const char* agentTypes, int numAgentTypes); - unsigned int getSocketListenPort(); - - char getOwnerType() const { return _ownerType; } - - uint16_t getLastAgentID() const { return _lastAgentID; } - void increaseAgentID() { ++_lastAgentID; } - - uint16_t getOwnerID() const { return _ownerID; } - void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; } - - UDPSocket* getAgentSocket() { return &_agentSocket; } - - unsigned int getSocketListenPort() const { return _socketListenPort; }; Agent* soloAgentOfType(char agentType); void startSilentAgentRemovalThread(); void stopSilentAgentRemovalThread(); - void startDomainServerCheckInThread(); - void stopDomainServerCheckInThread(); void startPingUnknownAgentsThread(); void stopPingUnknownAgentsThread(); @@ -105,6 +106,7 @@ private: int _numAgents; UDPSocket _agentSocket; char _ownerType; + unsigned char* _agentTypesOfInterest; unsigned int _socketListenPort; uint16_t _ownerID; uint16_t _lastAgentID; diff --git a/libraries/shared/src/AgentTypes.h b/libraries/shared/src/AgentTypes.h index 8bc97b5ba3..56e900c923 100644 --- a/libraries/shared/src/AgentTypes.h +++ b/libraries/shared/src/AgentTypes.h @@ -16,12 +16,13 @@ // If you don't then it will make things harder on your co-developers in debugging because the Agent // class won't know the name and will report it as "Unknown". -const char AGENT_TYPE_DOMAIN = 'D'; -const char AGENT_TYPE_VOXEL_SERVER = 'V'; -const char AGENT_TYPE_AVATAR = 'I'; -const char AGENT_TYPE_AUDIO_MIXER = 'M'; -const char AGENT_TYPE_AVATAR_MIXER = 'W'; -const char AGENT_TYPE_AUDIO_INJECTOR = 'A'; -const char AGENT_TYPE_ANIMATION_SERVER = 'a'; +typedef char AGENT_TYPE; +const AGENT_TYPE AGENT_TYPE_DOMAIN = 'D'; +const AGENT_TYPE AGENT_TYPE_VOXEL_SERVER = 'V'; +const AGENT_TYPE AGENT_TYPE_AVATAR = 'I'; +const AGENT_TYPE AGENT_TYPE_AUDIO_MIXER = 'M'; +const AGENT_TYPE AGENT_TYPE_AVATAR_MIXER = 'W'; +const AGENT_TYPE AGENT_TYPE_AUDIO_INJECTOR = 'A'; +const AGENT_TYPE AGENT_TYPE_ANIMATION_SERVER = 'a'; #endif From 8c30c3ff7f8145fc127c464793fee8d62e5dcea2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:20:43 -0700 Subject: [PATCH 05/18] use new non-threaded method to checkin with domain server --- animation-server/src/main.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 9878d2e6a4..3134488157 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -702,7 +702,6 @@ int main(int argc, const char * argv[]) agentList->linkedDataCreateCallback = NULL; // do we need a callback? agentList->startSilentAgentRemovalThread(); - agentList->startDomainServerCheckInThread(); srand((unsigned)time(0)); @@ -713,16 +712,20 @@ int main(int argc, const char * argv[]) unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; ssize_t receivedBytes; + + timeval lastDomainServerCheckIn = {}; // loop to send to agents requesting data while (true) { - // Agents sending messages to us... + // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed + if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { + gettimeofday(&lastDomainServerCheckIn, NULL); + AgentList::getInstance()->sendDomainServerCheckIn(); + } + + // Agents sending messages to us... if (agentList->getAgentSocket()->receive(&agentPublicAddress, packetData, &receivedBytes)) { - switch (packetData[0]) { - default: { - AgentList::getInstance()->processAgentData(&agentPublicAddress, packetData, receivedBytes); - } break; - } + AgentList::getInstance()->processAgentData(&agentPublicAddress, packetData, receivedBytes); } } From d33f3e43bd46ccf3a19ff150a8d5a1c45e112b74 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:28:30 -0700 Subject: [PATCH 06/18] agentTypesOfInterest need not be unsigned and remove debugging --- libraries/shared/src/AgentList.cpp | 7 +++---- libraries/shared/src/AgentList.h | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 982116b39a..6f38bff519 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -178,10 +178,10 @@ Agent* AgentList::agentWithID(uint16_t agentID) { return NULL; } -void AgentList::setAgentTypesOfInterest(const unsigned char* agentTypesOfInterest, int numAgentTypesOfInterest) { +void AgentList::setAgentTypesOfInterest(const char* agentTypesOfInterest, int numAgentTypesOfInterest) { delete _agentTypesOfInterest; - _agentTypesOfInterest = new unsigned char[numAgentTypesOfInterest + sizeof(char)]; + _agentTypesOfInterest = new char[numAgentTypesOfInterest + sizeof(char)]; memcpy(_agentTypesOfInterest, agentTypesOfInterest, numAgentTypesOfInterest); _agentTypesOfInterest[numAgentTypesOfInterest] = '\0'; } @@ -209,11 +209,10 @@ void AgentList::sendDomainServerCheckIn() { if (!checkInPacket) { int numBytesAgentsOfInterest = _agentTypesOfInterest ? strlen((char*) _agentTypesOfInterest) : NULL; - printf("There are %d AOI\n", numBytesAgentsOfInterest); + // check in packet has header, agent type, port, IP, agent types of interest, null termination int numPacketBytes = sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE) + sizeof(uint16_t) + (sizeof(char) * 4) + numBytesAgentsOfInterest + sizeof(char); - printf("Packet as a whole will be %d\n", numPacketBytes); checkInPacket = new unsigned char[numPacketBytes]; diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index 2c07b7c34f..3007dbc8e3 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -67,7 +67,7 @@ public: void lock() { pthread_mutex_lock(&mutex); } void unlock() { pthread_mutex_unlock(&mutex); } - void setAgentTypesOfInterest(const unsigned char* agentTypesOfInterest, int numAgentTypesOfInterest); + void setAgentTypesOfInterest(const char* agentTypesOfInterest, int numAgentTypesOfInterest); void sendDomainServerCheckIn(); int processDomainServerList(unsigned char *packetData, size_t dataBytes); @@ -106,7 +106,7 @@ private: int _numAgents; UDPSocket _agentSocket; char _ownerType; - unsigned char* _agentTypesOfInterest; + char* _agentTypesOfInterest; unsigned int _socketListenPort; uint16_t _ownerID; uint16_t _lastAgentID; From 4715dbf412663b5ddd18488655e50d5b6a55d9fe Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:29:26 -0700 Subject: [PATCH 07/18] ask only for agents of type AGENT_TYPE_VOXEL_SERVER --- animation-server/src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 3134488157..c02e8e8383 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -714,6 +714,7 @@ int main(int argc, const char * argv[]) ssize_t receivedBytes; timeval lastDomainServerCheckIn = {}; + AgentList::getInstance()->setAgentTypesOfInterest(&AGENT_TYPE_VOXEL_SERVER, 1); // loop to send to agents requesting data while (true) { From 0585d6756de1a35b106cb2bdad3fcf72b3d8f49b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:34:30 -0700 Subject: [PATCH 08/18] if an agent doesn't send a list of types of interest assume it wants to hear about nobody --- domain-server/src/main.cpp | 77 ++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index da4852c4d9..3bc40efc07 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -130,49 +130,52 @@ int main(int argc, const char * argv[]) char* agentTypesOfInterest = (char*) currentBufferPos + sizeof(AGENT_TYPE) + numBytesSocket; int numInterestTypes = strlen(agentTypesOfInterest); - for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType) - && (numInterestTypes > 0 && memchr(agentTypesOfInterest, agent->getType(), strlen(agentTypesOfInterest)))) { - // this is not the agent themselves - // and this is an agent of a type in the passed agent types of interest - // or the agent did not pass us any specific types they are interested in + if (numInterestTypes > 0) { + // if the agent has sent no types of interest, assume they want nothing but their own ID back + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { + if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType) + && memchr(agentTypesOfInterest, agent->getType(), strlen(agentTypesOfInterest))) { + // this is not the agent themselves + // and this is an agent of a type in the passed agent types of interest + // or the agent did not pass us any specific types they are interested in - if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) { - // this is an agent of which there can be multiple, just add them to the packet - // don't send avatar agents to other avatars, that will come from avatar mixer - if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) { - currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); + if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) { + // this is an agent of which there can be multiple, just add them to the packet + // don't send avatar agents to other avatars, that will come from avatar mixer + if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) { + currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); + } + + } else { + // solo agent, we need to only send newest + if (newestSoloAgents[agent->getType()] == NULL || + newestSoloAgents[agent->getType()]->getWakeMicrostamp() < agent->getWakeMicrostamp()) { + // we have to set the newer solo agent to add it to the broadcast later + newestSoloAgents[agent->getType()] = &(*agent); + } } - } else { - // solo agent, we need to only send newest - if (newestSoloAgents[agent->getType()] == NULL || - newestSoloAgents[agent->getType()]->getWakeMicrostamp() < agent->getWakeMicrostamp()) { - // we have to set the newer solo agent to add it to the broadcast later - newestSoloAgents[agent->getType()] = &(*agent); - } - } - } else { - double timeNow = usecTimestampNow(); - - // this is the agent, just update last receive to now - agent->setLastHeardMicrostamp(timeNow); - - // grab the ID for this agent so we can send it back with the packet - packetAgentID = agent->getAgentID(); - - if (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY - && memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) { + double timeNow = usecTimestampNow(); + + // this is the agent, just update last receive to now + agent->setLastHeardMicrostamp(timeNow); + + // grab the ID for this agent so we can send it back with the packet + packetAgentID = agent->getAgentID(); + + if (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY + && memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) { agent->setWakeMicrostamp(timeNow); + } } } - } - - for (std::map::iterator soloAgent = newestSoloAgents.begin(); - soloAgent != newestSoloAgents.end(); - soloAgent++) { - // this is the newest alive solo agent, add them to the packet - currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, soloAgent->second); + + for (std::map::iterator soloAgent = newestSoloAgents.begin(); + soloAgent != newestSoloAgents.end(); + soloAgent++) { + // this is the newest alive solo agent, add them to the packet + currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, soloAgent->second); + } } // add the agent ID to the end of the pointer From d95d3eba3b979cf6453881ad6cf8f183283e5661 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:35:17 -0700 Subject: [PATCH 09/18] hook audio-mixer up to new domain server check in method --- audio-mixer/src/main.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 718dae9757..c9ea474354 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -80,7 +80,6 @@ int main(int argc, const char* argv[]) { agentList->linkedDataCreateCallback = attachNewBufferToAgent; agentList->startSilentAgentRemovalThread(); - agentList->startDomainServerCheckInThread(); unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; @@ -99,7 +98,16 @@ int main(int argc, const char* argv[]) { gettimeofday(&startTime, NULL); + timeval lastDomainServerCheckIn = {}; + while (true) { + + // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed + if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { + gettimeofday(&lastDomainServerCheckIn, NULL); + AgentList::getInstance()->sendDomainServerCheckIn(); + } + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { PositionalAudioRingBuffer* positionalRingBuffer = (PositionalAudioRingBuffer*) agent->getLinkedData(); From dae8032cd8c52123d909c0e13dad84e1ff57585b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:35:33 -0700 Subject: [PATCH 10/18] hook the avatar mixer up to the new domain server check in method --- avatar-mixer/src/main.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index 0398a597fc..aace967564 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -66,7 +66,6 @@ int main(int argc, const char* argv[]) { agentList->linkedDataCreateCallback = attachAvatarDataToAgent; - agentList->startDomainServerCheckInThread(); agentList->startSilentAgentRemovalThread(); sockaddr *agentAddress = new sockaddr; @@ -80,8 +79,19 @@ int main(int argc, const char* argv[]) { uint16_t agentID = 0; Agent* avatarAgent = NULL; - + + timeval lastDomainServerCheckIn = {}; + // we only need to hear back about avatar agents from the DS + AgentList::getInstance()->setAgentTypesOfInterest(&AGENT_TYPE_AVATAR, 1); + while (true) { + + // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed + if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { + gettimeofday(&lastDomainServerCheckIn, NULL); + AgentList::getInstance()->sendDomainServerCheckIn(); + } + if (agentList->getAgentSocket()->receive(agentAddress, packetData, &receivedBytes)) { switch (packetData[0]) { case PACKET_HEADER_HEAD_DATA: @@ -129,7 +139,6 @@ int main(int argc, const char* argv[]) { } agentList->stopSilentAgentRemovalThread(); - agentList->stopDomainServerCheckInThread(); return 0; } From 5efff3857a07176763e3755cde95cffd0a696572 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Jun 2013 15:39:46 -0700 Subject: [PATCH 11/18] hook eve up to new domain server check in method --- eve/src/main.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index c670be050e..387c72633b 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -82,9 +82,6 @@ int main(int argc, const char* argv[]) { // create an AgentList instance to handle communication with other agents AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR, EVE_AGENT_LISTEN_PORT); - // start telling the domain server that we are alive - agentList->startDomainServerCheckInThread(); - // start the agent list thread that will kill off agents when they stop talking agentList->startSilentAgentRemovalThread(); @@ -134,8 +131,20 @@ int main(int argc, const char* argv[]) { double numMicrosecondsSleep = 0; int handStateTimer = 0; + + timeval lastDomainServerCheckIn = {}; + + // eve wants to hear about an avatar mixer and an audio mixer from the domain server + const char EVE_AGENT_TYPES_OF_INTEREST[] = {AGENT_TYPE_AVATAR_MIXER, AGENT_TYPE_AUDIO_MIXER}; + AgentList::getInstance()->setAgentTypesOfInterest(EVE_AGENT_TYPES_OF_INTEREST, sizeof(EVE_AGENT_TYPES_OF_INTEREST)); while (true) { + // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed + if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { + gettimeofday(&lastDomainServerCheckIn, NULL); + AgentList::getInstance()->sendDomainServerCheckIn(); + } + // update the thisSend timeval to the current time gettimeofday(&thisSend, NULL); @@ -201,7 +210,6 @@ int main(int argc, const char* argv[]) { pthread_join(receiveAgentDataThread, NULL); // stop the agent list's threads - agentList->stopDomainServerCheckInThread(); agentList->stopPingUnknownAgentsThread(); agentList->stopSilentAgentRemovalThread(); } \ No newline at end of file From fc3fb7d3f041559e0e8e87344a46f33134b7f0ea Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 10 Jun 2013 11:46:06 -0700 Subject: [PATCH 12/18] fixed bug with loading of corrupt settings file where NaN returned for avatar position details --- interface/src/Application.cpp | 40 ++++++++++++++++++++++++++--------- interface/src/Avatar.cpp | 24 ++++++++++----------- interface/src/Util.cpp | 10 +++++++++ interface/src/Util.h | 4 ++++ 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eb03e1f592..5aafd9f4a6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2573,20 +2573,40 @@ void Application::saveAction(QSettings* set, QAction* action) { set->setValue(action->text(), action->isChecked()); } -void Application::loadSettings(QSettings* set) { - if (!set) set = getSettings(); +void Application::loadSettings(QSettings* settings) { + if (!settings) settings = getSettings(); - _headCameraPitchYawScale = set->value("headCameraPitchYawScale", 0.0f).toFloat(); - scanMenuBar(&Application::loadAction, set); - getAvatar()->loadData(set); + _headCameraPitchYawScale = settings->value("headCameraPitchYawScale", 0.0f).toFloat(); + + settings->beginGroup("View Frustum Offset Camera"); + // in case settings is corrupt or missing loadSetting() will check for NaN + _viewFrustumOffsetYaw = loadSetting(settings, "viewFrustumOffsetYaw" , 0.0f); + _viewFrustumOffsetPitch = loadSetting(settings, "viewFrustumOffsetPitch" , 0.0f); + _viewFrustumOffsetRoll = loadSetting(settings, "viewFrustumOffsetRoll" , 0.0f); + _viewFrustumOffsetDistance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f); + _viewFrustumOffsetUp = loadSetting(settings, "viewFrustumOffsetUp" , 0.0f); + settings->endGroup(); + + scanMenuBar(&Application::loadAction, settings); + getAvatar()->loadData(settings); } -void Application::saveSettings(QSettings* set) { - if (!set) set = getSettings(); - set->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); - scanMenuBar(&Application::saveAction, set); - getAvatar()->saveData(set); +void Application::saveSettings(QSettings* settings) { + if (!settings) settings = getSettings(); + + settings->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); + + settings->beginGroup("View Frustum Offset Camera"); + settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffsetYaw); + settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffsetPitch); + settings->setValue("viewFrustumOffsetRoll", _viewFrustumOffsetRoll); + settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffsetDistance); + settings->setValue("viewFrustumOffsetUp", _viewFrustumOffsetUp); + settings->endGroup(); + + scanMenuBar(&Application::saveAction, settings); + getAvatar()->saveData(settings); } void Application::importSettings() { diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index e5c5a76a70..32b35aebac 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1212,22 +1212,20 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) { } +void Avatar::loadData(QSettings* settings) { + settings->beginGroup("Avatar"); - -void Avatar::loadData(QSettings* set) { - set->beginGroup("Avatar"); + // in case settings is corrupt or missing loadSetting() will check for NaN + _bodyYaw = loadSetting(settings, "bodyYaw" , 0.0f); + _bodyPitch = loadSetting(settings, "bodyPitch", 0.0f); + _bodyRoll = loadSetting(settings, "bodyRoll" , 0.0f); + _position.x = loadSetting(settings, "position_x", 0.0f); + _position.y = loadSetting(settings, "position_y", 0.0f); + _position.z = loadSetting(settings, "position_z", 0.0f); - _bodyYaw = set->value("bodyYaw", _bodyYaw).toFloat(); - _bodyPitch = set->value("bodyPitch", _bodyPitch).toFloat(); - _bodyRoll = set->value("bodyRoll", _bodyRoll).toFloat(); + _voxels.setVoxelURL(settings->value("voxelURL").toUrl()); - _position.x = set->value("position_x", _position.x).toFloat(); - _position.y = set->value("position_y", _position.y).toFloat(); - _position.z = set->value("position_z", _position.z).toFloat(); - - _voxels.setVoxelURL(set->value("voxelURL").toUrl()); - - set->endGroup(); + settings->endGroup(); } void Avatar::getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const { diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 9a31af93f4..5c9d0c8984 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -498,6 +498,16 @@ void runTimingTests() { } +float loadSetting(QSettings* settings, const char* name, float defaultValue) { + float value = settings->value(name, 0.0f).toFloat(); + if (isnan(value)) { + value = defaultValue; + } + return value; +} + + + diff --git a/interface/src/Util.h b/interface/src/Util.h index 3e084fd16d..6cac785956 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -17,6 +17,7 @@ #include #include +#include // the standard sans serif font family #define SANS_FONT_FAMILY "Helvetica" @@ -66,4 +67,7 @@ void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int void runTimingTests(); + +float loadSetting(QSettings* settings, const char* name, float defaultValue); + #endif From ed79a9f72aff5c8c598a38f4146d2c859df0bd48 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Jun 2013 12:18:25 -0700 Subject: [PATCH 13/18] prepend the agent types of interest with the number that follow --- domain-server/src/main.cpp | 6 +++--- libraries/shared/src/AgentList.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 3bc40efc07..6988137455 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -127,14 +127,14 @@ int main(int argc, const char * argv[]) currentBufferPos = broadcastPacket + sizeof(PACKET_HEADER); startPointer = currentBufferPos; - char* agentTypesOfInterest = (char*) currentBufferPos + sizeof(AGENT_TYPE) + numBytesSocket; - int numInterestTypes = strlen(agentTypesOfInterest); + char* agentTypesOfInterest = (char*) currentBufferPos + sizeof(AGENT_TYPE) + numBytesSocket + sizeof(unsigned char); + int numInterestTypes = *(agentTypesOfInterest - 1); if (numInterestTypes > 0) { // if the agent has sent no types of interest, assume they want nothing but their own ID back for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType) - && memchr(agentTypesOfInterest, agent->getType(), strlen(agentTypesOfInterest))) { + && memchr(agentTypesOfInterest, agent->getType(), numInterestTypes)) { // this is not the agent themselves // and this is an agent of a type in the passed agent types of interest // or the agent did not pass us any specific types they are interested in diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 6f38bff519..1da6b90c2d 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -208,11 +208,11 @@ void AgentList::sendDomainServerCheckIn() { static unsigned char* checkInPacket = NULL; if (!checkInPacket) { - int numBytesAgentsOfInterest = _agentTypesOfInterest ? strlen((char*) _agentTypesOfInterest) : NULL; + int numBytesAgentsOfInterest = _agentTypesOfInterest ? strlen((char*) _agentTypesOfInterest) : 0; // check in packet has header, agent type, port, IP, agent types of interest, null termination int numPacketBytes = sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE) + sizeof(uint16_t) + (sizeof(char) * 4) + - numBytesAgentsOfInterest + sizeof(char); + numBytesAgentsOfInterest + sizeof(unsigned char); checkInPacket = new unsigned char[numPacketBytes]; @@ -223,14 +223,15 @@ void AgentList::sendDomainServerCheckIn() { packSocket(checkInPacket + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE), getLocalAddress(), htons(_socketListenPort)); + // add the number of bytes for agent types of interest + checkInPacket[numPacketBytes] = numBytesAgentsOfInterest; + // copy over the bytes for agent types of interest, if required if (numBytesAgentsOfInterest > 0) { - memcpy(checkInPacket + numPacketBytes - sizeof(char) - numBytesAgentsOfInterest, + memcpy(checkInPacket + numPacketBytes + sizeof(unsigned char), _agentTypesOfInterest, numBytesAgentsOfInterest); } - - checkInPacket[numPacketBytes - 1] = '\0'; } _agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, strlen((char*) checkInPacket)); From 7fb42dcb8a089549e01d636040215e9a797c58ce Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Jun 2013 13:48:34 -0700 Subject: [PATCH 14/18] fix bug with sent and received agent interest packets --- domain-server/src/main.cpp | 6 ++++-- interface/src/Application.cpp | 2 +- libraries/shared/src/AgentList.cpp | 16 +++++++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 6988137455..b1e2117db3 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -102,7 +102,8 @@ int main(int argc, const char * argv[]) std::map newestSoloAgents; agentType = packetData[1]; - int numBytesSocket = unpackSocket(packetData + 2, (sockaddr*) &agentLocalAddress); + int numBytesSocket = unpackSocket(packetData + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE), + (sockaddr*) &agentLocalAddress); // check the agent public address // if it matches our local address we're on the same box @@ -127,7 +128,8 @@ int main(int argc, const char * argv[]) currentBufferPos = broadcastPacket + sizeof(PACKET_HEADER); startPointer = currentBufferPos; - char* agentTypesOfInterest = (char*) currentBufferPos + sizeof(AGENT_TYPE) + numBytesSocket + sizeof(unsigned char); + unsigned char* agentTypesOfInterest = packetData + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE) + + numBytesSocket + sizeof(unsigned char); int numInterestTypes = *(agentTypesOfInterest - 1); if (numInterestTypes > 0) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fe65c56424..df9321a977 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -209,7 +209,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : #endif // tell the AgentList instance who to tell the domain server we care about - const unsigned char agentTypesOfInterest[] = {AGENT_TYPE_AUDIO_MIXER, AGENT_TYPE_AVATAR_MIXER, AGENT_TYPE_VOXEL_SERVER}; + const char agentTypesOfInterest[] = {AGENT_TYPE_AUDIO_MIXER, AGENT_TYPE_AVATAR_MIXER, AGENT_TYPE_VOXEL_SERVER}; AgentList::getInstance()->setAgentTypesOfInterest(agentTypesOfInterest, sizeof(agentTypesOfInterest)); // start the agentList threads diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 1da6b90c2d..42a735a1e3 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -215,23 +215,29 @@ void AgentList::sendDomainServerCheckIn() { numBytesAgentsOfInterest + sizeof(unsigned char); checkInPacket = new unsigned char[numPacketBytes]; + unsigned char* packetPosition = checkInPacket; - checkInPacket[0] = (memchr(SOLO_AGENT_TYPES, _ownerType, sizeof(SOLO_AGENT_TYPES))) + *(packetPosition++) = (memchr(SOLO_AGENT_TYPES, _ownerType, sizeof(SOLO_AGENT_TYPES))) ? PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY : PACKET_HEADER_DOMAIN_LIST_REQUEST; - checkInPacket[1] = _ownerType; + *(packetPosition++) = _ownerType; - packSocket(checkInPacket + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE), getLocalAddress(), htons(_socketListenPort)); + packetPosition += packSocket(checkInPacket + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE), + getLocalAddress(), + htons(_socketListenPort)); // add the number of bytes for agent types of interest - checkInPacket[numPacketBytes] = numBytesAgentsOfInterest; + *(packetPosition++) = numBytesAgentsOfInterest; // copy over the bytes for agent types of interest, if required if (numBytesAgentsOfInterest > 0) { - memcpy(checkInPacket + numPacketBytes + sizeof(unsigned char), + memcpy(packetPosition, _agentTypesOfInterest, numBytesAgentsOfInterest); + packetPosition += numBytesAgentsOfInterest; } + + *packetPosition = '\0'; } _agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, strlen((char*) checkInPacket)); From 2e99ae199ee0e93364731dafcdea8d8421111aed Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Jun 2013 13:48:51 -0700 Subject: [PATCH 15/18] hook injector up to new domain-server interest list --- injector/src/main.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/injector/src/main.cpp b/injector/src/main.cpp index 41e2bc0bbd..f2e87990d1 100644 --- a/injector/src/main.cpp +++ b/injector/src/main.cpp @@ -167,9 +167,6 @@ int main(int argc, char* argv[]) { pthread_t receiveAgentDataThread; pthread_create(&receiveAgentDataThread, NULL, receiveAgentData, NULL); - // start telling the domain server that we are alive - agentList->startDomainServerCheckInThread(); - // start the agent list thread that will kill off agents when they stop talking agentList->startSilentAgentRemovalThread(); @@ -192,7 +189,20 @@ int main(int argc, char* argv[]) { timeval thisSend; double numMicrosecondsSleep = 0; + timeval lastDomainServerCheckIn = {}; + + // the audio injector needs to know about the avatar mixer and the audio mixer + const char INJECTOR_AGENTS_OF_INTEREST[] = {AGENT_TYPE_AVATAR_MIXER, AGENT_TYPE_AUDIO_MIXER}; + AgentList::getInstance()->setAgentTypesOfInterest(INJECTOR_AGENTS_OF_INTEREST, sizeof(INJECTOR_AGENTS_OF_INTEREST)); + while (true) { + + // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed + if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { + gettimeofday(&lastDomainServerCheckIn, NULL); + AgentList::getInstance()->sendDomainServerCheckIn(); + } + if (::triggerDistance) { // update the thisSend timeval to the current time @@ -260,7 +270,6 @@ int main(int argc, char* argv[]) { pthread_join(receiveAgentDataThread, NULL); // stop the agent list's threads - agentList->stopDomainServerCheckInThread(); agentList->stopSilentAgentRemovalThread(); } } From ae0ef412a326576e28f3f70c36febd3c4c61979e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Jun 2013 13:54:18 -0700 Subject: [PATCH 16/18] hook up voxel-server to domain-server interest list --- voxel-server/src/main.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 81a92d4d07..2d6cd4d991 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -460,7 +460,7 @@ int main(int argc, const char * argv[]) { pthread_mutex_init(&::treeLock, NULL); - AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); + AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL_SERVER, VOXEL_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); // Handle Local Domain testing with the --local command line @@ -474,7 +474,6 @@ int main(int argc, const char * argv[]) { agentList->linkedDataCreateCallback = &attachVoxelAgentDataToAgent; agentList->startSilentAgentRemovalThread(); - agentList->startDomainServerCheckInThread(); srand((unsigned)time(0)); @@ -577,10 +576,19 @@ int main(int argc, const char * argv[]) { unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; ssize_t receivedBytes; + + timeval lastDomainServerCheckIn = {}; // loop to send to agents requesting data - while (true) { + while (true) { + + // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed + if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { + gettimeofday(&lastDomainServerCheckIn, NULL); + AgentList::getInstance()->sendDomainServerCheckIn(); + } + // check to see if we need to persist our voxel state persistVoxelsWhenDirty(); From b15f5a721b460160ba0b189aff6210283b432e34 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Jun 2013 14:03:34 -0700 Subject: [PATCH 17/18] remove hacked method to keep servers alive --- libraries/shared/src/AgentList.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 42a735a1e3..9c309bb23f 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -309,9 +309,7 @@ Agent* AgentList::addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket } else { if (agent->getType() == AGENT_TYPE_AUDIO_MIXER || - agent->getType() == AGENT_TYPE_VOXEL_SERVER || - agent->getType() == AGENT_TYPE_ANIMATION_SERVER || - agent->getType() == AGENT_TYPE_AUDIO_INJECTOR) { + agent->getType() == AGENT_TYPE_VOXEL_SERVER) { // until the Audio class also uses our agentList, we need to update // the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously agent->setLastHeardMicrostamp(usecTimestampNow()); From 27f8f5dcb8c16e4a00770de973597104de62914b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 10 Jun 2013 14:50:04 -0700 Subject: [PATCH 18/18] fix CR feedback --- interface/src/Application.cpp | 11 +++++++---- interface/src/Util.cpp | 9 +-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5aafd9f4a6..01c97766c6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2574,9 +2574,11 @@ void Application::saveAction(QSettings* set, QAction* action) { } void Application::loadSettings(QSettings* settings) { - if (!settings) settings = getSettings(); + if (!settings) { + settings = getSettings(); + } - _headCameraPitchYawScale = settings->value("headCameraPitchYawScale", 0.0f).toFloat(); + _headCameraPitchYawScale = loadSetting(settings, "headCameraPitchYawScale", 0.0f); settings->beginGroup("View Frustum Offset Camera"); // in case settings is corrupt or missing loadSetting() will check for NaN @@ -2593,10 +2595,11 @@ void Application::loadSettings(QSettings* settings) { void Application::saveSettings(QSettings* settings) { - if (!settings) settings = getSettings(); + if (!settings) { + settings = getSettings(); + } settings->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); - settings->beginGroup("View Frustum Offset Camera"); settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffsetYaw); settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffsetPitch); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 5c9d0c8984..74fe5abd1c 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -497,17 +497,10 @@ void runTimingTests() { } - float loadSetting(QSettings* settings, const char* name, float defaultValue) { float value = settings->value(name, 0.0f).toFloat(); if (isnan(value)) { value = defaultValue; } return value; -} - - - - - - +} \ No newline at end of file