mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 17:41:12 +02:00
inital setup for static assignment mapped file
This commit is contained in:
parent
daa5493973
commit
bed4819313
3 changed files with 143 additions and 92 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QMutex>
|
#include <QtCore/QMutex>
|
||||||
|
|
||||||
|
@ -139,30 +140,57 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
timeval lastStatSendTime = {};
|
timeval lastStatSendTime = {};
|
||||||
|
|
||||||
// as a domain-server we will always want an audio mixer and avatar mixer
|
const QString STATIC_ASSIGNMENT_FILENAME = QString("%1/config.ds").arg(QCoreApplication::applicationDirPath());
|
||||||
// setup the create assignments for those
|
|
||||||
Assignment audioMixerAssignment(Assignment::CreateCommand,
|
|
||||||
Assignment::AudioMixerType,
|
|
||||||
Assignment::LocalLocation);
|
|
||||||
|
|
||||||
Assignment avatarMixerAssignment(Assignment::CreateCommand,
|
const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000;
|
||||||
Assignment::AvatarMixerType,
|
|
||||||
Assignment::LocalLocation);
|
|
||||||
|
|
||||||
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
QFile staticAssignmentFile(STATIC_ASSIGNMENT_FILENAME);
|
||||||
Assignment::VoxelServerType,
|
|
||||||
Assignment::LocalLocation);
|
if (!staticAssignmentFile.exists()) {
|
||||||
|
|
||||||
// Handle Domain/Voxel Server configuration command line arguments
|
const uint NUM_FRESH_STATIC_ASSIGNMENTS = 3;
|
||||||
const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig";
|
|
||||||
const char* voxelServerConfig = getCmdOption(argc, argv, VOXEL_CONFIG_OPTION);
|
// write a fresh static assignment list to file
|
||||||
if (voxelServerConfig) {
|
Assignment freshStaticAssignmentList[NUM_FRESH_STATIC_ASSIGNMENTS];
|
||||||
qDebug("Reading Voxel Server Configuration.\n");
|
|
||||||
qDebug() << " config: " << voxelServerConfig << "\n";
|
// pre-populate the first static assignment list with assignments for root AuM, AvM, VS
|
||||||
int payloadLength = strlen(voxelServerConfig) + sizeof(char);
|
freshStaticAssignmentList[0] = Assignment(Assignment::CreateCommand,
|
||||||
voxelServerAssignment.setPayload((const uchar*)voxelServerConfig, payloadLength);
|
Assignment::AudioMixerType,
|
||||||
|
Assignment::LocalLocation);
|
||||||
|
freshStaticAssignmentList[1] = Assignment(Assignment::CreateCommand,
|
||||||
|
Assignment::AvatarMixerType,
|
||||||
|
Assignment::LocalLocation);
|
||||||
|
|
||||||
|
Assignment voxelServerAssignment(Assignment::CreateCommand, Assignment::VoxelServerType, Assignment::LocalLocation);
|
||||||
|
|
||||||
|
// Handle Domain/Voxel Server configuration command line arguments
|
||||||
|
const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig";
|
||||||
|
const char* voxelServerConfig = getCmdOption(argc, argv, VOXEL_CONFIG_OPTION);
|
||||||
|
if (voxelServerConfig) {
|
||||||
|
qDebug("Reading Voxel Server Configuration.\n");
|
||||||
|
qDebug() << " config: " << voxelServerConfig << "\n";
|
||||||
|
int payloadLength = strlen(voxelServerConfig) + sizeof(char);
|
||||||
|
voxelServerAssignment.setPayload((const uchar*)voxelServerConfig, payloadLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
freshStaticAssignmentList[2] = voxelServerAssignment;
|
||||||
|
|
||||||
|
staticAssignmentFile.open(QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
staticAssignmentFile.write((char*) &NUM_FRESH_STATIC_ASSIGNMENTS,
|
||||||
|
sizeof(uint16_t));
|
||||||
|
staticAssignmentFile.write((char*) &freshStaticAssignmentList, sizeof(freshStaticAssignmentList));
|
||||||
|
staticAssignmentFile.resize(MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS * sizeof(Assignment));
|
||||||
|
staticAssignmentFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
staticAssignmentFile.open(QIODevice::ReadWrite);
|
||||||
|
|
||||||
|
uchar* staticAssignmentFileData = staticAssignmentFile.map(0, staticAssignmentFile.size());
|
||||||
|
|
||||||
|
uint16_t* numAssignmentsInStaticFile = (uint16_t*) staticAssignmentFileData;
|
||||||
|
Assignment* staticFileAssignments = (Assignment*) (staticAssignmentFileData + sizeof(*numAssignmentsInStaticFile));
|
||||||
|
|
||||||
// construct a local socket to send with our created assignments to the global AS
|
// construct a local socket to send with our created assignments to the global AS
|
||||||
sockaddr_in localSocket = {};
|
sockaddr_in localSocket = {};
|
||||||
localSocket.sin_family = AF_INET;
|
localSocket.sin_family = AF_INET;
|
||||||
|
@ -186,46 +214,6 @@ int main(int argc, const char* argv[]) {
|
||||||
ctx = mg_start(&callbacks, NULL, options);
|
ctx = mg_start(&callbacks, NULL, options);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
::assignmentQueueMutex.lock();
|
|
||||||
// check if our audio-mixer or avatar-mixer are dead and we don't have existing assignments in the queue
|
|
||||||
// so we can add those assignments back to the front of the queue since they are high-priority
|
|
||||||
if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER) &&
|
|
||||||
std::find(::assignmentQueue.begin(), assignmentQueue.end(), &avatarMixerAssignment) == ::assignmentQueue.end()) {
|
|
||||||
qDebug("Missing an avatar mixer and assignment not in queue. Adding.\n");
|
|
||||||
|
|
||||||
// reset the UUID so it is new
|
|
||||||
avatarMixerAssignment.resetUUID();
|
|
||||||
|
|
||||||
::assignmentQueue.push_front(&avatarMixerAssignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER) &&
|
|
||||||
std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &audioMixerAssignment) == ::assignmentQueue.end()) {
|
|
||||||
qDebug("Missing an audio mixer and assignment not in queue. Adding.\n");
|
|
||||||
|
|
||||||
// reset the UUID so it is new
|
|
||||||
audioMixerAssignment.resetUUID();
|
|
||||||
|
|
||||||
::assignmentQueue.push_front(&audioMixerAssignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now handle voxel servers. Since Voxel Servers aren't soloNodeOfType() we will count them and add an assignment if
|
|
||||||
// there is not at least one of them in the domain.
|
|
||||||
int voxelServerCount = 0;
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
|
||||||
voxelServerCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (voxelServerCount == 0 &&
|
|
||||||
std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &voxelServerAssignment) == ::assignmentQueue.end()) {
|
|
||||||
qDebug("Missing a voxel server and assignment not in queue. Adding.\n");
|
|
||||||
::assignmentQueue.push_front(&voxelServerAssignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
::assignmentQueueMutex.unlock();
|
|
||||||
|
|
||||||
while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
|
while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
|
||||||
packetVersionMatch(packetData)) {
|
packetVersionMatch(packetData)) {
|
||||||
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
|
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
|
||||||
|
|
|
@ -9,37 +9,79 @@
|
||||||
#include "PacketHeaders.h"
|
#include "PacketHeaders.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDataStream>
|
||||||
|
|
||||||
#include "Assignment.h"
|
#include "Assignment.h"
|
||||||
|
|
||||||
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
||||||
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
||||||
|
|
||||||
|
Assignment::Assignment() :
|
||||||
|
_uuid(),
|
||||||
|
_command(Assignment::RequestCommand),
|
||||||
|
_type(Assignment::AllTypes),
|
||||||
|
_location(Assignment::LocalLocation),
|
||||||
|
_numberOfInstances(1),
|
||||||
|
_payload(),
|
||||||
|
_numPayloadBytes(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
|
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
|
||||||
_command(command),
|
_command(command),
|
||||||
_type(type),
|
_type(type),
|
||||||
_location(location),
|
_location(location),
|
||||||
_numberOfInstances(1),
|
_numberOfInstances(1),
|
||||||
_payload(NULL),
|
_payload(),
|
||||||
_numPayloadBytes(0)
|
_numPayloadBytes(0)
|
||||||
{
|
{
|
||||||
// set the create time on this assignment
|
|
||||||
gettimeofday(&_time, NULL);
|
|
||||||
|
|
||||||
if (_command == Assignment::CreateCommand) {
|
if (_command == Assignment::CreateCommand) {
|
||||||
// this is a newly created assignment, generate a random UUID
|
// this is a newly created assignment, generate a random UUID
|
||||||
_uuid = QUuid::createUuid();
|
_uuid = QUuid::createUuid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Assignment::Assignment(const Assignment& otherAssignment) {
|
||||||
|
|
||||||
|
_uuid = otherAssignment._uuid;
|
||||||
|
|
||||||
|
_command = otherAssignment._command;
|
||||||
|
_type = otherAssignment._type;
|
||||||
|
_location = otherAssignment._location;
|
||||||
|
_numberOfInstances = otherAssignment._numberOfInstances;
|
||||||
|
|
||||||
|
setPayload(otherAssignment._payload, otherAssignment._numPayloadBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assignment& Assignment::operator=(const Assignment& rhsAssignment) {
|
||||||
|
Assignment temp(rhsAssignment);
|
||||||
|
swap(temp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assignment::swap(Assignment& otherAssignment) {
|
||||||
|
using std::swap;
|
||||||
|
|
||||||
|
swap(_uuid, otherAssignment._uuid);
|
||||||
|
swap(_command, otherAssignment._command);
|
||||||
|
swap(_type, otherAssignment._type);
|
||||||
|
swap(_location, otherAssignment._location);
|
||||||
|
swap(_numberOfInstances, otherAssignment._numberOfInstances);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_PAYLOAD_BYTES; i++) {
|
||||||
|
swap(_payload[i], otherAssignment._payload[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
swap(_numPayloadBytes, otherAssignment._numPayloadBytes);
|
||||||
|
}
|
||||||
|
|
||||||
Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
_location(GlobalLocation),
|
_location(GlobalLocation),
|
||||||
_numberOfInstances(1),
|
_numberOfInstances(1),
|
||||||
_payload(NULL),
|
_payload(),
|
||||||
_numPayloadBytes(0)
|
_numPayloadBytes(0)
|
||||||
{
|
{
|
||||||
// set the create time on this assignment
|
|
||||||
gettimeofday(&_time, NULL);
|
|
||||||
|
|
||||||
int numBytesRead = 0;
|
int numBytesRead = 0;
|
||||||
|
|
||||||
if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||||
|
@ -62,19 +104,10 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numBytes > numBytesRead) {
|
if (numBytes > numBytesRead) {
|
||||||
_numPayloadBytes = numBytes - numBytesRead;
|
setPayload(dataBuffer + numBytesRead, numBytes - numBytesRead);
|
||||||
_payload = new uchar[_numPayloadBytes];
|
|
||||||
memcpy(_payload, dataBuffer + numBytesRead, _numPayloadBytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assignment::~Assignment() {
|
|
||||||
delete[] _payload;
|
|
||||||
_numPayloadBytes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int MAX_PAYLOAD_BYTES = 1024;
|
|
||||||
|
|
||||||
void Assignment::setPayload(const uchar* payload, int numBytes) {
|
void Assignment::setPayload(const uchar* payload, int numBytes) {
|
||||||
|
|
||||||
if (numBytes > MAX_PAYLOAD_BYTES) {
|
if (numBytes > MAX_PAYLOAD_BYTES) {
|
||||||
|
@ -87,8 +120,7 @@ void Assignment::setPayload(const uchar* payload, int numBytes) {
|
||||||
_numPayloadBytes = numBytes;
|
_numPayloadBytes = numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] _payload;
|
memset(_payload, 0, MAX_PAYLOAD_BYTES);
|
||||||
_payload = new uchar[_numPayloadBytes];
|
|
||||||
memcpy(_payload, payload, _numPayloadBytes);
|
memcpy(_payload, payload, _numPayloadBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,4 +155,34 @@ void Assignment::run() {
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDataStream& operator<<(QDataStream& out, const Assignment& assignment) {
|
||||||
|
out << assignment._uuid;
|
||||||
|
out << (uchar) assignment._command;
|
||||||
|
out << (uchar) assignment._type;
|
||||||
|
out << (uchar) assignment._location;
|
||||||
|
out << assignment._numberOfInstances;
|
||||||
|
out << assignment._numPayloadBytes;
|
||||||
|
|
||||||
|
if (assignment._numPayloadBytes > 0) {
|
||||||
|
out.writeBytes((char*) assignment._payload, assignment._numPayloadBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream& operator>>(QDataStream& in, Assignment& assignment) {
|
||||||
|
in >> assignment._uuid;
|
||||||
|
in >> (uchar&) assignment._command;
|
||||||
|
in >> (uchar&) assignment._type;
|
||||||
|
in >> (uchar&) assignment._location;
|
||||||
|
in >> assignment._numberOfInstances;
|
||||||
|
in >> assignment._numPayloadBytes;
|
||||||
|
|
||||||
|
if (assignment._numPayloadBytes > 0) {
|
||||||
|
in.readRawData((char*) assignment._payload, assignment._numPayloadBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "NodeList.h"
|
#include "NodeList.h"
|
||||||
|
|
||||||
const int NUM_BYTES_RFC4122_UUID = 16;
|
const int NUM_BYTES_RFC4122_UUID = 16;
|
||||||
|
const int MAX_PAYLOAD_BYTES = 1024;
|
||||||
|
|
||||||
/// Holds information used for request, creation, and deployment of assignments
|
/// Holds information used for request, creation, and deployment of assignments
|
||||||
class Assignment : public QObject {
|
class Assignment : public QObject {
|
||||||
|
@ -41,17 +42,20 @@ public:
|
||||||
LocalLocation
|
LocalLocation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Assignment();
|
||||||
Assignment(Assignment::Command command,
|
Assignment(Assignment::Command command,
|
||||||
Assignment::Type type,
|
Assignment::Type type,
|
||||||
Assignment::Location location = Assignment::LocalLocation);
|
Assignment::Location location = Assignment::LocalLocation);
|
||||||
|
Assignment(const Assignment& otherAssignment);
|
||||||
|
Assignment& operator=(const Assignment &rhsAssignment);
|
||||||
|
|
||||||
|
void swap(Assignment& otherAssignment);
|
||||||
|
|
||||||
/// Constructs an Assignment from the data in the buffer
|
/// Constructs an Assignment from the data in the buffer
|
||||||
/// \param dataBuffer the source buffer to un-pack the assignment from
|
/// \param dataBuffer the source buffer to un-pack the assignment from
|
||||||
/// \param numBytes the number of bytes left to read in the source buffer
|
/// \param numBytes the number of bytes left to read in the source buffer
|
||||||
Assignment(const unsigned char* dataBuffer, int numBytes);
|
Assignment(const unsigned char* dataBuffer, int numBytes);
|
||||||
|
|
||||||
~Assignment();
|
|
||||||
|
|
||||||
const QUuid& getUUID() const { return _uuid; }
|
const QUuid& getUUID() const { return _uuid; }
|
||||||
QString getUUIDStringWithoutCurlyBraces() const;
|
QString getUUIDStringWithoutCurlyBraces() const;
|
||||||
void resetUUID() { _uuid = QUuid::createUuid(); }
|
void resetUUID() { _uuid = QUuid::createUuid(); }
|
||||||
|
@ -59,7 +63,6 @@ public:
|
||||||
Assignment::Command getCommand() const { return _command; }
|
Assignment::Command getCommand() const { return _command; }
|
||||||
Assignment::Type getType() const { return _type; }
|
Assignment::Type getType() const { return _type; }
|
||||||
Assignment::Location getLocation() const { return _location; }
|
Assignment::Location getLocation() const { return _location; }
|
||||||
const timeval& getTime() const { return _time; }
|
|
||||||
|
|
||||||
uchar* getPayload() { return _payload; }
|
uchar* getPayload() { return _payload; }
|
||||||
int getNumPayloadBytes() const { return _numPayloadBytes; }
|
int getNumPayloadBytes() const { return _numPayloadBytes; }
|
||||||
|
@ -74,23 +77,21 @@ public:
|
||||||
/// \return number of bytes packed into buffer
|
/// \return number of bytes packed into buffer
|
||||||
int packToBuffer(unsigned char* buffer);
|
int packToBuffer(unsigned char* buffer);
|
||||||
|
|
||||||
/// Sets _time to the current time given by gettimeofday
|
|
||||||
void setCreateTimeToNow() { gettimeofday(&_time, NULL); }
|
|
||||||
|
|
||||||
/// blocking run of the assignment
|
/// blocking run of the assignment
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
|
friend QDebug operator<<(QDebug debug, const Assignment& assignment);
|
||||||
|
friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment);
|
||||||
|
friend QDataStream& operator>>(QDataStream &in, Assignment& assignment);
|
||||||
|
|
||||||
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)
|
||||||
Assignment::Type _type; /// the type of the assignment, defines what the assignee will do
|
Assignment::Type _type; /// the type of the assignment, defines what the assignee will do
|
||||||
Assignment::Location _location; /// the location of the assignment, allows a domain to preferentially use local ACs
|
Assignment::Location _location; /// the location of the assignment, allows a domain to preferentially use local ACs
|
||||||
timeval _time; /// time the assignment was created (set in constructor)
|
|
||||||
int _numberOfInstances; /// the number of instances of this assignment
|
int _numberOfInstances; /// the number of instances of this assignment
|
||||||
uchar *_payload; /// an optional payload attached to this assignment, a maximum for 1024 bytes will be packed
|
uchar _payload[MAX_PAYLOAD_BYTES]; /// an optional payload attached to this assignment, a maximum for 1024 bytes will be packed
|
||||||
int _numPayloadBytes; /// number of bytes in the payload, up to a maximum of 1024
|
int _numPayloadBytes; /// number of bytes in the payload, up to a maximum of 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const Assignment &assignment);
|
|
||||||
|
|
||||||
#endif /* defined(__hifi__Assignment__) */
|
#endif /* defined(__hifi__Assignment__) */
|
||||||
|
|
Loading…
Reference in a new issue