diff --git a/VoxelScriptingInterface.cpp b/VoxelScriptingInterface.cpp deleted file mode 100644 index 901bb06750..0000000000 --- a/VoxelScriptingInterface.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// -// VoxelScriptingInterface.cpp -// hifi -// -// Created by Stephen Birarda on 9/17/13. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. -// - -#include "VoxelScriptingInterface.h" diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index ac6f1eca4f..a2d96c6a1c 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -15,18 +15,22 @@ #include "Agent.h" #include "voxels/VoxelScriptingInterface.h" -Agent::Agent() : - _shouldStop(false) -{ +Agent::Agent(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { } -void Agent::run(QUrl scriptURL) { +void Agent::run() { NodeList::getInstance()->setOwnerType(NODE_TYPE_AGENT); NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_VOXEL_SERVER, 1); QNetworkAccessManager manager; + // figure out the URL for the script for this agent assignment + QString scriptURLString("http://%1:8080/assignment/%2"); + scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainIP(), + this->getUUIDStringWithoutCurlyBraces()); + QUrl scriptURL(scriptURLString); + qDebug() << "Attemping download of " << scriptURL << "\n"; QNetworkReply* reply = manager.get(QNetworkRequest(scriptURL)); diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 45d0beb650..5e0765fd33 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -9,19 +9,19 @@ #ifndef __hifi__Agent__ #define __hifi__Agent__ -#include "SharedUtil.h" - #include #include -class Agent : public QObject { +#include + +class Agent : public Assignment { Q_OBJECT public: - Agent(); + Agent(const unsigned char* dataBuffer, int numBytes); bool volatile _shouldStop; - void run(QUrl scriptUrl); + void run(); signals: void preSendCallback(); }; diff --git a/assignment-client/src/AssignmentFactory.cpp b/assignment-client/src/AssignmentFactory.cpp new file mode 100644 index 0000000000..a3aa657943 --- /dev/null +++ b/assignment-client/src/AssignmentFactory.cpp @@ -0,0 +1,36 @@ +// +// AssignmentFactory.cpp +// hifi +// +// Created by Stephen Birarda on 9/17/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include + +#include "Agent.h" +#include "audio/AudioMixer.h" +#include "avatars/AvatarMixer.h" +#include + +#include "AssignmentFactory.h" + +Assignment* AssignmentFactory::unpackAssignment(const unsigned char* dataBuffer, int numBytes) { + int headerBytes = numBytesForPacketHeader(dataBuffer); + + Assignment::Type assignmentType = Assignment::AllTypes; + memcpy(&assignmentType, dataBuffer + headerBytes, sizeof(Assignment::Type)); + + switch (assignmentType) { + case Assignment::AudioMixerType: + return new AudioMixer(dataBuffer, numBytes); + case Assignment::AvatarMixerType: + return new AvatarMixer(dataBuffer, numBytes); + case Assignment::AgentType: + return new Agent(dataBuffer, numBytes); + case Assignment::VoxelServerType: + return new VoxelServer(dataBuffer, numBytes); + default: + return new Assignment(dataBuffer, numBytes); + } +} \ No newline at end of file diff --git a/assignment-client/src/AssignmentFactory.h b/assignment-client/src/AssignmentFactory.h new file mode 100644 index 0000000000..8adadb07ed --- /dev/null +++ b/assignment-client/src/AssignmentFactory.h @@ -0,0 +1,19 @@ +// +// AssignmentFactory.h +// hifi +// +// Created by Stephen Birarda on 9/17/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AssignmentFactory__ +#define __hifi__AssignmentFactory__ + +#include "Assignment.h" + +class AssignmentFactory { +public: + static Assignment* unpackAssignment(const unsigned char* dataBuffer, int numBytes); +}; + +#endif /* defined(__hifi__AssignmentFactory__) */ diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index d4b6097134..930b44dbce 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -69,6 +69,10 @@ void attachNewBufferToNode(Node *newNode) { } } +AudioMixer::AudioMixer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { + +} + void AudioMixer::run() { // change the logging target name while this is running Logging::setTargetName(AUDIO_MIXER_LOGGING_TARGET_NAME); diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index fa67d55bca..565bae180a 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -9,11 +9,15 @@ #ifndef __hifi__AudioMixer__ #define __hifi__AudioMixer__ +#include + /// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients. -class AudioMixer { +class AudioMixer : public Assignment { public: + AudioMixer(const unsigned char* dataBuffer, int numBytes); + /// runs the audio mixer - static void run(); + void run(); }; #endif /* defined(__hifi__AudioMixer__) */ diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index acf77be8da..604301a391 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -83,6 +83,10 @@ void broadcastAvatarData(NodeList* nodeList, sockaddr* nodeAddress) { nodeList->getNodeSocket()->send(nodeAddress, broadcastPacket, currentBufferPosition - broadcastPacket); } +AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { + +} + void AvatarMixer::run() { // change the logging target name while AvatarMixer is running Logging::setTargetName(AVATAR_MIXER_LOGGING_NAME); diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index 7e58e067ce..41a584a296 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -9,13 +9,15 @@ #ifndef __hifi__AvatarMixer__ #define __hifi__AvatarMixer__ -#include +#include /// Handles assignments of type AvatarMixer - distribution of avatar data to various clients -class AvatarMixer { +class AvatarMixer : public Assignment { public: + AvatarMixer(const unsigned char* dataBuffer, int numBytes); + /// runs the avatar mixer - static void run(); + void run(); }; #endif /* defined(__hifi__AvatarMixer__) */ diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index f287e1066e..0b9da7fa70 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -14,16 +14,19 @@ #include -#include "Agent.h" -#include -#include "audio/AudioMixer.h" -#include "avatars/AvatarMixer.h" + #include #include #include #include #include +#include "Agent.h" +#include "Assignment.h" +#include "AssignmentFactory.h" +#include "audio/AudioMixer.h" +#include "avatars/AvatarMixer.h" + const long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000; const char PARENT_TARGET_NAME[] = "assignment-client-monitor"; const char CHILD_TARGET_NAME[] = "assignment-client"; @@ -32,7 +35,6 @@ pid_t* childForks = NULL; sockaddr_in customAssignmentSocket = {}; int numForks = 0; Assignment::Type overiddenAssignmentType = Assignment::AllTypes; -std::vector voxelServers; void childClient() { // this is one of the child forks or there is a single assignment client, continue assignment-client execution @@ -74,13 +76,13 @@ void childClient() { && packetVersionMatch(packetData)) { // construct the deployed assignment from the packet data - Assignment deployedAssignment(packetData, receivedBytes); + Assignment* deployedAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes); qDebug() << "Received an assignment -" << deployedAssignment << "\n"; // switch our nodelist DOMAIN_IP if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT || - deployedAssignment.getAttachedPublicSocket()->sa_family == AF_INET) { + deployedAssignment->getAttachedPublicSocket()->sa_family == AF_INET) { in_addr domainSocketAddr = {}; @@ -89,38 +91,24 @@ void childClient() { domainSocketAddr = senderSocket.sin_addr; } else { // grab the domain server IP address from the packet from the AS - domainSocketAddr = ((sockaddr_in*) deployedAssignment.getAttachedPublicSocket())->sin_addr; + domainSocketAddr = ((sockaddr_in*) deployedAssignment->getAttachedPublicSocket())->sin_addr; } nodeList->setDomainIP(inet_ntoa(domainSocketAddr)); qDebug("Destination IP for assignment is %s\n", inet_ntoa(domainSocketAddr)); - if (deployedAssignment.getType() == Assignment::AudioMixerType) { - AudioMixer::run(); - } else if (deployedAssignment.getType() == Assignment::AvatarMixerType) { - AvatarMixer::run(); - } else if (deployedAssignment.getType() == Assignment::VoxelServerType) { - VoxelServer* voxelServer = new VoxelServer(); - ::voxelServers.push_back(voxelServer); - voxelServer->run((const char*)deployedAssignment.getPayload()); - } else { - // figure out the URL for the script for this agent assignment - QString scriptURLString("http://%1:8080/assignment/%2"); - scriptURLString = scriptURLString.arg(inet_ntoa(domainSocketAddr), - deployedAssignment.getUUIDStringWithoutCurlyBraces()); - - qDebug() << "Starting an Agent assignment-client with script at" << scriptURLString << "\n"; - - Agent scriptAgent; - scriptAgent.run(QUrl(scriptURLString)); - } + // run the deployed assignment + deployedAssignment->run(); } else { qDebug("Received a bad destination socket for assignment.\n"); } qDebug("Assignment finished or never started - waiting for new assignment\n"); + // delete the deployedAssignment + delete deployedAssignment; + // reset our NodeList by switching back to unassigned and clearing the list nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); nodeList->clear(); @@ -166,12 +154,6 @@ void sigchldHandler(int sig) { } } - // cleanup voxelServers - for (int i = 0; i < ::voxelServers.size(); i++) { - VoxelServer* voxelServer = ::voxelServers[i]; - delete voxelServer; - } - } void parentMonitor() { diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index ec7a4a8897..a4f7b7d6fb 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -346,6 +346,9 @@ int main(int argc, const char* argv[]) { if (requestAssignment.getType() == Assignment::AllTypes || (*assignment)->getType() == requestAssignment.getType()) { + // attach our local socket to the assignment + (*assignment)->setAttachedLocalSocket((sockaddr*) &localSocket); + // give this assignment out, either the type matches or the requestor said they will take any int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT); int numAssignmentBytes = (*assignment)->packToBuffer(broadcastPacket + numHeaderBytes); diff --git a/libraries/shared/src/Assignment.cpp b/libraries/shared/src/Assignment.cpp index 9c0bf751e8..239212a660 100644 --- a/libraries/shared/src/Assignment.cpp +++ b/libraries/shared/src/Assignment.cpp @@ -58,15 +58,15 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) : numBytesRead += numBytesForPacketHeader(dataBuffer); + memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type)); + numBytesRead += sizeof(Assignment::Type); + if (dataBuffer[0] != PACKET_TYPE_REQUEST_ASSIGNMENT) { // read the GUID for this assignment _uuid = QUuid::fromRfc4122(QByteArray((const char*) dataBuffer + numBytesRead, NUM_BYTES_RFC4122_UUID)); numBytesRead += NUM_BYTES_RFC4122_UUID; } - memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type)); - numBytesRead += sizeof(Assignment::Type); - if (_command != Assignment::RequestCommand) { sockaddr* newSocket = NULL; @@ -149,15 +149,15 @@ void Assignment::setAttachedLocalSocket(const sockaddr* attachedLocalSocket) { int Assignment::packToBuffer(unsigned char* buffer) { int numPackedBytes = 0; - // pack the UUID for this assignment, if this is an assignment create or deploy - if (_command != Assignment::RequestCommand) { - memcpy(buffer, _uuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); - numPackedBytes += NUM_BYTES_RFC4122_UUID; - } - memcpy(buffer + numPackedBytes, &_type, sizeof(_type)); numPackedBytes += sizeof(_type); + // pack the UUID for this assignment, if this is an assignment create or deploy + if (_command != Assignment::RequestCommand) { + memcpy(buffer + numPackedBytes, _uuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); + numPackedBytes += NUM_BYTES_RFC4122_UUID; + } + if (_attachedPublicSocket || _attachedLocalSocket) { sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket; @@ -174,6 +174,10 @@ int Assignment::packToBuffer(unsigned char* buffer) { return numPackedBytes; } +void Assignment::run() { + // run method ovveridden by subclasses +} + QDebug operator<<(QDebug debug, const Assignment &assignment) { debug << "T:" << assignment.getType(); return debug.nospace(); diff --git a/libraries/shared/src/Assignment.h b/libraries/shared/src/Assignment.h index 4fa97d4368..1ebc0a73b3 100644 --- a/libraries/shared/src/Assignment.h +++ b/libraries/shared/src/Assignment.h @@ -16,7 +16,8 @@ #include "NodeList.h" /// Holds information used for request, creation, and deployment of assignments -class Assignment { +class Assignment : public QObject { + Q_OBJECT public: enum Type { @@ -78,6 +79,9 @@ public: /// Sets _time to the current time given by gettimeofday void setCreateTimeToNow() { gettimeofday(&_time, NULL); } + /// blocking run of the assignment + virtual void run(); + private: QUuid _uuid; /// the 16 byte UUID for this assignment Assignment::Command _command; /// the command for this assignment (Create, Deploy, Request) diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index ea94e8c080..bf64e5bb40 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -72,6 +72,7 @@ public: const char* getDomainHostname() const { return _domainHostname; } void setDomainHostname(const char* domainHostname); + const char* getDomainIP() const { return _domainIP; } void setDomainIP(const char* domainIP); void setDomainIPToLocalhost(); diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index 9625926ebd..fed5bdd869 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -43,9 +43,9 @@ void attachVoxelNodeDataToNode(Node* newNode) { } } -VoxelServer::VoxelServer() : - _serverTree(true) -{ +VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location location) : + Assignment(command, Assignment::VoxelServerType, location), + _serverTree(true) { _argc = 0; _argv = NULL; _dontKillOnMissingDomain = false; @@ -64,8 +64,10 @@ VoxelServer::VoxelServer() : _jurisdictionSender = NULL; _voxelServerPacketProcessor = NULL; _voxelPersistThread = NULL; + +} - +VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { } void VoxelServer::setArguments(int argc, char** argv) { @@ -93,7 +95,7 @@ void VoxelServer::setupStandAlone(const char* domain, int port) { } //int main(int argc, const char * argv[]) { -void VoxelServer::run(const char* configuration) { +void VoxelServer::run() { pthread_mutex_init(&_treeLock, NULL); qInstallMessageHandler(sharedMessageHandler); diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h index 923bc5139c..3a7d0e5c48 100644 --- a/libraries/voxel-server-library/src/VoxelServer.h +++ b/libraries/voxel-server-library/src/VoxelServer.h @@ -1,3 +1,4 @@ +// // VoxelServer.h // voxel-server // @@ -9,6 +10,7 @@ #ifndef __voxel_server__VoxelServer__ #define __voxel_server__VoxelServer__ +#include #include #include "NodeWatcher.h" @@ -18,12 +20,15 @@ #include "VoxelServerPacketProcessor.h" /// Handles assignments of type VoxelServer - sending voxels to various clients. -class VoxelServer { +class VoxelServer : public Assignment { public: - VoxelServer(); + VoxelServer(Assignment::Command command, + Assignment::Location location = Assignment::GlobalLocation); + + VoxelServer(const unsigned char* dataBuffer, int numBytes); /// runs the voxel server assignment - void run(const char* configuration = NULL); + void run(); /// allows setting of run arguments void setArguments(int argc, char** argv); @@ -81,6 +86,4 @@ private: }; - - #endif // __voxel_server__VoxelServer__ diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 4d82c43343..ac9e39e634 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -30,7 +30,7 @@ int main(int argc, const char * argv[]) { printf("portParameter=%s listenPort=%d\n", portParameter, listenPort); } - VoxelServer ourVoxelServer; + VoxelServer ourVoxelServer(Assignment::CreateCommand); if (wantLocalDomain) { ourVoxelServer.setupStandAlone(local, listenPort);