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 "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));

View file

@ -9,19 +9,19 @@
#ifndef __hifi__Agent__
#define __hifi__Agent__
#include "SharedUtil.h"
#include <QtCore/QObject>
#include <QtCore/QUrl>
class Agent : public QObject {
#include <Assignment.h>
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();
};

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() {
// change the logging target name while this is running
Logging::setTargetName(AUDIO_MIXER_LOGGING_TARGET_NAME);

View file

@ -9,11 +9,15 @@
#ifndef __hifi__AudioMixer__
#define __hifi__AudioMixer__
#include <Assignment.h>
/// 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__) */

View file

@ -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);

View file

@ -9,13 +9,15 @@
#ifndef __hifi__AvatarMixer__
#define __hifi__AvatarMixer__
#include <iostream>
#include <Assignment.h>
/// 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__) */

View file

@ -14,16 +14,19 @@
#include <QtCore/QCoreApplication>
#include "Agent.h"
#include <Assignment.h>
#include "audio/AudioMixer.h"
#include "avatars/AvatarMixer.h"
#include <Logging.h>
#include <NodeList.h>
#include <PacketHeaders.h>
#include <SharedUtil.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 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<VoxelServer*> 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() {

View file

@ -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);

View file

@ -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();

View file

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

View file

@ -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();

View file

@ -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);

View file

@ -1,3 +1,4 @@
//
// VoxelServer.h
// voxel-server
//
@ -9,6 +10,7 @@
#ifndef __voxel_server__VoxelServer__
#define __voxel_server__VoxelServer__
#include <Assignment.h>
#include <EnvironmentData.h>
#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__

View file

@ -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);