Merge branch 'master' of https://github.com/worklist/hifi into multi_VS_assigments

This commit is contained in:
ZappoMan 2013-09-17 16:00:32 -07:00
commit 49c4075277
17 changed files with 140 additions and 77 deletions

View file

@ -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"

View file

@ -15,18 +15,22 @@
#include "Agent.h" #include "Agent.h"
#include "voxels/VoxelScriptingInterface.h" #include "voxels/VoxelScriptingInterface.h"
Agent::Agent() : Agent::Agent(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) {
_shouldStop(false)
{
} }
void Agent::run(QUrl scriptURL) { void Agent::run() {
NodeList::getInstance()->setOwnerType(NODE_TYPE_AGENT); NodeList::getInstance()->setOwnerType(NODE_TYPE_AGENT);
NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_VOXEL_SERVER, 1); NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_VOXEL_SERVER, 1);
QNetworkAccessManager manager; 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"; qDebug() << "Attemping download of " << scriptURL << "\n";
QNetworkReply* reply = manager.get(QNetworkRequest(scriptURL)); QNetworkReply* reply = manager.get(QNetworkRequest(scriptURL));

View file

@ -9,19 +9,19 @@
#ifndef __hifi__Agent__ #ifndef __hifi__Agent__
#define __hifi__Agent__ #define __hifi__Agent__
#include "SharedUtil.h"
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QUrl> #include <QtCore/QUrl>
class Agent : public QObject { #include <Assignment.h>
class Agent : public Assignment {
Q_OBJECT Q_OBJECT
public: public:
Agent(); Agent(const unsigned char* dataBuffer, int numBytes);
bool volatile _shouldStop; bool volatile _shouldStop;
void run(QUrl scriptUrl); void run();
signals: signals:
void preSendCallback(); void preSendCallback();
}; };

View file

@ -0,0 +1,36 @@
//
// AssignmentFactory.cpp
// hifi
//
// Created by Stephen Birarda on 9/17/13.
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include <PacketHeaders.h>
#include "Agent.h"
#include "audio/AudioMixer.h"
#include "avatars/AvatarMixer.h"
#include <VoxelServer.h>
#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);
}
}

View file

@ -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__) */

View file

@ -69,6 +69,10 @@ void attachNewBufferToNode(Node *newNode) {
} }
} }
AudioMixer::AudioMixer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) {
}
void AudioMixer::run() { void AudioMixer::run() {
// change the logging target name while this is running // change the logging target name while this is running
Logging::setTargetName(AUDIO_MIXER_LOGGING_TARGET_NAME); Logging::setTargetName(AUDIO_MIXER_LOGGING_TARGET_NAME);

View file

@ -9,11 +9,15 @@
#ifndef __hifi__AudioMixer__ #ifndef __hifi__AudioMixer__
#define __hifi__AudioMixer__ #define __hifi__AudioMixer__
#include <Assignment.h>
/// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients. /// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients.
class AudioMixer { class AudioMixer : public Assignment {
public: public:
AudioMixer(const unsigned char* dataBuffer, int numBytes);
/// runs the audio mixer /// runs the audio mixer
static void run(); void run();
}; };
#endif /* defined(__hifi__AudioMixer__) */ #endif /* defined(__hifi__AudioMixer__) */

View file

@ -83,6 +83,10 @@ void broadcastAvatarData(NodeList* nodeList, sockaddr* nodeAddress) {
nodeList->getNodeSocket()->send(nodeAddress, broadcastPacket, currentBufferPosition - broadcastPacket); nodeList->getNodeSocket()->send(nodeAddress, broadcastPacket, currentBufferPosition - broadcastPacket);
} }
AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) {
}
void AvatarMixer::run() { void AvatarMixer::run() {
// change the logging target name while AvatarMixer is running // change the logging target name while AvatarMixer is running
Logging::setTargetName(AVATAR_MIXER_LOGGING_NAME); Logging::setTargetName(AVATAR_MIXER_LOGGING_NAME);

View file

@ -9,13 +9,15 @@
#ifndef __hifi__AvatarMixer__ #ifndef __hifi__AvatarMixer__
#define __hifi__AvatarMixer__ #define __hifi__AvatarMixer__
#include <iostream> #include <Assignment.h>
/// Handles assignments of type AvatarMixer - distribution of avatar data to various clients /// Handles assignments of type AvatarMixer - distribution of avatar data to various clients
class AvatarMixer { class AvatarMixer : public Assignment {
public: public:
AvatarMixer(const unsigned char* dataBuffer, int numBytes);
/// runs the avatar mixer /// runs the avatar mixer
static void run(); void run();
}; };
#endif /* defined(__hifi__AvatarMixer__) */ #endif /* defined(__hifi__AvatarMixer__) */

View file

@ -14,16 +14,19 @@
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include "Agent.h"
#include <Assignment.h>
#include "audio/AudioMixer.h"
#include "avatars/AvatarMixer.h"
#include <Logging.h> #include <Logging.h>
#include <NodeList.h> #include <NodeList.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <VoxelServer.h> #include <VoxelServer.h>
#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 long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000;
const char PARENT_TARGET_NAME[] = "assignment-client-monitor"; const char PARENT_TARGET_NAME[] = "assignment-client-monitor";
const char CHILD_TARGET_NAME[] = "assignment-client"; const char CHILD_TARGET_NAME[] = "assignment-client";
@ -32,7 +35,6 @@ pid_t* childForks = NULL;
sockaddr_in customAssignmentSocket = {}; sockaddr_in customAssignmentSocket = {};
int numForks = 0; int numForks = 0;
Assignment::Type overiddenAssignmentType = Assignment::AllTypes; Assignment::Type overiddenAssignmentType = Assignment::AllTypes;
std::vector<VoxelServer*> voxelServers;
void childClient() { void childClient() {
// this is one of the child forks or there is a single assignment client, continue assignment-client execution // 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)) { && packetVersionMatch(packetData)) {
// construct the deployed assignment from the packet data // construct the deployed assignment from the packet data
Assignment deployedAssignment(packetData, receivedBytes); Assignment* deployedAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
qDebug() << "Received an assignment -" << deployedAssignment << "\n"; qDebug() << "Received an assignment -" << deployedAssignment << "\n";
// switch our nodelist DOMAIN_IP // switch our nodelist DOMAIN_IP
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT || if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT ||
deployedAssignment.getAttachedPublicSocket()->sa_family == AF_INET) { deployedAssignment->getAttachedPublicSocket()->sa_family == AF_INET) {
in_addr domainSocketAddr = {}; in_addr domainSocketAddr = {};
@ -89,38 +91,24 @@ void childClient() {
domainSocketAddr = senderSocket.sin_addr; domainSocketAddr = senderSocket.sin_addr;
} else { } else {
// grab the domain server IP address from the packet from the AS // 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)); nodeList->setDomainIP(inet_ntoa(domainSocketAddr));
qDebug("Destination IP for assignment is %s\n", inet_ntoa(domainSocketAddr)); qDebug("Destination IP for assignment is %s\n", inet_ntoa(domainSocketAddr));
if (deployedAssignment.getType() == Assignment::AudioMixerType) { // run the deployed assignment
AudioMixer::run(); deployedAssignment->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));
}
} else { } else {
qDebug("Received a bad destination socket for assignment.\n"); qDebug("Received a bad destination socket for assignment.\n");
} }
qDebug("Assignment finished or never started - waiting for new 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 // reset our NodeList by switching back to unassigned and clearing the list
nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); nodeList->setOwnerType(NODE_TYPE_UNASSIGNED);
nodeList->clear(); 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() { void parentMonitor() {

View file

@ -346,6 +346,9 @@ int main(int argc, const char* argv[]) {
if (requestAssignment.getType() == Assignment::AllTypes || if (requestAssignment.getType() == Assignment::AllTypes ||
(*assignment)->getType() == requestAssignment.getType()) { (*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 // 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 numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT);
int numAssignmentBytes = (*assignment)->packToBuffer(broadcastPacket + numHeaderBytes); int numAssignmentBytes = (*assignment)->packToBuffer(broadcastPacket + numHeaderBytes);

View file

@ -58,15 +58,15 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
numBytesRead += numBytesForPacketHeader(dataBuffer); numBytesRead += numBytesForPacketHeader(dataBuffer);
memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type));
numBytesRead += sizeof(Assignment::Type);
if (dataBuffer[0] != PACKET_TYPE_REQUEST_ASSIGNMENT) { if (dataBuffer[0] != PACKET_TYPE_REQUEST_ASSIGNMENT) {
// read the GUID for this assignment // read the GUID for this assignment
_uuid = QUuid::fromRfc4122(QByteArray((const char*) dataBuffer + numBytesRead, NUM_BYTES_RFC4122_UUID)); _uuid = QUuid::fromRfc4122(QByteArray((const char*) dataBuffer + numBytesRead, NUM_BYTES_RFC4122_UUID));
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) { if (_command != Assignment::RequestCommand) {
sockaddr* newSocket = NULL; sockaddr* newSocket = NULL;
@ -149,15 +149,15 @@ void Assignment::setAttachedLocalSocket(const sockaddr* attachedLocalSocket) {
int Assignment::packToBuffer(unsigned char* buffer) { int Assignment::packToBuffer(unsigned char* buffer) {
int numPackedBytes = 0; 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)); memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
numPackedBytes += 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) { if (_attachedPublicSocket || _attachedLocalSocket) {
sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket; sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket;
@ -174,6 +174,10 @@ int Assignment::packToBuffer(unsigned char* buffer) {
return numPackedBytes; return numPackedBytes;
} }
void Assignment::run() {
// run method ovveridden by subclasses
}
QDebug operator<<(QDebug debug, const Assignment &assignment) { QDebug operator<<(QDebug debug, const Assignment &assignment) {
debug << "T:" << assignment.getType(); debug << "T:" << assignment.getType();
return debug.nospace(); return debug.nospace();

View file

@ -16,7 +16,8 @@
#include "NodeList.h" #include "NodeList.h"
/// Holds information used for request, creation, and deployment of assignments /// Holds information used for request, creation, and deployment of assignments
class Assignment { class Assignment : public QObject {
Q_OBJECT
public: public:
enum Type { enum Type {
@ -78,6 +79,9 @@ public:
/// Sets _time to the current time given by gettimeofday /// Sets _time to the current time given by gettimeofday
void setCreateTimeToNow() { gettimeofday(&_time, NULL); } void setCreateTimeToNow() { gettimeofday(&_time, NULL); }
/// blocking run of the assignment
virtual void run();
private: private:
QUuid _uuid; /// the 16 byte UUID for this assignment QUuid _uuid; /// the 16 byte UUID for this assignment
Assignment::Command _command; /// the command for this assignment (Create, Deploy, Request) Assignment::Command _command; /// the command for this assignment (Create, Deploy, Request)

View file

@ -72,6 +72,7 @@ public:
const char* getDomainHostname() const { return _domainHostname; } const char* getDomainHostname() const { return _domainHostname; }
void setDomainHostname(const char* domainHostname); void setDomainHostname(const char* domainHostname);
const char* getDomainIP() const { return _domainIP; }
void setDomainIP(const char* domainIP); void setDomainIP(const char* domainIP);
void setDomainIPToLocalhost(); void setDomainIPToLocalhost();

View file

@ -43,9 +43,9 @@ void attachVoxelNodeDataToNode(Node* newNode) {
} }
} }
VoxelServer::VoxelServer() : VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location location) :
_serverTree(true) Assignment(command, Assignment::VoxelServerType, location),
{ _serverTree(true) {
_argc = 0; _argc = 0;
_argv = NULL; _argv = NULL;
_dontKillOnMissingDomain = false; _dontKillOnMissingDomain = false;
@ -65,7 +65,9 @@ VoxelServer::VoxelServer() :
_voxelServerPacketProcessor = NULL; _voxelServerPacketProcessor = NULL;
_voxelPersistThread = NULL; _voxelPersistThread = NULL;
}
VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) {
} }
void VoxelServer::setArguments(int argc, char** argv) { 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[]) { //int main(int argc, const char * argv[]) {
void VoxelServer::run(const char* configuration) { void VoxelServer::run() {
pthread_mutex_init(&_treeLock, NULL); pthread_mutex_init(&_treeLock, NULL);
qInstallMessageHandler(sharedMessageHandler); qInstallMessageHandler(sharedMessageHandler);

View file

@ -1,3 +1,4 @@
//
// VoxelServer.h // VoxelServer.h
// voxel-server // voxel-server
// //
@ -9,6 +10,7 @@
#ifndef __voxel_server__VoxelServer__ #ifndef __voxel_server__VoxelServer__
#define __voxel_server__VoxelServer__ #define __voxel_server__VoxelServer__
#include <Assignment.h>
#include <EnvironmentData.h> #include <EnvironmentData.h>
#include "NodeWatcher.h" #include "NodeWatcher.h"
@ -18,12 +20,15 @@
#include "VoxelServerPacketProcessor.h" #include "VoxelServerPacketProcessor.h"
/// Handles assignments of type VoxelServer - sending voxels to various clients. /// Handles assignments of type VoxelServer - sending voxels to various clients.
class VoxelServer { class VoxelServer : public Assignment {
public: public:
VoxelServer(); VoxelServer(Assignment::Command command,
Assignment::Location location = Assignment::GlobalLocation);
VoxelServer(const unsigned char* dataBuffer, int numBytes);
/// runs the voxel server assignment /// runs the voxel server assignment
void run(const char* configuration = NULL); void run();
/// allows setting of run arguments /// allows setting of run arguments
void setArguments(int argc, char** argv); void setArguments(int argc, char** argv);
@ -81,6 +86,4 @@ private:
}; };
#endif // __voxel_server__VoxelServer__ #endif // __voxel_server__VoxelServer__

View file

@ -30,7 +30,7 @@ int main(int argc, const char * argv[]) {
printf("portParameter=%s listenPort=%d\n", portParameter, listenPort); printf("portParameter=%s listenPort=%d\n", portParameter, listenPort);
} }
VoxelServer ourVoxelServer; VoxelServer ourVoxelServer(Assignment::CreateCommand);
if (wantLocalDomain) { if (wantLocalDomain) {
ourVoxelServer.setupStandAlone(local, listenPort); ourVoxelServer.setupStandAlone(local, listenPort);