From d830351ed6608478b7b6eb15c1d100a2a4f61a5f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Sep 2013 14:54:58 -0700 Subject: [PATCH 1/4] make the assignment targets subclasses of Assignment for access to UUID --- VoxelScriptingInterface.cpp | 9 ----- assignment-client/src/Agent.cpp | 12 ++++-- assignment-client/src/Agent.h | 10 ++--- assignment-client/src/AssignmentFactory.cpp | 33 +++++++++++++++ assignment-client/src/AssignmentFactory.h | 19 +++++++++ assignment-client/src/audio/AudioMixer.cpp | 4 ++ assignment-client/src/audio/AudioMixer.h | 8 +++- assignment-client/src/avatars/AvatarMixer.cpp | 4 ++ assignment-client/src/avatars/AvatarMixer.h | 8 ++-- assignment-client/src/main.cpp | 40 ++++++++----------- libraries/shared/src/Assignment.cpp | 16 +++++--- libraries/shared/src/Assignment.h | 6 ++- libraries/shared/src/NodeList.h | 1 + .../voxel-server-library/src/VoxelServer.h | 7 +++- 14 files changed, 121 insertions(+), 56 deletions(-) delete mode 100644 VoxelScriptingInterface.cpp create mode 100644 assignment-client/src/AssignmentFactory.cpp create mode 100644 assignment-client/src/AssignmentFactory.h 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..01abceea1b --- /dev/null +++ b/assignment-client/src/AssignmentFactory.cpp @@ -0,0 +1,33 @@ +// +// 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 "AssignmentFactory.h" + +Assignment* AssignmentFactory::unpackAssignment(const unsigned char* dataBuffer, int numBytes) { + int headerBytes = numBytesForPacketHeader(dataBuffer); + + Assignment::Type type; + memcpy(&type, dataBuffer + headerBytes, sizeof(type)); + + switch (type) { + case Assignment::AudioMixerType: + return new AudioMixer(dataBuffer, numBytes); + case Assignment::AvatarMixerType: + return new AvatarMixer(dataBuffer, numBytes); + case Assignment::AgentType: + return new Agent(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 76fb99839a..3d4f4b6e4c 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"; @@ -73,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 = {}; @@ -88,36 +91,25 @@ 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::run(); - } 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(); diff --git a/libraries/shared/src/Assignment.cpp b/libraries/shared/src/Assignment.cpp index 3a02408a7b..1cd30afaf0 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; + 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, _uuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); numPackedBytes += NUM_BYTES_RFC4122_UUID; } - memcpy(buffer + numPackedBytes, &_type, sizeof(_type)); - numPackedBytes += sizeof(_type); - if (_attachedPublicSocket || _attachedLocalSocket) { sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket; @@ -176,6 +176,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 325cca1c8e..5854ea270d 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.h b/libraries/voxel-server-library/src/VoxelServer.h index d51870dbb1..d158cdfd5c 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,11 +10,13 @@ #ifndef __voxel_server__VoxelServer__ #define __voxel_server__VoxelServer__ +#include + /// Handles assignments of type VoxelServer - sending voxels to various clients. -class VoxelServer { +class VoxelServer : public Assignment { public: /// runs the voxel server assignment - static void run(); + void run(); /// allows setting of run arguments static void setArguments(int argc, char** argv); From 17a210813be24fa06dd724511903cf0739c31afe Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Sep 2013 15:20:34 -0700 Subject: [PATCH 2/4] repairs to subclasses of assignment --- assignment-client/src/AssignmentFactory.cpp | 9 ++++++--- domain-server/src/main.cpp | 3 +++ libraries/shared/src/Assignment.cpp | 2 +- libraries/voxel-server-library/src/VoxelServer.cpp | 4 ++++ libraries/voxel-server-library/src/VoxelServer.h | 2 ++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/AssignmentFactory.cpp b/assignment-client/src/AssignmentFactory.cpp index 01abceea1b..a3aa657943 100644 --- a/assignment-client/src/AssignmentFactory.cpp +++ b/assignment-client/src/AssignmentFactory.cpp @@ -11,22 +11,25 @@ #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 type; - memcpy(&type, dataBuffer + headerBytes, sizeof(type)); + Assignment::Type assignmentType = Assignment::AllTypes; + memcpy(&assignmentType, dataBuffer + headerBytes, sizeof(Assignment::Type)); - switch (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); } diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 62d8be42b7..04072dab49 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -335,6 +335,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 1cd30afaf0..f8aabf370f 100644 --- a/libraries/shared/src/Assignment.cpp +++ b/libraries/shared/src/Assignment.cpp @@ -154,7 +154,7 @@ int Assignment::packToBuffer(unsigned char* buffer) { // 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); + memcpy(buffer + numPackedBytes, _uuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); numPackedBytes += NUM_BYTES_RFC4122_UUID; } diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index b239a180d9..f89b477e6b 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -73,6 +73,10 @@ void attachVoxelNodeDataToNode(Node* newNode) { } } +VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { + +} + void VoxelServer::setArguments(int argc, char** argv) { _argc = argc; _argv = const_cast(argv); diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h index d158cdfd5c..93baf87fda 100644 --- a/libraries/voxel-server-library/src/VoxelServer.h +++ b/libraries/voxel-server-library/src/VoxelServer.h @@ -15,6 +15,8 @@ /// Handles assignments of type VoxelServer - sending voxels to various clients. class VoxelServer : public Assignment { public: + VoxelServer(const unsigned char* dataBuffer, int numBytes); + /// runs the voxel server assignment void run(); From 8bb77ecc9e249cbc8a27b9a4fb49b1da23cb2e58 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Sep 2013 15:23:49 -0700 Subject: [PATCH 3/4] type squish for deployed assignment --- assignment-client/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 3d4f4b6e4c..674550f684 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -76,7 +76,7 @@ void childClient() { && packetVersionMatch(packetData)) { // construct the deployed assignment from the packet data - Assignment *deployedAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes); + Assignment* deployedAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes); qDebug() << "Received an assignment -" << deployedAssignment << "\n"; From 89546f71406358a5f0415df8630df4967ea9262d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Sep 2013 15:38:54 -0700 Subject: [PATCH 4/4] repairs to temporary standalone voxel-server for assignment subclass --- libraries/voxel-server-library/src/VoxelServer.cpp | 5 +++++ libraries/voxel-server-library/src/VoxelServer.h | 2 ++ voxel-server/src/main.cpp | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index f89b477e6b..86a7df5dc6 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -73,6 +73,11 @@ void attachVoxelNodeDataToNode(Node* newNode) { } } +VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location location) : + Assignment(command, Assignment::VoxelServerType, location) { + +} + VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { } diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h index 93baf87fda..aca3d7c485 100644 --- a/libraries/voxel-server-library/src/VoxelServer.h +++ b/libraries/voxel-server-library/src/VoxelServer.h @@ -15,6 +15,8 @@ /// Handles assignments of type VoxelServer - sending voxels to various clients. class VoxelServer : public Assignment { public: + VoxelServer(Assignment::Command command, + Assignment::Location location = Assignment::GlobalLocation); VoxelServer(const unsigned char* dataBuffer, int numBytes); /// runs the voxel server assignment diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index f854df84cf..d38d2e48bc 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -39,7 +39,9 @@ int main(int argc, const char * argv[]) { } VoxelServer::setArguments(argc, const_cast(argv)); - VoxelServer::run(); + + VoxelServer dummyAssignedVoxelServer(Assignment::CreateCommand); + dummyAssignedVoxelServer.run(); }