Merge pull request #1725 from birarda/packet-changes

I looked it over but did not test.  A lot of uint64_t --> qint64 and name changes.
This commit is contained in:
AndrewMeadows 2014-01-29 13:13:20 -08:00
commit 4ff400f59f
142 changed files with 1833 additions and 2111 deletions

View file

@ -16,7 +16,6 @@
#include <EnvironmentData.h>
#include <NodeList.h>
#include <NodeTypes.h>
#include <OctalCode.h>
#include <PacketHeaders.h>
#include <JurisdictionListener.h>
@ -152,7 +151,7 @@ static void renderMovingBug() {
}
// send the "erase message" first...
PACKET_TYPE message = PACKET_TYPE_VOXEL_ERASE;
PacketType message = PacketTypeVoxelErase;
::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details);
// Move the bug...
@ -212,7 +211,7 @@ static void renderMovingBug() {
}
// send the "create message" ...
message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE;
message = PacketTypeVoxelSetDestructive;
::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details);
}
@ -247,7 +246,7 @@ static void sendVoxelBlinkMessage() {
detail.green = 0 * ::intensity;
detail.blue = 0 * ::intensity;
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE;
PacketType message = PacketTypeVoxelSetDestructive;
::voxelEditPacketSender->sendVoxelEditMessage(message, detail);
}
@ -264,7 +263,7 @@ unsigned char onColor[3] = { 0, 255, 255 };
const float STRING_OF_LIGHTS_SIZE = 0.125f / TREE_SCALE; // approximately 1/8th meter
static void sendBlinkingStringOfLights() {
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
float lightScale = STRING_OF_LIGHTS_SIZE;
static VoxelDetail details[LIGHTS_PER_SEGMENT];
@ -370,7 +369,7 @@ const int PACKETS_PER_DANCE_FLOOR = DANCE_FLOOR_VOXELS_PER_PACKET / (DANCE_FLOOR
int danceFloorColors[DANCE_FLOOR_WIDTH][DANCE_FLOOR_LENGTH];
void sendDanceFloor() {
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
float lightScale = DANCE_FLOOR_LIGHT_SIZE;
static VoxelDetail details[DANCE_FLOOR_VOXELS_PER_PACKET];
@ -486,7 +485,7 @@ bool billboardMessage[BILLBOARD_HEIGHT][BILLBOARD_WIDTH] = {
};
static void sendBillboard() {
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
float lightScale = BILLBOARD_LIGHT_SIZE;
static VoxelDetail details[VOXELS_PER_PACKET];
@ -557,7 +556,7 @@ void doBuildStreet() {
return;
}
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
static VoxelDetail details[BRICKS_PER_PACKET];
for (int z = 0; z < ROAD_LENGTH; z++) {
@ -592,8 +591,8 @@ double start = 0;
void* animateVoxels(void* args) {
uint64_t lastAnimateTime = 0;
uint64_t lastProcessTime = 0;
quint64 lastAnimateTime = 0;
quint64 lastProcessTime = 0;
int processesPerAnimate = 0;
bool firstTime = true;
@ -623,8 +622,8 @@ void* animateVoxels(void* args) {
// The while loop will be running at PROCESSING_FPS, but we only want to call these animation functions at
// ANIMATE_FPS. So we check out last animate time and only call these if we've elapsed that time.
uint64_t now = usecTimestampNow();
uint64_t animationElapsed = now - lastAnimateTime;
quint64 now = usecTimestampNow();
quint64 animationElapsed = now - lastAnimateTime;
int withinAnimationTarget = ANIMATE_VOXELS_INTERVAL_USECS - animationElapsed;
const int CLOSE_ENOUGH_TO_ANIMATE = 2000; // approximately 2 ms
@ -677,7 +676,7 @@ void* animateVoxels(void* args) {
processesPerAnimate++;
}
// dynamically sleep until we need to fire off the next set of voxels
uint64_t usecToSleep = PROCESSING_INTERVAL_USECS - (usecTimestampNow() - lastProcessTime);
quint64 usecToSleep = PROCESSING_INTERVAL_USECS - (usecTimestampNow() - lastProcessTime);
if (usecToSleep > PROCESSING_INTERVAL_USECS) {
usecToSleep = PROCESSING_INTERVAL_USECS;
}
@ -695,7 +694,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
{
::start = usecTimestampNow();
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_ANIMATION_SERVER, ANIMATION_LISTEN_PORT);
NodeList* nodeList = NodeList::createInstance(NodeType::AnimationServer, ANIMATION_LISTEN_PORT);
setvbuf(stdout, NULL, _IOLBF, 0);
// Handle Local Domain testing with the --local command line
@ -807,7 +806,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
pthread_create(&::animateVoxelThread, NULL, animateVoxels, NULL);
NodeList::getInstance()->addNodeTypeToInterestSet(NODE_TYPE_VOXEL_SERVER);
NodeList::getInstance()->addNodeTypeToInterestSet(NodeType::VoxelServer);
QTimer* domainServerTimer = new QTimer(this);
connect(domainServerTimer, SIGNAL(timeout()), nodeList, SLOT(sendDomainServerCheckIn()));
@ -823,25 +822,24 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
void AnimationServer::readPendingDatagrams() {
NodeList* nodeList = NodeList::getInstance();
static int receivedBytes = 0;
static unsigned char packetData[MAX_PACKET_SIZE];
static QByteArray receivedPacket;
static HifiSockAddr nodeSockAddr;
// Nodes sending messages to us...
while (nodeList->getNodeSocket().hasPendingDatagrams()
&& (receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
nodeSockAddr.getAddressPointer(),
nodeSockAddr.getPortPointer())) &&
packetVersionMatch(packetData, nodeSockAddr)) {
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
int headerBytes = numBytesForPacketHeader(packetData);
// PACKET_TYPE_JURISDICTION, first byte is the node type...
if (packetData[headerBytes] == NODE_TYPE_VOXEL_SERVER && ::jurisdictionListener) {
::jurisdictionListener->queueReceivedPacket(nodeSockAddr, packetData, receivedBytes);
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer());
if (packetVersionMatch(receivedPacket)) {
if (packetTypeForPacket(receivedPacket) == PacketTypeJurisdiction) {
int headerBytes = numBytesForPacketHeader(receivedPacket);
// PacketType_JURISDICTION, first byte is the node type...
if (receivedPacket.data()[headerBytes] == NodeType::VoxelServer && ::jurisdictionListener) {
::jurisdictionListener->queueReceivedPacket(nodeSockAddr, receivedPacket);
}
}
NodeList::getInstance()->processNodeData(nodeSockAddr, receivedPacket);
}
NodeList::getInstance()->processNodeData(nodeSockAddr, packetData, receivedBytes);
}
}

View file

@ -22,43 +22,42 @@
#include "Agent.h"
Agent::Agent(const unsigned char* dataBuffer, int numBytes) :
ThreadedAssignment(dataBuffer, numBytes)
Agent::Agent(const QByteArray& packet) :
ThreadedAssignment(packet)
{
}
void Agent::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
if (dataByteArray[0] == PACKET_TYPE_JURISDICTION) {
int headerBytes = numBytesForPacketHeader((const unsigned char*) dataByteArray.constData());
// PACKET_TYPE_JURISDICTION, first byte is the node type...
PacketType datagramPacketType = packetTypeForPacket(dataByteArray);
if (datagramPacketType == PacketTypeJurisdiction) {
int headerBytes = numBytesForPacketHeader(dataByteArray);
// PacketType_JURISDICTION, first byte is the node type...
switch (dataByteArray[headerBytes]) {
case NODE_TYPE_VOXEL_SERVER:
case NodeType::VoxelServer:
_scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
(unsigned char*) dataByteArray.data(),
dataByteArray.size());
dataByteArray);
break;
case NODE_TYPE_PARTICLE_SERVER:
case NodeType::ParticleServer:
_scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
(unsigned char*) dataByteArray.data(),
dataByteArray.size());
dataByteArray);
break;
}
} else if (dataByteArray[0] == PACKET_TYPE_PARTICLE_ADD_RESPONSE) {
} else if (datagramPacketType == PacketTypeParticleAddResponse) {
// this will keep creatorTokenIDs to IDs mapped correctly
Particle::handleAddParticleResponse((unsigned char*) dataByteArray.data(), dataByteArray.size());
Particle::handleAddParticleResponse(dataByteArray);
// also give our local particle tree a chance to remap any internal locally created particles
_particleTree.handleAddParticleResponse((unsigned char*) dataByteArray.data(), dataByteArray.size());
_particleTree.handleAddParticleResponse(dataByteArray);
} else {
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
}
}
void Agent::run() {
NodeList* nodeList = NodeList::getInstance();
nodeList->setOwnerType(NODE_TYPE_AGENT);
nodeList->setOwnerType(NodeType::Agent);
nodeList->addSetOfNodeTypesToNodeInterestSet(QSet<NODE_TYPE>() << NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER);
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer);
// figure out the URL for the script for this agent assignment
QString scriptURLString("http://%1:8080/assignment/%2");

View file

@ -22,7 +22,7 @@
class Agent : public ThreadedAssignment {
Q_OBJECT
public:
Agent(const unsigned char* dataBuffer, int numBytes);
Agent(const QByteArray& packet);
public slots:
void run();

View file

@ -52,7 +52,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
_requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool);
// create a NodeList as an unassigned client
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED);
NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned);
const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a";
const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p";
@ -102,34 +102,33 @@ void AssignmentClient::sendAssignmentRequest() {
void AssignmentClient::readPendingDatagrams() {
NodeList* nodeList = NodeList::getInstance();
static unsigned char packetData[1500];
static qint64 receivedBytes = 0;
static HifiSockAddr senderSockAddr;
QByteArray receivedPacket;
HifiSockAddr senderSockAddr;
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
senderSockAddr.getAddressPointer(),
senderSockAddr.getPortPointer()))
&& packetVersionMatch(packetData, senderSockAddr)) {
if (packetVersionMatch(receivedPacket)) {
if (_currentAssignment) {
// have the threaded current assignment handle this datagram
QMetaObject::invokeMethod(_currentAssignment, "processDatagram", Qt::QueuedConnection,
Q_ARG(QByteArray, QByteArray((char*) packetData, receivedBytes)),
Q_ARG(QByteArray, receivedPacket),
Q_ARG(HifiSockAddr, senderSockAddr));
} else if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT || packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
} else if (packetTypeForPacket(receivedPacket) == PacketTypeCreateAssignment) {
if (_currentAssignment) {
qDebug() << "Dropping received assignment since we are currently running one.";
} else {
// construct the deployed assignment from the packet data
_currentAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
_currentAssignment = AssignmentFactory::unpackAssignment(receivedPacket);
qDebug() << "Received an assignment -" << *_currentAssignment;
// switch our nodelist domain IP and port to whoever sent us the assignment
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
if (_currentAssignment) {
qDebug() << "Received an assignment -" << *_currentAssignment;
// switch our nodelist domain IP and port to whoever sent us the assignment
nodeList->setDomainSockAddr(senderSockAddr);
nodeList->setOwnerUUID(_currentAssignment->getUUID());
@ -153,12 +152,12 @@ void AssignmentClient::readPendingDatagrams() {
// Starts an event loop, and emits workerThread->started()
workerThread->start();
} else {
qDebug("Received a bad destination socket for assignment.");
qDebug() << "Received an assignment that could not be unpacked. Re-requesting.";
}
}
} else {
// have the NodeList attempt to handle it
nodeList->processNodeData(senderSockAddr, packetData, receivedBytes);
nodeList->processNodeData(senderSockAddr, receivedPacket);
}
}
}
@ -175,6 +174,6 @@ void AssignmentClient::assignmentCompleted() {
NodeList* nodeList = NodeList::getInstance();
// reset our NodeList by switching back to unassigned and clearing the list
nodeList->setOwnerType(NODE_TYPE_UNASSIGNED);
nodeList->setOwnerType(NodeType::Unassigned);
nodeList->reset();
}

View file

@ -18,25 +18,27 @@
#include "avatars/AvatarMixer.h"
#include "metavoxels/MetavoxelServer.h"
ThreadedAssignment* AssignmentFactory::unpackAssignment(const unsigned char* dataBuffer, int numBytes) {
int headerBytes = numBytesForPacketHeader(dataBuffer);
ThreadedAssignment* AssignmentFactory::unpackAssignment(const QByteArray& packet) {
int headerBytes = numBytesForPacketHeader(packet);
Assignment::Type assignmentType = Assignment::AllTypes;
memcpy(&assignmentType, dataBuffer + headerBytes, sizeof(Assignment::Type));
quint8 packedType;
memcpy(&packedType, packet.data() + headerBytes, sizeof(packedType));
switch (assignmentType) {
Assignment::Type unpackedType = (Assignment::Type) packedType;
switch (unpackedType) {
case Assignment::AudioMixerType:
return new AudioMixer(dataBuffer, numBytes);
return new AudioMixer(packet);
case Assignment::AvatarMixerType:
return new AvatarMixer(dataBuffer, numBytes);
return new AvatarMixer(packet);
case Assignment::AgentType:
return new Agent(dataBuffer, numBytes);
return new Agent(packet);
case Assignment::VoxelServerType:
return new VoxelServer(dataBuffer, numBytes);
return new VoxelServer(packet);
case Assignment::ParticleServerType:
return new ParticleServer(dataBuffer, numBytes);
return new ParticleServer(packet);
case Assignment::MetavoxelServerType:
return new MetavoxelServer(dataBuffer, numBytes);
return new MetavoxelServer(packet);
default:
return NULL;
}

View file

@ -13,7 +13,7 @@
class AssignmentFactory {
public:
static ThreadedAssignment* unpackAssignment(const unsigned char* dataBuffer, int numBytes);
static ThreadedAssignment* unpackAssignment(const QByteArray& packet);
};
#endif /* defined(__hifi__AssignmentFactory__) */

View file

@ -37,7 +37,6 @@
#include <Logging.h>
#include <NodeList.h>
#include <Node.h>
#include <NodeTypes.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <StdDev.h>
@ -61,8 +60,8 @@ void attachNewBufferToNode(Node *newNode) {
}
}
AudioMixer::AudioMixer(const unsigned char* dataBuffer, int numBytes) :
ThreadedAssignment(dataBuffer, numBytes)
AudioMixer::AudioMixer(const QByteArray& packet) :
ThreadedAssignment(packet)
{
}
@ -210,18 +209,19 @@ void AudioMixer::prepareMixForListeningNode(Node* node) {
void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
// pull any new audio data from nodes off of the network stack
if (dataByteArray[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO
|| dataByteArray[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO
|| dataByteArray[0] == PACKET_TYPE_INJECT_AUDIO) {
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
NUM_BYTES_RFC4122_UUID));
PacketType mixerPacketType = packetTypeForPacket(dataByteArray);
if (mixerPacketType == PacketTypeMicrophoneAudioNoEcho
|| mixerPacketType == PacketTypeMicrophoneAudioWithEcho
|| mixerPacketType == PacketTypeInjectAudio) {
QUuid nodeUUID;
deconstructPacketHeader(dataByteArray, nodeUUID);
NodeList* nodeList = NodeList::getInstance();
SharedNodePointer matchingNode = nodeList->nodeWithUUID(nodeUUID);
if (matchingNode) {
nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, dataByteArray);
if (!matchingNode->getActiveSocket()) {
// we don't have an active socket for this node, but they're talking to us
@ -231,17 +231,17 @@ void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSock
}
} else {
// let processNodeData handle it.
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
}
}
void AudioMixer::run() {
commonInit(AUDIO_MIXER_LOGGING_TARGET_NAME, NODE_TYPE_AUDIO_MIXER);
commonInit(AUDIO_MIXER_LOGGING_TARGET_NAME, NodeType::AudioMixer);
NodeList* nodeList = NodeList::getInstance();
nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
nodeList->linkedDataCreateCallback = attachNewBufferToNode;
@ -250,14 +250,14 @@ void AudioMixer::run() {
gettimeofday(&startTime, NULL);
int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_MIXED_AUDIO);
int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio);
// note: Visual Studio 2010 doesn't support variable sized local arrays
#ifdef _WIN32
unsigned char clientPacket[MAX_PACKET_SIZE];
#else
unsigned char clientPacket[NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesPacketHeader];
#endif
populateTypeAndVersion(clientPacket, PACKET_TYPE_MIXED_AUDIO);
populatePacketHeader(reinterpret_cast<char*>(clientPacket), PacketTypeMixedAudio);
while (!_isFinished) {
@ -274,7 +274,7 @@ void AudioMixer::run() {
}
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket() && node->getLinkedData()
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData()
&& ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) {
prepareMixForListeningNode(node.data());

View file

@ -20,7 +20,7 @@ class AvatarAudioRingBuffer;
class AudioMixer : public ThreadedAssignment {
Q_OBJECT
public:
AudioMixer(const unsigned char* dataBuffer, int numBytes);
AudioMixer(const QByteArray& packet);
public slots:
/// threaded run of assignment
void run();

View file

@ -31,9 +31,10 @@ AvatarAudioRingBuffer* AudioMixerClientData::getAvatarAudioRingBuffer() const {
return NULL;
}
int AudioMixerClientData::parseData(unsigned char* packetData, int numBytes) {
if (packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO
|| packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO) {
int AudioMixerClientData::parseData(const QByteArray& packet) {
PacketType packetType = packetTypeForPacket(packet);
if (packetType == PacketTypeMicrophoneAudioWithEcho
|| packetType == PacketTypeMicrophoneAudioNoEcho) {
// grab the AvatarAudioRingBuffer from the vector (or create it if it doesn't exist)
AvatarAudioRingBuffer* avatarRingBuffer = getAvatarAudioRingBuffer();
@ -45,14 +46,12 @@ int AudioMixerClientData::parseData(unsigned char* packetData, int numBytes) {
}
// ask the AvatarAudioRingBuffer instance to parse the data
avatarRingBuffer->parseData(packetData, numBytes);
avatarRingBuffer->parseData(packet);
} else {
// this is injected audio
// grab the stream identifier for this injected audio
QByteArray rfcUUID = QByteArray((char*) packetData + numBytesForPacketHeader(packetData) + NUM_BYTES_RFC4122_UUID,
NUM_BYTES_RFC4122_UUID);
QUuid streamIdentifier = QUuid::fromRfc4122(rfcUUID);
QUuid streamIdentifier = QUuid::fromRfc4122(packet.mid(numBytesForPacketHeader(packet), NUM_BYTES_RFC4122_UUID));
InjectedAudioRingBuffer* matchingInjectedRingBuffer = NULL;
@ -69,7 +68,7 @@ int AudioMixerClientData::parseData(unsigned char* packetData, int numBytes) {
_ringBuffers.push_back(matchingInjectedRingBuffer);
}
matchingInjectedRingBuffer->parseData(packetData, numBytes);
matchingInjectedRingBuffer->parseData(packet);
}
return 0;

View file

@ -23,7 +23,7 @@ public:
const std::vector<PositionalAudioRingBuffer*> getRingBuffers() const { return _ringBuffers; }
AvatarAudioRingBuffer* getAvatarAudioRingBuffer() const;
int parseData(unsigned char* packetData, int numBytes);
int parseData(const QByteArray& packet);
void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples);
void pushBuffersAfterFrameSend();
private:

View file

@ -15,7 +15,7 @@ AvatarAudioRingBuffer::AvatarAudioRingBuffer() :
}
int AvatarAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
_shouldLoopbackForNode = (sourceBuffer[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO);
return PositionalAudioRingBuffer::parseData(sourceBuffer, numBytes);
int AvatarAudioRingBuffer::parseData(const QByteArray& packet) {
_shouldLoopbackForNode = (packetTypeForPacket(packet) == PacketTypeMicrophoneAudioWithEcho);
return PositionalAudioRingBuffer::parseData(packet);
}

View file

@ -17,7 +17,7 @@ class AvatarAudioRingBuffer : public PositionalAudioRingBuffer {
public:
AvatarAudioRingBuffer();
int parseData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
private:
// disallow copying of AvatarAudioRingBuffer objects
AvatarAudioRingBuffer(const AvatarAudioRingBuffer&);

View file

@ -27,24 +27,13 @@ const char AVATAR_MIXER_LOGGING_NAME[] = "avatar-mixer";
const unsigned int AVATAR_DATA_SEND_INTERVAL_USECS = (1 / 60.0) * 1000 * 1000;
AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) :
ThreadedAssignment(dataBuffer, numBytes)
AvatarMixer::AvatarMixer(const QByteArray& packet) :
ThreadedAssignment(packet)
{
// make sure we hear about node kills so we can tell the other nodes
connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled);
}
unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) {
QByteArray rfcUUID = nodeToAdd->getUUID().toRfc4122();
memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size());
currentPosition += rfcUUID.size();
AvatarData *nodeData = (AvatarData *)nodeToAdd->getLinkedData();
currentPosition += nodeData->getBroadcastData(currentPosition);
return currentPosition;
}
void attachAvatarDataToNode(Node* newNode) {
if (newNode->getLinkedData() == NULL) {
newNode->setLinkedData(new AvatarData());
@ -59,58 +48,51 @@ void attachAvatarDataToNode(Node* newNode) {
// determine which avatars are included in the packet stream
// 4) we should optimize the avatar data format to be more compact (100 bytes is pretty wasteful).
void broadcastAvatarData() {
static unsigned char broadcastPacket[MAX_PACKET_SIZE];
static unsigned char avatarDataBuffer[MAX_PACKET_SIZE];
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_BULK_AVATAR_DATA);
unsigned char* currentBufferPosition = broadcastPacket + numHeaderBytes;
int packetLength = currentBufferPosition - broadcastPacket;
static QByteArray mixedAvatarByteArray;
int numPacketHeaderBytes = populatePacketHeader(mixedAvatarByteArray, PacketTypeBulkAvatarData);
int packetsSent = 0;
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT && node->getActiveSocket()) {
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()) {
// reset packet pointers for this node
currentBufferPosition = broadcastPacket + numHeaderBytes;
packetLength = currentBufferPosition - broadcastPacket;
mixedAvatarByteArray.resize(numPacketHeaderBytes);
// this is an AGENT we have received head data from
// send back a packet with other active node data to this node
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) {
unsigned char* avatarDataEndpoint = addNodeToBroadcastPacket((unsigned char*)&avatarDataBuffer[0],
otherNode.data());
int avatarDataLength = avatarDataEndpoint - (unsigned char*)&avatarDataBuffer;
QByteArray avatarByteArray;
avatarByteArray.append(otherNode->getUUID().toRfc4122());
if (avatarDataLength + packetLength <= MAX_PACKET_SIZE) {
memcpy(currentBufferPosition, &avatarDataBuffer[0], avatarDataLength);
packetLength += avatarDataLength;
currentBufferPosition += avatarDataLength;
} else {
AvatarData *nodeData = (AvatarData *)otherNode->getLinkedData();
avatarByteArray.append(nodeData->toByteArray());
if (avatarByteArray.size() + mixedAvatarByteArray.size() > MAX_PACKET_SIZE) {
packetsSent++;
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket,
currentBufferPosition - broadcastPacket,
nodeList->getNodeSocket().writeDatagram(mixedAvatarByteArray,
node->getActiveSocket()->getAddress(),
node->getActiveSocket()->getPort());
// reset the packet
currentBufferPosition = broadcastPacket + numHeaderBytes;
packetLength = currentBufferPosition - broadcastPacket;
// copy the avatar that didn't fit into the next packet
memcpy(currentBufferPosition, &avatarDataBuffer[0], avatarDataLength);
packetLength += avatarDataLength;
currentBufferPosition += avatarDataLength;
mixedAvatarByteArray.resize(numPacketHeaderBytes);
}
// copy the avatar into the mixedAvatarByteArray packet
mixedAvatarByteArray.append(avatarByteArray);
}
}
packetsSent++;
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
nodeList->getNodeSocket().writeDatagram(mixedAvatarByteArray,
node->getActiveSocket()->getAddress(),
node->getActiveSocket()->getPort());
}
@ -118,18 +100,15 @@ void broadcastAvatarData() {
}
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
if (killedNode->getType() == NODE_TYPE_AGENT
if (killedNode->getType() == NodeType::Agent
&& killedNode->getLinkedData()) {
// this was an avatar we were sending to other people
// send a kill packet for it to our other nodes
unsigned char packetData[MAX_PACKET_SIZE];
int numHeaderBytes = populateTypeAndVersion(packetData, PACKET_TYPE_KILL_AVATAR);
QByteArray killPacket = byteArrayWithPopluatedHeader(PacketTypeKillAvatar);
killPacket += killedNode->getUUID().toRfc4122();
QByteArray rfcUUID = killedNode->getUUID().toRfc4122();
memcpy(packetData + numHeaderBytes, rfcUUID.constData(), rfcUUID.size());
NodeList::getInstance()->broadcastToNodes(packetData, numHeaderBytes + NUM_BYTES_RFC4122_UUID,
QSet<NODE_TYPE>() << NODE_TYPE_AGENT);
NodeList::getInstance()->broadcastToNodes(killPacket,
NodeSet() << NodeType::Agent);
}
}
@ -137,39 +116,38 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
NodeList* nodeList = NodeList::getInstance();
switch (dataByteArray[0]) {
case PACKET_TYPE_HEAD_DATA: {
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
NUM_BYTES_RFC4122_UUID));
switch (packetTypeForPacket(dataByteArray)) {
case PacketTypeAvatarData: {
QUuid nodeUUID;
deconstructPacketHeader(dataByteArray, nodeUUID);
// add or update the node in our list
SharedNodePointer avatarNode = nodeList->nodeWithUUID(nodeUUID);
if (avatarNode) {
// parse positional data from an node
nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr,
(unsigned char*) dataByteArray.data(), dataByteArray.size());
nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr, dataByteArray);
}
break;
}
case PACKET_TYPE_KILL_AVATAR: {
case PacketTypeKillAvatar: {
nodeList->processKillNode(dataByteArray);
break;
}
default:
// hand this off to the NodeList
nodeList->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
nodeList->processNodeData(senderSockAddr, dataByteArray);
break;
}
}
void AvatarMixer::run() {
commonInit(AVATAR_MIXER_LOGGING_NAME, NODE_TYPE_AVATAR_MIXER);
commonInit(AVATAR_MIXER_LOGGING_NAME, NodeType::AvatarMixer);
NodeList* nodeList = NodeList::getInstance();
nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;

View file

@ -14,7 +14,7 @@
/// Handles assignments of type AvatarMixer - distribution of avatar data to various clients
class AvatarMixer : public ThreadedAssignment {
public:
AvatarMixer(const unsigned char* dataBuffer, int numBytes);
AvatarMixer(const QByteArray& packet);
public slots:
/// runs the avatar mixer

View file

@ -17,8 +17,8 @@
const int SEND_INTERVAL = 50;
MetavoxelServer::MetavoxelServer(const unsigned char* dataBuffer, int numBytes) :
ThreadedAssignment(dataBuffer, numBytes),
MetavoxelServer::MetavoxelServer(const QByteArray& packet) :
ThreadedAssignment(packet),
_data(new MetavoxelData()) {
_sendTimer.setSingleShot(true);
@ -32,7 +32,7 @@ void MetavoxelServer::removeSession(const QUuid& sessionId) {
const char METAVOXEL_SERVER_LOGGING_NAME[] = "metavoxel-server";
void MetavoxelServer::run() {
commonInit(METAVOXEL_SERVER_LOGGING_NAME, NODE_TYPE_METAVOXEL_SERVER);
commonInit(METAVOXEL_SERVER_LOGGING_NAME, NodeType::MetavoxelServer);
_lastSend = QDateTime::currentMSecsSinceEpoch();
_sendTimer.start(SEND_INTERVAL);
@ -40,12 +40,12 @@ void MetavoxelServer::run() {
void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
switch (dataByteArray.at(0)) {
case PACKET_TYPE_METAVOXEL_DATA:
case PacketTypeMetavoxelData:
processData(dataByteArray, senderSockAddr);
break;
default:
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*)dataByteArray.data(), dataByteArray.size());
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
break;
}
}

View file

@ -28,7 +28,7 @@ class MetavoxelServer : public ThreadedAssignment {
public:
MetavoxelServer(const unsigned char* dataBuffer, int numBytes);
MetavoxelServer(const QByteArray& packet);
const MetavoxelDataPointer& getData() const { return _data; }

View file

@ -9,6 +9,7 @@
#include <QtCore/QUuid>
#include <PacketHeaders.h>
#include <HifiSockAddr.h>
#include <UUID.h>
#include "DataServer.h"
@ -51,66 +52,59 @@ DataServer::~DataServer() {
const int MAX_PACKET_SIZE = 1500;
void DataServer::readPendingDatagrams() {
qint64 receivedBytes = 0;
static unsigned char packetData[MAX_PACKET_SIZE];
QByteArray receivedPacket;
HifiSockAddr senderSockAddr;
while (_socket.hasPendingDatagrams() &&
(receivedBytes = _socket.readDatagram(reinterpret_cast<char*>(packetData), MAX_PACKET_SIZE,
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()))) {
if ((packetData[0] == PACKET_TYPE_DATA_SERVER_PUT || packetData[0] == PACKET_TYPE_DATA_SERVER_GET) &&
packetVersionMatch(packetData, senderSockAddr)) {
int readBytes = numBytesForPacketHeader(packetData);
while (_socket.hasPendingDatagrams()) {
receivedPacket.resize(_socket.pendingDatagramSize());
_socket.readDatagram(receivedPacket.data(), _socket.pendingDatagramSize());
PacketType requestType = packetTypeForPacket(receivedPacket);
if ((requestType == PacketTypeDataServerPut || requestType == PacketTypeDataServerGet) &&
packetVersionMatch(receivedPacket)) {
QDataStream packetStream(receivedPacket);
int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket);
packetStream.skipRawData(numReceivedHeaderBytes);
// pull the sequence number used for this packet
quint8 sequenceNumber = 0;
memcpy(&sequenceNumber, packetData + readBytes, sizeof(sequenceNumber));
readBytes += sizeof(sequenceNumber);
packetStream >> sequenceNumber;
// pull the UUID that we will need as part of the key
QString uuidString(reinterpret_cast<char*>(packetData + readBytes));
QUuid parsedUUID(uuidString);
QString userString;
packetStream >> userString;
QUuid parsedUUID(userString);
if (parsedUUID.isNull()) {
// we failed to parse a UUID, this means the user has sent us a username
QString username(reinterpret_cast<char*>(packetData + readBytes));
readBytes += username.size() + sizeof('\0');
// ask redis for the UUID for this user
redisReply* reply = (redisReply*) redisCommand(_redis, "GET user:%s", qPrintable(username));
redisReply* reply = (redisReply*) redisCommand(_redis, "GET user:%s", qPrintable(userString));
if (reply->type == REDIS_REPLY_STRING) {
parsedUUID = QUuid(QString(reply->str));
}
if (!parsedUUID.isNull()) {
qDebug() << "Found UUID" << parsedUUID << "for username" << username;
qDebug() << "Found UUID" << parsedUUID << "for username" << userString;
} else {
qDebug() << "Failed UUID lookup for username" << username;
qDebug() << "Failed UUID lookup for username" << userString;
}
freeReplyObject(reply);
reply = NULL;
} else {
readBytes += uuidString.size() + sizeof('\0');
}
if (!parsedUUID.isNull()) {
// pull the number of keys the user has sent
unsigned char numKeys = packetData[readBytes++];
if (packetData[0] == PACKET_TYPE_DATA_SERVER_PUT) {
if (requestType == PacketTypeDataServerPut) {
// pull the key that specifies the data the user is putting/getting
QString dataKey(reinterpret_cast<char*>(packetData + readBytes));
readBytes += dataKey.size() + sizeof('\0');
// pull the key and value that specifies the data the user is putting/getting
QString dataKey, dataValue;
// grab the string value the user wants us to put, null terminate it
QString dataValue(reinterpret_cast<char*>(packetData + readBytes));
readBytes += dataValue.size() + sizeof('\0');
packetStream >> dataKey >> dataValue;
qDebug("Sending command to redis: SET uuid:%s:%s %s",
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
@ -122,9 +116,12 @@ void DataServer::readPendingDatagrams() {
if (reply->type == REDIS_REPLY_STATUS && strcmp("OK", reply->str) == 0) {
// if redis stored the value successfully reply back with a confirm
// which is the sent packet with the header replaced
packetData[0] = PACKET_TYPE_DATA_SERVER_CONFIRM;
_socket.writeDatagram(reinterpret_cast<char*>(packetData), receivedBytes,
// which is a reply packet with the sequence number
QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerConfirm);
replyPacket.append(sequenceNumber);
_socket.writeDatagram(replyPacket,
senderSockAddr.getAddress(), senderSockAddr.getPort());
}
@ -132,66 +129,49 @@ void DataServer::readPendingDatagrams() {
} else {
// setup a send packet with the returned data
// leverage the packetData sent by overwriting and appending
int numSendPacketBytes = receivedBytes;
QByteArray sendPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerSend);
packetData[0] = PACKET_TYPE_DATA_SERVER_SEND;
if (strcmp((char*) packetData + readBytes, "uuid") != 0) {
if (!receivedPacket.mid(numReceivedHeaderBytes).startsWith("uuid")) {
const char MULTI_KEY_VALUE_SEPARATOR = '|';
// the user has sent one or more keys - make the associated requests
for (int j = 0; j < numKeys; j++) {
// pull the key that specifies the data the user is putting/getting, null terminate it
int numDataKeyBytes = 0;
// look for the key separator or the null terminator
while (packetData[readBytes + numDataKeyBytes] != MULTI_KEY_VALUE_SEPARATOR
&& packetData[readBytes + numDataKeyBytes] != '\0') {
numDataKeyBytes++;
}
QString dataKey(QByteArray(reinterpret_cast<char*>(packetData + readBytes), numDataKeyBytes));
readBytes += dataKey.size() + sizeof('\0');
// pull the key that specifies the data the user is putting/getting, null terminate it
QString keyListString(receivedPacket.mid(numReceivedHeaderBytes));
QStringList keyList = keyListString.split(MULTI_KEY_VALUE_SEPARATOR);
foreach (const QString& dataKey, keyList) {
qDebug("Sending command to redis: GET uuid:%s:%s",
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
qPrintable(dataKey));
redisReply* reply = (redisReply*) redisCommand(_redis, "GET uuid:%s:%s",
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
qPrintable(dataKey));
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
qPrintable(dataKey));
if (reply->len) {
// copy the value that redis returned
memcpy(packetData + numSendPacketBytes, reply->str, reply->len);
numSendPacketBytes += reply->len;
sendPacket.append(reply->str, reply->len);
} else {
// didn't find a value - insert a space
packetData[numSendPacketBytes++] = ' ';
sendPacket.append(' ');
}
// add the multi-value separator
packetData[numSendPacketBytes++] = MULTI_KEY_VALUE_SEPARATOR;
sendPacket.append(MULTI_KEY_VALUE_SEPARATOR);
freeReplyObject(reply);
}
// null terminate the packet we're sending back (erases the trailing separator)
packetData[(numSendPacketBytes - 1)] = '\0';
sendPacket[sendPacket.size() - 1] = '\0';
} else {
// user is asking for a UUID matching username, copy the UUID we found
QString uuidString = uuidStringWithoutCurlyBraces(parsedUUID);
memcpy(packetData + numSendPacketBytes, qPrintable(uuidString), uuidString.size() + sizeof('\0'));
numSendPacketBytes += uuidString.size() + sizeof('\0');
sendPacket.append(uuidStringWithoutCurlyBraces(parsedUUID));
sendPacket.append('\0');
}
// reply back with the send packet
_socket.writeDatagram(reinterpret_cast<char*>(packetData), numSendPacketBytes,
senderSockAddr.getAddress(), senderSockAddr.getPort());
_socket.writeDatagram(sendPacket, senderSockAddr.getAddress(), senderSockAddr.getPort());
}
}
}

View file

@ -66,7 +66,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
_metavoxelServerConfig = getCmdOption(argc, (const char**) argv, metavoxelConfigOption.constData());
}
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, domainServerPort);
NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort);
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), this, SLOT(nodeKilled(SharedNodePointer)));
@ -102,39 +102,39 @@ void DomainServer::readAvailableDatagrams() {
NodeList* nodeList = NodeList::getInstance();
HifiSockAddr senderSockAddr, nodePublicAddress, nodeLocalAddress;
static unsigned char packetData[MAX_PACKET_SIZE];
static unsigned char broadcastPacket[MAX_PACKET_SIZE];
static unsigned char* currentBufferPos;
static unsigned char* startPointer;
int receivedBytes = 0;
static QByteArray broadcastPacket = byteArrayWithPopluatedHeader(PacketTypeDomainList);
static int numBroadcastPacketHeaderBytes = broadcastPacket.size();
static QByteArray assignmentPacket = byteArrayWithPopluatedHeader(PacketTypeCreateAssignment);
static int numAssignmentPacketHeaderBytes = assignmentPacket.size();
QByteArray receivedPacket;
NodeType_t nodeType;
QUuid nodeUUID;
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
senderSockAddr.getAddressPointer(),
senderSockAddr.getPortPointer()))
&& packetVersionMatch((unsigned char*) packetData, senderSockAddr)) {
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
if (packetVersionMatch(receivedPacket)) {
PacketType requestType = packetTypeForPacket(receivedPacket);
if (requestType == PacketTypeDomainListRequest) {
// this is an RFD or domain list request packet, and there is a version match
int numBytesSenderHeader = numBytesForPacketHeader((unsigned char*) packetData);
NODE_TYPE nodeType = *(packetData + numBytesSenderHeader);
int packetIndex = numBytesSenderHeader + sizeof(NODE_TYPE);
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray(((char*) packetData + packetIndex), NUM_BYTES_RFC4122_UUID));
packetIndex += NUM_BYTES_RFC4122_UUID;
int numBytesPrivateSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodePublicAddress);
packetIndex += numBytesPrivateSocket;
QDataStream packetStream(receivedPacket);
packetStream.skipRawData(numBytesForPacketHeader(receivedPacket));
deconstructPacketHeader(receivedPacket, nodeUUID);
packetStream >> nodeType;
packetStream >> nodePublicAddress >> nodeLocalAddress;
if (nodePublicAddress.getAddress().isNull()) {
// this node wants to use us its STUN server
// so set the node public address to whatever we perceive the public address to be
// if the sender is on our box then leave its public address to 0 so that
// other users attempt to reach it on the same address they have for the domain-server
if (senderSockAddr.getAddress().isLoopback()) {
@ -143,20 +143,14 @@ void DomainServer::readAvailableDatagrams() {
nodePublicAddress.setAddress(senderSockAddr.getAddress());
}
}
int numBytesPublicSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodeLocalAddress);
packetIndex += numBytesPublicSocket;
const char STATICALLY_ASSIGNED_NODES[] = {
NODE_TYPE_AUDIO_MIXER,
NODE_TYPE_AVATAR_MIXER,
NODE_TYPE_VOXEL_SERVER,
NODE_TYPE_METAVOXEL_SERVER
};
const NodeSet STATICALLY_ASSIGNED_NODES = NodeSet() << NodeType::AudioMixer
<< NodeType::AvatarMixer << NodeType::VoxelServer << NodeType::ParticleServer
<< NodeType::MetavoxelServer;
Assignment* matchingStaticAssignment = NULL;
if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL
if (!STATICALLY_ASSIGNED_NODES.contains(nodeType)
|| ((matchingStaticAssignment = matchingStaticAssignmentForCheckIn(nodeUUID, nodeType))
|| checkInWithUUIDMatchesExistingNode(nodePublicAddress,
nodeLocalAddress,
@ -166,80 +160,82 @@ void DomainServer::readAvailableDatagrams() {
nodeType,
nodePublicAddress,
nodeLocalAddress);
// resize our broadcast packet in preparation to set it up again
broadcastPacket.resize(numBroadcastPacketHeaderBytes);
if (matchingStaticAssignment) {
// this was a newly added node with a matching static assignment
if (_hasCompletedRestartHold) {
// remove the matching assignment from the assignment queue so we don't take the next check in
removeAssignmentFromQueue(matchingStaticAssignment);
}
// set the linked data for this node to a copy of the matching assignment
// so we can re-queue it should the node die
Assignment* nodeCopyOfMatchingAssignment = new Assignment(*matchingStaticAssignment);
checkInNode->setLinkedData(nodeCopyOfMatchingAssignment);
}
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
currentBufferPos = broadcastPacket + numHeaderBytes;
startPointer = currentBufferPos;
unsigned char* nodeTypesOfInterest = packetData + packetIndex + sizeof(unsigned char);
int numInterestTypes = *(nodeTypesOfInterest - 1);
quint8 numInterestTypes = 0;
packetStream >> numInterestTypes;
NodeType_t* nodeTypesOfInterest = reinterpret_cast<NodeType_t*>(receivedPacket.data()
+ packetStream.device()->pos());
if (numInterestTypes > 0) {
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
// if the node has sent no types of interest, assume they want nothing but their own ID back
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getUUID() != nodeUUID &&
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
// don't send avatar nodes to other avatars, that will come from avatar mixer
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, node.data());
}
broadcastDataStream << *node.data();
}
}
}
// update last receive to now
uint64_t timeNow = usecTimestampNow();
quint64 timeNow = usecTimestampNow();
checkInNode->setLastHeardMicrostamp(timeNow);
// send the constructed list back to this node
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket,
(currentBufferPos - startPointer) + numHeaderBytes,
nodeList->getNodeSocket().writeDatagram(broadcastPacket,
senderSockAddr.getAddress(), senderSockAddr.getPort());
}
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
} else if (requestType == PacketTypeRequestAssignment) {
if (_assignmentQueue.size() > 0) {
// construct the requested assignment from the packet data
Assignment requestAssignment(packetData, receivedBytes);
Assignment requestAssignment(receivedPacket);
qDebug("Received a request for assignment type %i from %s.",
requestAssignment.getType(), qPrintable(senderSockAddr.getAddress().toString()));
Assignment* assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
if (assignmentToDeploy) {
// 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 = assignmentToDeploy->packToBuffer(broadcastPacket + numHeaderBytes);
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, numHeaderBytes + numAssignmentBytes,
assignmentPacket.resize(numAssignmentPacketHeaderBytes);
QDataStream assignmentStream(&assignmentPacket, QIODevice::Append);
assignmentStream << *assignmentToDeploy;
nodeList->getNodeSocket().writeDatagram(assignmentPacket,
senderSockAddr.getAddress(), senderSockAddr.getPort());
if (assignmentToDeploy->getNumberOfInstances() == 0) {
// there are no more instances of this script to send out, delete it
delete assignmentToDeploy;
}
}
} else {
qDebug() << "Received an invalid assignment request from" << senderSockAddr.getAddress();
}
@ -266,7 +262,7 @@ QJsonObject jsonObjectForNode(Node* node) {
QJsonObject nodeJson;
// re-format the type name so it matches the target name
QString nodeTypeName(node->getTypeName());
QString nodeTypeName = NodeType::getNodeTypeName(node->getType());
nodeTypeName = nodeTypeName.toLower();
nodeTypeName.replace(' ', '-');
@ -278,8 +274,8 @@ QJsonObject jsonObjectForNode(Node* node) {
nodeJson[JSON_KEY_LOCAL_SOCKET] = jsonForSocket(node->getLocalSocket());
// if the node has pool information, add it
if (node->getLinkedData() && ((Assignment*) node->getLinkedData())->hasPool()) {
nodeJson[JSON_KEY_POOL] = QString(((Assignment*) node->getLinkedData())->getPool());
if (node->getLinkedData() && !((Assignment*) node->getLinkedData())->getPool().isEmpty()) {
nodeJson[JSON_KEY_POOL] = ((Assignment*) node->getLinkedData())->getPool();
}
return nodeJson;
@ -386,8 +382,8 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
queuedAssignmentJSON[JSON_KEY_TYPE] = QString((*assignment)->getTypeName());
// if the assignment has a pool, add it
if ((*assignment)->hasPool()) {
queuedAssignmentJSON[JSON_KEY_POOL] = QString((*assignment)->getPool());
if (!(*assignment)->getPool().isEmpty()) {
queuedAssignmentJSON[JSON_KEY_POOL] = (*assignment)->getPool();
}
// add this queued assignment to the JSON
@ -538,21 +534,6 @@ void DomainServer::nodeKilled(SharedNodePointer node) {
}
}
unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd) {
*currentPosition++ = nodeToAdd->getType();
QByteArray rfcUUID = nodeToAdd->getUUID().toRfc4122();
memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size());
currentPosition += rfcUUID.size();
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getPublicSocket());
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getLocalSocket());
// return the new unsigned char * for broadcast packet
return currentPosition;
}
void DomainServer::prepopulateStaticAssignmentFile() {
int numFreshStaticAssignments = 0;
@ -595,9 +576,8 @@ void DomainServer::prepopulateStaticAssignmentFile() {
Assignment voxelServerAssignment(Assignment::CreateCommand,
Assignment::VoxelServerType,
(assignmentPool.isEmpty() ? NULL : assignmentPool.toLocal8Bit().constData()));
int payloadLength = config.length() + sizeof(char);
voxelServerAssignment.setPayload((uchar*)config.toLocal8Bit().constData(), payloadLength);
voxelServerAssignment.setPayload(config.toUtf8());
freshStaticAssignments[numFreshStaticAssignments++] = voxelServerAssignment;
}
@ -637,9 +617,8 @@ void DomainServer::prepopulateStaticAssignmentFile() {
Assignment particleServerAssignment(Assignment::CreateCommand,
Assignment::ParticleServerType,
(assignmentPool.isEmpty() ? NULL : assignmentPool.toLocal8Bit().constData()));
int payloadLength = config.length() + sizeof(char);
particleServerAssignment.setPayload((uchar*)config.toLocal8Bit().constData(), payloadLength);
particleServerAssignment.setPayload(config.toLocal8Bit());
freshStaticAssignments[numFreshStaticAssignments++] = particleServerAssignment;
}
@ -652,7 +631,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
Assignment& metavoxelAssignment = (freshStaticAssignments[numFreshStaticAssignments++] =
Assignment(Assignment::CreateCommand, Assignment::MetavoxelServerType));
if (_metavoxelServerConfig) {
metavoxelAssignment.setPayload((const unsigned char*)_metavoxelServerConfig, strlen(_metavoxelServerConfig));
metavoxelAssignment.setPayload(QByteArray(_metavoxelServerConfig));
}
qDebug() << "Adding" << numFreshStaticAssignments << "static assignments to fresh file.";
@ -663,7 +642,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
_staticAssignmentFile.close();
}
Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType) {
Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType) {
// pull the UUID passed with the check in
if (_hasCompletedRestartHold) {
@ -708,10 +687,8 @@ Assignment* DomainServer::deployableAssignmentForRequest(Assignment& requestAssi
while (assignment != _assignmentQueue.end()) {
bool requestIsAllTypes = requestAssignment.getType() == Assignment::AllTypes;
bool assignmentTypesMatch = (*assignment)->getType() == requestAssignment.getType();
bool nietherHasPool = !(*assignment)->hasPool() && !requestAssignment.hasPool();
bool assignmentPoolsMatch = memcmp((*assignment)->getPool(),
requestAssignment.getPool(),
MAX_ASSIGNMENT_POOL_BYTES) == 0;
bool nietherHasPool = (*assignment)->getPool().isEmpty() && requestAssignment.getPool().isEmpty();
bool assignmentPoolsMatch = (*assignment)->getPool() == requestAssignment.getPool();
if ((requestIsAllTypes || assignmentTypesMatch) && (nietherHasPool || assignmentPoolsMatch)) {

View file

@ -39,7 +39,7 @@ private:
QString readServerAssignmentConfig(QJsonObject jsonObj, const char* nodeName);
void prepopulateStaticAssignmentFile();
Assignment* matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType);
Assignment* matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType);
Assignment* deployableAssignmentForRequest(Assignment& requestAssignment);
void removeAssignmentFromQueue(Assignment* removableAssignment);
bool checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePublicSocket,
@ -47,8 +47,6 @@ private:
const QUuid& checkInUUI);
void addReleasedAssignmentBackToQueue(Assignment* releasedAssignment);
unsigned char* addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd);
HTTPManager _HTTPManager;
QMutex _assignmentQueueMutex;

View file

@ -50,7 +50,6 @@
#include <QMediaPlayer>
#include <AudioInjector.h>
#include <NodeTypes.h>
#include <Logging.h>
#include <OctalCode.h>
#include <PacketHeaders.h>
@ -183,7 +182,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_nodeThread->setPriority(QThread::TimeCriticalPriority);
// put the NodeList and datagram processing on the node thread
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
NodeList* nodeList = NodeList::createInstance(NodeType::Agent, listenPort);
nodeList->moveToThread(_nodeThread);
_datagramProcessor.moveToThread(_nodeThread);
@ -230,9 +229,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
#endif
// tell the NodeList instance who to tell the domain server we care about
nodeList->addSetOfNodeTypesToNodeInterestSet(QSet<NODE_TYPE>() << NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER
<< NODE_TYPE_VOXEL_SERVER << NODE_TYPE_PARTICLE_SERVER
<< NODE_TYPE_METAVOXEL_SERVER);
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer
<< NodeType::VoxelServer << NodeType::ParticleServer
<< NodeType::MetavoxelServer);
// connect to the packet sent signal of the _voxelEditSender and the _particleEditSender
connect(&_voxelEditSender, &VoxelEditPacketSender::packetSent, this, &Application::packetSent);
@ -651,32 +650,30 @@ void Application::resetProfile(const QString& username) {
updateWindowTitle();
}
void Application::controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
const QSet<NODE_TYPE>& destinationNodeTypes) {
foreach(NODE_TYPE type, destinationNodeTypes) {
void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
foreach(NodeType_t type, destinationNodeTypes) {
// Intercept data to voxel server when voxels are disabled
if (type == NODE_TYPE_VOXEL_SERVER && !Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
if (type == NodeType::VoxelServer && !Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
continue;
}
// Perform the broadcast for one type
int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(broadcastData, dataBytes,
QSet<NODE_TYPE>() << type);
int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(packet, NodeSet() << type);
// Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise)
BandwidthMeter::ChannelIndex channel;
switch (type) {
case NODE_TYPE_AGENT:
case NODE_TYPE_AVATAR_MIXER:
case NodeType::Agent:
case NodeType::AvatarMixer:
channel = BandwidthMeter::AVATARS;
break;
case NODE_TYPE_VOXEL_SERVER:
case NodeType::VoxelServer:
channel = BandwidthMeter::VOXELS;
break;
default:
continue;
}
_bandwidthMeter.outputStream(channel).updateValue(nReceivingNodes * dataBytes);
_bandwidthMeter.outputStream(channel).updateValue(nReceivingNodes * packet.size());
}
}
@ -1409,13 +1406,11 @@ void Application::wheelEvent(QWheelEvent* event) {
}
void Application::sendPingPackets() {
unsigned char pingPacket[MAX_PACKET_SIZE];
int length = NodeList::getInstance()->fillPingPacket(pingPacket);
getInstance()->controlledBroadcastToNodes(pingPacket, length, QSet<NODE_TYPE>()
<< NODE_TYPE_VOXEL_SERVER << NODE_TYPE_PARTICLE_SERVER
<< NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER
<< NODE_TYPE_METAVOXEL_SERVER);
QByteArray pingPacket = NodeList::getInstance()->constructPingPacket();
getInstance()->controlledBroadcastToNodes(pingPacket, NodeSet() << NodeType::VoxelServer
<< NodeType::ParticleServer
<< NodeType::AudioMixer << NodeType::AvatarMixer
<< NodeType::MetavoxelServer);
}
// Every second, check the frame rates and other stuff
@ -1553,7 +1548,7 @@ void Application::removeVoxel(glm::vec3 position,
voxel.y = position.y / TREE_SCALE;
voxel.z = position.z / TREE_SCALE;
voxel.s = scale / TREE_SCALE;
_voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_VOXEL_ERASE, voxel);
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, voxel);
// delete it locally to see the effect immediately (and in case no voxel server is present)
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
@ -1574,7 +1569,7 @@ void Application::makeVoxel(glm::vec3 position,
voxel.red = red;
voxel.green = green;
voxel.blue = blue;
PACKET_TYPE message = isDestructive ? PACKET_TYPE_VOXEL_SET_DESTRUCTIVE : PACKET_TYPE_VOXEL_SET;
PacketType message = isDestructive ? PacketTypeVoxelSetDestructive : PacketTypeVoxelSet;
_voxelEditSender.sendVoxelEditMessage(message, voxel);
// create the voxel locally so it appears immediately
@ -1644,7 +1639,7 @@ bool Application::sendVoxelsOperation(OctreeElement* element, void* extraData) {
codeColorBuffer[bytesInCode + RED_INDEX] = voxel->getColor()[RED_INDEX];
codeColorBuffer[bytesInCode + GREEN_INDEX] = voxel->getColor()[GREEN_INDEX];
codeColorBuffer[bytesInCode + BLUE_INDEX] = voxel->getColor()[BLUE_INDEX];
getInstance()->_voxelEditSender.queueVoxelEditMessage(PACKET_TYPE_VOXEL_SET_DESTRUCTIVE,
getInstance()->_voxelEditSender.queueVoxelEditMessage(PacketTypeVoxelSetDestructive,
codeColorBuffer, codeAndColorLength);
delete[] codeColorBuffer;
@ -2337,7 +2332,7 @@ void Application::updateCursor(float deltaTime) {
// watch mouse position, if it hasn't moved, hide the cursor
bool underMouse = _glWidget->underMouse();
if (!_mouseHidden) {
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
int elapsed = now - _lastMouseMove;
const int HIDE_CURSOR_TIMEOUT = 1 * 1000 * 1000; // 1 second
if (elapsed > HIDE_CURSOR_TIMEOUT && (underMouse || !_seenMouseMove)) {
@ -2438,18 +2433,10 @@ void Application::updateAvatar(float deltaTime) {
_myAvatar.getHead().setAudioLoudness(_audio.getLastInputLoudness());
// send head/hand data to the avatar mixer and voxel server
unsigned char broadcastString[MAX_PACKET_SIZE];
unsigned char* endOfBroadcastStringWrite = broadcastString;
QByteArray avatarData = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
avatarData.append(_myAvatar.toByteArray());
endOfBroadcastStringWrite += populateTypeAndVersion(endOfBroadcastStringWrite, PACKET_TYPE_HEAD_DATA);
// pack the NodeList owner UUID
endOfBroadcastStringWrite += NodeList::getInstance()->packOwnerUUID(endOfBroadcastStringWrite);
endOfBroadcastStringWrite += _myAvatar.getBroadcastData(endOfBroadcastStringWrite);
controlledBroadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString,
QSet<NODE_TYPE>() << NODE_TYPE_AVATAR_MIXER);
controlledBroadcastToNodes(avatarData, NodeSet() << NodeType::AvatarMixer);
// Update _viewFrustum with latest camera and view frustum data...
// NOTE: we get this from the view frustum, to make it simpler, since the
@ -2460,11 +2447,11 @@ void Application::updateAvatar(float deltaTime) {
loadViewFrustum(_myCamera, _viewFrustum);
// Update my voxel servers with my current voxel query...
queryOctree(NODE_TYPE_VOXEL_SERVER, PACKET_TYPE_VOXEL_QUERY, _voxelServerJurisdictions);
queryOctree(NODE_TYPE_PARTICLE_SERVER, PACKET_TYPE_PARTICLE_QUERY, _particleServerJurisdictions);
queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions);
queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions);
}
void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions) {
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
// if voxels are disabled, then don't send this at all...
if (!Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
@ -2632,10 +2619,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
// insert packet type/version and node UUID
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
endOfVoxelQueryPacket += ownerUUID.size();
endOfVoxelQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfVoxelQueryPacket), packetType);
// encode the query data...
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
@ -3146,7 +3130,7 @@ void Application::displayOverlay() {
// Show on-screen msec timer
if (Menu::getInstance()->isOptionChecked(MenuOption::FrameTimer)) {
char frameTimer[10];
uint64_t mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
sprintf(frameTimer, "%d\n", (int)(mSecsNow % 1000));
int timerBottom =
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
@ -3237,10 +3221,8 @@ void Application::displayStats() {
glPointSize(1.0f);
int totalAvatars = 0, totalServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++;
}
int totalAvatars = _avatarManager.size();
int totalServers = NodeList::getInstance()->size();
if (mirrorEnabled) {
horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
@ -3283,8 +3265,8 @@ void Application::displayStats() {
int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0;
NodeList* nodeList = NodeList::getInstance();
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
pingAudio = audioMixerNode ? audioMixerNode->getPingMs() : 0;
pingAvatar = avatarMixerNode ? avatarMixerNode->getPingMs() : 0;
@ -3294,7 +3276,7 @@ void Application::displayStats() {
int voxelServerCount = 0;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
if (node->getType() == NodeType::VoxelServer) {
totalPingVoxel += node->getPingMs();
voxelServerCount++;
if (pingVoxelMax < node->getPingMs()) {
@ -3365,7 +3347,7 @@ void Application::displayStats() {
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarBodyYaw, .93f, .93f, .93f);
if (_statsExpanded) {
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer);
if (avatarMixer) {
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
roundf(avatarMixer->getAverageKilobitsPerSecond()),
@ -3939,7 +3921,7 @@ bool Application::maybeEditVoxelUnderCursor() {
void Application::deleteVoxelUnderCursor() {
if (_mouseVoxel.s != 0) {
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
_voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_VOXEL_ERASE, _mouseVoxel);
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, _mouseVoxel);
// delete it locally to see the effect immediately (and in case no voxel server is present)
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
@ -4043,7 +4025,7 @@ void Application::domainChanged(const QString& domainHostname) {
}
void Application::nodeKilled(SharedNodePointer node) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
if (node->getType() == NodeType::VoxelServer) {
QUuid nodeUUID = node->getUUID();
// see if this is the first we've heard of this node...
if (_voxelServerJurisdictions.find(nodeUUID) != _voxelServerJurisdictions.end()) {
@ -4074,7 +4056,7 @@ void Application::nodeKilled(SharedNodePointer node) {
}
_voxelSceneStatsLock.unlock();
} else if (node->getType() == NODE_TYPE_PARTICLE_SERVER) {
} else if (node->getType() == NodeType::ParticleServer) {
QUuid nodeUUID = node->getUUID();
// see if this is the first we've heard of this node...
if (_particleServerJurisdictions.find(nodeUUID) != _particleServerJurisdictions.end()) {
@ -4105,14 +4087,13 @@ void Application::nodeKilled(SharedNodePointer node) {
}
_voxelSceneStatsLock.unlock();
} else if (node->getType() == NODE_TYPE_AVATAR_MIXER) {
} else if (node->getType() == NodeType::AvatarMixer) {
// our avatar mixer has gone away - clear the hash of avatars
_avatarManager.clearHash();
}
}
void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength,
const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
void Application::trackIncomingVoxelPacket(const QByteArray& packet, const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
// Attempt to identify the sender from it's address.
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
@ -4123,13 +4104,13 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m
_voxelSceneStatsLock.lockForWrite();
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
VoxelSceneStats& stats = _octreeServerSceneStats[nodeUUID];
stats.trackIncomingOctreePacket(messageData, messageLength, wasStatsPacket, serverNode->getClockSkewUsec());
stats.trackIncomingOctreePacket(packet, wasStatsPacket, serverNode->getClockSkewUsec());
}
_voxelSceneStatsLock.unlock();
}
}
int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) {
int Application::parseOctreeStats(const QByteArray& packet, const HifiSockAddr& senderSockAddr) {
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
SharedNodePointer server = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
@ -4137,7 +4118,7 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
// parse the incoming stats datas stick it in a temporary object for now, while we
// determine which server it belongs to
VoxelSceneStats temp;
int statsMessageLength = temp.unpackFromMessage(messageData, messageLength);
int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
// quick fix for crash... why would voxelServer be NULL?
if (server) {
@ -4146,7 +4127,8 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
// now that we know the node ID, let's add these stats to the stats for that node...
_voxelSceneStatsLock.lockForWrite();
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
_octreeServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
_octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()),
packet.size());
} else {
_octreeServerSceneStats[nodeUUID] = temp;
}
@ -4157,7 +4139,7 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
// see if this is the first we've heard of this node...
NodeToJurisdictionMap* jurisdiction = NULL;
if (server->getType() == NODE_TYPE_VOXEL_SERVER) {
if (server->getType() == NodeType::VoxelServer) {
jurisdiction = &_voxelServerJurisdictions;
} else {
jurisdiction = &_particleServerJurisdictions;

View file

@ -175,8 +175,7 @@ public:
Profile* getProfile() { return &_profile; }
void resetProfile(const QString& username);
void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
const QSet<NODE_TYPE>& destinationNodeTypes);
void controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes);
void setupWorldLight();
@ -299,7 +298,7 @@ private:
void renderHighlightVoxel(VoxelDetail voxel);
void updateAvatar(float deltaTime);
void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions);
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
glm::vec3 getSunDirection();
@ -404,7 +403,7 @@ private:
int _mouseY;
int _mouseDragStartedX;
int _mouseDragStartedY;
uint64_t _lastMouseMove;
quint64 _lastMouseMove;
bool _mouseHidden;
bool _seenMouseMove;
@ -482,9 +481,8 @@ private:
PieMenu _pieMenu;
int parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress);
void trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength,
const HifiSockAddr& senderSockAddr, bool wasStatsPacket);
int parseOctreeStats(const QByteArray& packet, const HifiSockAddr& senderAddress);
void trackIncomingVoxelPacket(const QByteArray& packet, const HifiSockAddr& senderSockAddr, bool wasStatsPacket);
NodeToJurisdictionMap _voxelServerJurisdictions;
NodeToJurisdictionMap _particleServerJurisdictions;

View file

@ -22,7 +22,6 @@
#include <AngleUtil.h>
#include <NodeList.h>
#include <NodeTypes.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <StdDev.h>
@ -286,8 +285,8 @@ void Audio::start() {
void Audio::handleAudioInput() {
static char monoAudioDataPacket[MAX_PACKET_SIZE];
static int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO);
static int leadingBytes = numBytesPacketHeader + sizeof(glm::vec3) + sizeof(glm::quat) + NUM_BYTES_RFC4122_UUID;
static int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMicrophoneAudioNoEcho);
static int leadingBytes = numBytesPacketHeader + sizeof(glm::vec3) + sizeof(glm::quat);
static int16_t* monoAudioSamples = (int16_t*) (monoAudioDataPacket + leadingBytes);
@ -366,7 +365,7 @@ void Audio::handleAudioInput() {
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
NodeList* nodeList = NodeList::getInstance();
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
@ -376,16 +375,10 @@ void Audio::handleAudioInput() {
// we need the amount of bytes in the buffer + 1 for type
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
PACKET_TYPE packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
? PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO : PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO;
PacketType packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
? PacketTypeMicrophoneAudioWithEcho : PacketTypeMicrophoneAudioNoEcho;
char* currentPacketPtr = monoAudioDataPacket + populateTypeAndVersion((unsigned char*) monoAudioDataPacket,
packetType);
// pack Source Data
QByteArray rfcUUID = NodeList::getInstance()->getOwnerUUID().toRfc4122();
memcpy(currentPacketPtr, rfcUUID.constData(), rfcUUID.size());
currentPacketPtr += rfcUUID.size();
char* currentPacketPtr = monoAudioDataPacket + populatePacketHeader(monoAudioDataPacket, packetType);
// memcpy the three float positions
memcpy(currentPacketPtr, &headPosition, sizeof(headPosition));
@ -434,7 +427,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
}
}
_ringBuffer.parseData((unsigned char*) audioByteArray.data(), audioByteArray.size());
_ringBuffer.parseData(audioByteArray);
static float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate())
* (_desiredOutputFormat.channelCount() / (float) _outputFormat.channelCount());

View file

@ -26,53 +26,53 @@ void DatagramProcessor::processDatagrams() {
"DatagramProcessor::processDatagrams()");
HifiSockAddr senderSockAddr;
ssize_t bytesReceived;
static unsigned char incomingPacket[MAX_PACKET_SIZE];
static QByteArray incomingPacket;
Application* application = Application::getInstance();
NodeList* nodeList = NodeList::getInstance();
while (NodeList::getInstance()->getNodeSocket().hasPendingDatagrams() &&
(bytesReceived = NodeList::getInstance()->getNodeSocket().readDatagram((char*) incomingPacket,
MAX_PACKET_SIZE,
senderSockAddr.getAddressPointer(),
senderSockAddr.getPortPointer()))) {
while (NodeList::getInstance()->getNodeSocket().hasPendingDatagrams()) {
incomingPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
nodeList->getNodeSocket().readDatagram(incomingPacket.data(), incomingPacket.size(),
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
_packetCount++;
_byteCount += bytesReceived;
_byteCount += incomingPacket.size();
if (packetVersionMatch(incomingPacket, senderSockAddr)) {
if (packetVersionMatch(incomingPacket)) {
// only process this packet if we have a match on the packet version
switch (incomingPacket[0]) {
case PACKET_TYPE_TRANSMITTER_DATA_V2:
switch (packetTypeForPacket(incomingPacket)) {
case PacketTypeTransmitterData:
// V2 = IOS transmitter app
application->_myTransmitter.processIncomingData(incomingPacket, bytesReceived);
application->_myTransmitter.processIncomingData(reinterpret_cast<unsigned char*>(incomingPacket.data()),
incomingPacket.size());
break;
case PACKET_TYPE_MIXED_AUDIO:
case PacketTypeMixedAudio:
QMetaObject::invokeMethod(&application->_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection,
Q_ARG(QByteArray, QByteArray((char*) incomingPacket, bytesReceived)));
Q_ARG(QByteArray, incomingPacket));
break;
case PACKET_TYPE_PARTICLE_ADD_RESPONSE:
case PacketTypeParticleAddResponse:
// this will keep creatorTokenIDs to IDs mapped correctly
Particle::handleAddParticleResponse(incomingPacket, bytesReceived);
application->getParticles()->getTree()->handleAddParticleResponse(incomingPacket, bytesReceived);
Particle::handleAddParticleResponse(incomingPacket);
application->getParticles()->getTree()->handleAddParticleResponse(incomingPacket);
break;
case PACKET_TYPE_PARTICLE_DATA:
case PACKET_TYPE_PARTICLE_ERASE:
case PACKET_TYPE_VOXEL_DATA:
case PACKET_TYPE_VOXEL_ERASE:
case PACKET_TYPE_OCTREE_STATS:
case PACKET_TYPE_ENVIRONMENT_DATA: {
case PacketTypeParticleData:
case PacketTypeParticleErase:
case PacketTypeVoxelData:
case PacketTypeVoxelErase:
case PacketTypeOctreeStats:
case PacketTypeEnvironmentData: {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
bool wantExtraDebugging = application->getLogger()->extraDebugging();
if (wantExtraDebugging && incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) {
if (wantExtraDebugging && packetTypeForPacket(incomingPacket) == PacketTypeVoxelData) {
int numBytesPacketHeader = numBytesForPacketHeader(incomingPacket);
unsigned char* dataAt = incomingPacket + numBytesPacketHeader;
unsigned char* dataAt = reinterpret_cast<unsigned char*>(incomingPacket.data()) + numBytesPacketHeader;
dataAt += sizeof(VOXEL_PACKET_FLAGS);
VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);
dataAt += sizeof(VOXEL_PACKET_SEQUENCE);
@ -81,50 +81,47 @@ void DatagramProcessor::processDatagrams() {
VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
int flightTime = arrivedAt - sentAt;
printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
printf("got PacketType_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
}
// add this packet to our list of voxel packets and process them on the voxel processing
application->_voxelProcessor.queueReceivedPacket(senderSockAddr, incomingPacket, bytesReceived);
application->_voxelProcessor.queueReceivedPacket(senderSockAddr, incomingPacket);
break;
}
case PACKET_TYPE_METAVOXEL_DATA:
application->_metavoxels.processData(QByteArray((const char*) incomingPacket, bytesReceived),
senderSockAddr);
case PacketTypeMetavoxelData:
application->_metavoxels.processData(incomingPacket, senderSockAddr);
break;
case PACKET_TYPE_BULK_AVATAR_DATA:
case PACKET_TYPE_KILL_AVATAR: {
case PacketTypeBulkAvatarData:
case PacketTypeKillAvatar: {
// update having heard from the avatar-mixer and record the bytes received
SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
if (avatarMixer) {
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
avatarMixer->recordBytesReceived(bytesReceived);
avatarMixer->recordBytesReceived(incomingPacket.size());
QByteArray datagram(reinterpret_cast<char*>(incomingPacket), bytesReceived);
if (incomingPacket[0] == PACKET_TYPE_BULK_AVATAR_DATA) {
if (packetTypeForPacket(incomingPacket) == PacketTypeBulkAvatarData) {
QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram",
Q_ARG(const QByteArray&, datagram),
Q_ARG(const QByteArray&, incomingPacket),
Q_ARG(const QWeakPointer<Node>&, avatarMixer));
} else {
// this is an avatar kill, pass it to the application AvatarManager
QMetaObject::invokeMethod(&application->getAvatarManager(), "processKillAvatar",
Q_ARG(const QByteArray&, datagram));
Q_ARG(const QByteArray&, incomingPacket));
}
}
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(incomingPacket.size());
break;
}
case PACKET_TYPE_DATA_SERVER_GET:
case PACKET_TYPE_DATA_SERVER_PUT:
case PACKET_TYPE_DATA_SERVER_SEND:
case PACKET_TYPE_DATA_SERVER_CONFIRM:
DataServerClient::processMessageFromDataServer(incomingPacket, bytesReceived);
}
case PacketTypeDataServerGet:
case PacketTypeDataServerPut:
case PacketTypeDataServerSend:
case PacketTypeDataServerConfirm:
DataServerClient::processMessageFromDataServer(incomingPacket);
break;
default:
NodeList::getInstance()->processNodeData(senderSockAddr, incomingPacket, bytesReceived);
NodeList::getInstance()->processNodeData(senderSockAddr, incomingPacket);
break;
}
}

View file

@ -148,32 +148,28 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
return found;
}
int Environment::parseData(const HifiSockAddr& senderAddress, unsigned char* sourceBuffer, int numBytes) {
int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) {
// push past the packet header
unsigned char* start = sourceBuffer;
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
sourceBuffer += numBytesPacketHeader;
numBytes -= numBytesPacketHeader;
int bytesRead = numBytesForPacketHeader(packet);
// get the lock for the duration of the call
QMutexLocker locker(&_mutex);
EnvironmentData newData;
while (numBytes > 0) {
int dataLength = newData.parseData(sourceBuffer, numBytes);
while (bytesRead < packet.size()) {
int dataLength = newData.parseData(reinterpret_cast<const unsigned char*>(packet.data()) + bytesRead,
packet.size() - bytesRead);
// update the mapping by address/ID
_data[senderAddress][newData.getID()] = newData;
sourceBuffer += dataLength;
numBytes -= dataLength;
bytesRead += dataLength;
}
// remove the default mapping, if any
_data.remove(HifiSockAddr());
return sourceBuffer - start;
return bytesRead;
}
ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {

View file

@ -34,7 +34,7 @@ public:
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration);
int parseData(const HifiSockAddr& senderSockAddr, unsigned char* sourceBuffer, int numBytes);
int parseData(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
private:

View file

@ -107,14 +107,14 @@ void MetavoxelSystem::render() {
}
void MetavoxelSystem::nodeAdded(SharedNodePointer node) {
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
if (node->getType() == NodeType::MetavoxelServer) {
QMetaObject::invokeMethod(this, "addClient", Q_ARG(const QUuid&, node->getUUID()),
Q_ARG(const HifiSockAddr&, node->getLocalSocket()));
}
}
void MetavoxelSystem::nodeKilled(SharedNodePointer node) {
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
if (node->getType() == NodeType::MetavoxelServer) {
QMetaObject::invokeMethod(this, "removeClient", Q_ARG(const QUuid&, node->getUUID()));
}
}
@ -167,8 +167,7 @@ bool MetavoxelSystem::PointVisitor::visit(MetavoxelInfo& info) {
}
static QByteArray createDatagramHeader(const QUuid& sessionID) {
QByteArray header(MAX_PACKET_HEADER_BYTES, 0);
populateTypeAndVersion(reinterpret_cast<unsigned char*>(header.data()), PACKET_TYPE_METAVOXEL_DATA);
QByteArray header = byteArrayWithPopluatedHeader(PacketTypeMetavoxelData);
header += sessionID.toRfc4122();
return header;
}

View file

@ -29,9 +29,9 @@ public:
virtual ~ParticleTreeRenderer();
virtual Octree* createTree() { return new ParticleTree(true); }
virtual NODE_TYPE getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; }
virtual PACKET_TYPE getMyQueryMessageType() const { return PACKET_TYPE_PARTICLE_QUERY; }
virtual PACKET_TYPE getExpectedPacketType() const { return PACKET_TYPE_PARTICLE_DATA; }
virtual NodeType_t getMyNodeType() const { return NodeType::ParticleServer; }
virtual PacketType getMyQueryMessageType() const { return PacketTypeParticleQuery; }
virtual PacketType getExpectedPacketType() const { return PacketTypeParticleData; }
virtual void renderElement(OctreeElement* element, RenderArgs* args);
void update();

View file

@ -21,15 +21,15 @@ VoxelHideShowThread::VoxelHideShowThread(VoxelSystem* theSystem) :
}
bool VoxelHideShowThread::process() {
const uint64_t MSECS_TO_USECS = 1000;
const uint64_t SECS_TO_USECS = 1000 * MSECS_TO_USECS;
const uint64_t FRAME_RATE = 60;
const uint64_t USECS_PER_FRAME = SECS_TO_USECS / FRAME_RATE; // every 60fps
const quint64 MSECS_TO_USECS = 1000;
const quint64 SECS_TO_USECS = 1000 * MSECS_TO_USECS;
const quint64 FRAME_RATE = 60;
const quint64 USECS_PER_FRAME = SECS_TO_USECS / FRAME_RATE; // every 60fps
uint64_t start = usecTimestampNow();
quint64 start = usecTimestampNow();
_theSystem->checkForCulling();
uint64_t end = usecTimestampNow();
uint64_t elapsed = end - start;
quint64 end = usecTimestampNow();
quint64 elapsed = end - start;
bool showExtraDebugging = Application::getInstance()->getLogger()->extraDebugging();
if (showExtraDebugging && elapsed > USECS_PER_FRAME) {
@ -38,7 +38,7 @@ bool VoxelHideShowThread::process() {
if (isStillRunning()) {
if (elapsed < USECS_PER_FRAME) {
uint64_t sleepFor = USECS_PER_FRAME - elapsed;
quint64 sleepFor = USECS_PER_FRAME - elapsed;
usleep(sleepFor);
}
}

View file

@ -14,16 +14,18 @@
#include "Menu.h"
#include "VoxelPacketProcessor.h"
void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength) {
void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"VoxelPacketProcessor::processPacket()");
QByteArray mutablePacket = packet;
const int WAY_BEHIND = 300;
if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) {
qDebug("VoxelPacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
}
ssize_t messageLength = packetLength;
ssize_t messageLength = mutablePacket.size();
Application* app = Application::getInstance();
bool wasStatsPacket = false;
@ -34,18 +36,19 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
app->_voxels.killLocalVoxels();
app->_wantToKillLocalVoxels = false;
}
PacketType voxelPacketType = packetTypeForPacket(mutablePacket);
// note: PACKET_TYPE_OCTREE_STATS can have PACKET_TYPE_VOXEL_DATA
// immediately following them inside the same packet. So, we process the PACKET_TYPE_OCTREE_STATS first
// note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first
// then process any remaining bytes as if it was another packet
if (packetData[0] == PACKET_TYPE_OCTREE_STATS) {
if (voxelPacketType == PacketTypeOctreeStats) {
int statsMessageLength = app->parseOctreeStats(packetData, messageLength, senderSockAddr);
int statsMessageLength = app->parseOctreeStats(mutablePacket, senderSockAddr);
wasStatsPacket = true;
if (messageLength > statsMessageLength) {
packetData += statsMessageLength;
messageLength -= statsMessageLength;
if (!packetVersionMatch(packetData, senderSockAddr)) {
mutablePacket = mutablePacket.mid(statsMessageLength);
if (!packetVersionMatch(packet)) {
return; // bail since piggyback data doesn't match our versioning
}
} else {
@ -53,31 +56,31 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
return; // bail since no piggyback data
}
} // fall through to piggyback message
voxelPacketType = packetTypeForPacket(mutablePacket);
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
app->trackIncomingVoxelPacket(packetData, messageLength, senderSockAddr, wasStatsPacket);
app->trackIncomingVoxelPacket(mutablePacket, senderSockAddr, wasStatsPacket);
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
if (serverNode && serverNode->getActiveSocket() && *serverNode->getActiveSocket() == senderSockAddr) {
switch(packetData[0]) {
case PACKET_TYPE_PARTICLE_ERASE: {
app->_particles.processEraseMessage(QByteArray((char*) packetData, messageLength),
senderSockAddr, serverNode.data());
switch(voxelPacketType) {
case PacketTypeParticleErase: {
app->_particles.processEraseMessage(mutablePacket, senderSockAddr, serverNode.data());
} break;
case PACKET_TYPE_PARTICLE_DATA: {
app->_particles.processDatagram(QByteArray((char*) packetData, messageLength),
senderSockAddr, serverNode.data());
case PacketTypeParticleData: {
app->_particles.processDatagram(mutablePacket, senderSockAddr, serverNode.data());
} break;
case PACKET_TYPE_ENVIRONMENT_DATA: {
app->_environment.parseData(senderSockAddr, packetData, messageLength);
case PacketTypeEnvironmentData: {
app->_environment.parseData(senderSockAddr, mutablePacket);
} break;
default : {
app->_voxels.setDataSourceUUID(serverNode->getUUID());
app->_voxels.parseData(packetData, messageLength);
app->_voxels.parseData(mutablePacket);
app->_voxels.setDataSourceUUID(QUuid());
} break;
}

View file

@ -17,6 +17,6 @@
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
class VoxelPacketProcessor : public ReceivedPacketProcessor {
protected:
virtual void processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength);
virtual void processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
};
#endif // __shared__VoxelPacketProcessor__

View file

@ -16,7 +16,6 @@
#include <PerfStat.h>
#include <SharedUtil.h>
#include <NodeList.h>
#include <NodeTypes.h>
#include "Application.h"
#include "CoverageMap.h"
@ -550,17 +549,17 @@ bool VoxelSystem::readFromSchematicFile(const char* filename) {
return result;
}
int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
int VoxelSystem::parseData(const QByteArray& packet) {
bool showTimingDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData()",showTimingDetails);
unsigned char command = *sourceBuffer;
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
PacketType command = packetTypeForPacket(packet);
int numBytesPacketHeader = numBytesForPacketHeader(packet);
switch(command) {
case PACKET_TYPE_VOXEL_DATA: {
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() PACKET_TYPE_VOXEL_DATA part...",showTimingDetails);
unsigned char* dataAt = sourceBuffer + numBytesPacketHeader;
case PacketTypeVoxelData: {
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() PacketType_VOXEL_DATA part...",showTimingDetails);
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));
dataAt += sizeof(VOXEL_PACKET_FLAGS);
@ -577,7 +576,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
int flightTime = arrivedAt - sentAt;
VOXEL_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0;
int dataBytes = numBytes - VOXEL_PACKET_HEADER_SIZE;
int dataBytes = packet.size() - VOXEL_PACKET_HEADER_SIZE;
int subsection = 1;
while (dataBytes > 0) {
@ -605,7 +604,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
" subsection:%d sectionLength:%d uncompressed:%d",
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
sequence, flightTime, numBytes, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());
sequence, flightTime, packet.size(), dataBytes, subsection, sectionLength,
packetData.getUncompressedSize());
}
_tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
unlockTree();
@ -616,7 +616,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
}
subsection++;
}
break;
default:
break;
}
if (!_useFastVoxelPipeline || _writeRenderFullVBO) {
setupNewVoxelsForDrawing();
@ -624,9 +625,9 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
}
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(numBytes);
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(packet.size());
return numBytes;
return packet.size();
}
void VoxelSystem::setupNewVoxelsForDrawing() {
@ -637,8 +638,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
return; // bail early if we're not initialized
}
uint64_t start = usecTimestampNow();
uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
quint64 start = usecTimestampNow();
quint64 sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
@ -684,7 +685,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
_bufferWriteLock.unlock();
uint64_t end = usecTimestampNow();
quint64 end = usecTimestampNow();
int elapsedmsec = (end - start) / 1000;
_setupNewVoxelsForDrawingLastFinished = end;
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
@ -701,8 +702,8 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"setupNewVoxelsForDrawingSingleNode() xxxxx");
uint64_t start = usecTimestampNow();
uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
quint64 start = usecTimestampNow();
quint64 sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
if (allowBailEarly && !iAmDebugging &&
@ -727,7 +728,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
_bufferWriteLock.unlock();
uint64_t end = usecTimestampNow();
quint64 end = usecTimestampNow();
int elapsedmsec = (end - start) / 1000;
_setupNewVoxelsForDrawingLastFinished = end;
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
@ -736,14 +737,14 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
void VoxelSystem::checkForCulling() {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()");
uint64_t start = usecTimestampNow();
quint64 start = usecTimestampNow();
// track how long its been since we were last moving. If we have recently moved then only use delta frustums, if
// it's been a long time since we last moved, then go ahead and do a full frustum cull.
if (isViewChanging()) {
_lastViewIsChanging = start;
}
uint64_t sinceLastMoving = (start - _lastViewIsChanging) / 1000;
quint64 sinceLastMoving = (start - _lastViewIsChanging) / 1000;
bool enoughTime = (sinceLastMoving >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS));
// These has changed events will occur before we stop. So we need to remember this for when we finally have stopped
@ -765,7 +766,7 @@ void VoxelSystem::checkForCulling() {
hideOutOfView(forceFullFrustum);
if (forceFullFrustum) {
uint64_t endViewCulling = usecTimestampNow();
quint64 endViewCulling = usecTimestampNow();
_lastViewCullingElapsed = (endViewCulling - start) / 1000;
}
@ -774,7 +775,7 @@ void VoxelSystem::checkForCulling() {
// VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
cleanupRemovedVoxels();
uint64_t sinceLastAudit = (start - _lastAudit) / 1000;
quint64 sinceLastAudit = (start - _lastAudit) / 1000;
if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
if (sinceLastAudit >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) {
@ -1590,7 +1591,7 @@ void VoxelSystem::falseColorizeBySource() {
// create a bunch of colors we'll use during colorization
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
if (node->getType() == NodeType::VoxelServer) {
uint16_t nodeID = VoxelTreeElement::getSourceNodeUUIDKey(node->getUUID());
int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS;
args.colors[nodeID] = groupColors[groupColor];
@ -2662,7 +2663,7 @@ void VoxelSystem::falseColorizeOccludedV2() {
}
void VoxelSystem::nodeAdded(SharedNodePointer node) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
if (node->getType() == NodeType::VoxelServer) {
qDebug("VoxelSystem... voxel server %s added...", node->getUUID().toString().toLocal8Bit().constData());
_voxelServerCount++;
}
@ -2683,7 +2684,7 @@ bool VoxelSystem::killSourceVoxelsOperation(OctreeElement* element, void* extraD
}
void VoxelSystem::nodeKilled(SharedNodePointer node) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
if (node->getType() == NodeType::VoxelServer) {
_voxelServerCount--;
QUuid nodeUUID = node->getUUID();
qDebug("VoxelSystem... voxel server %s removed...", nodeUUID.toString().toLocal8Bit().constData());

View file

@ -49,7 +49,7 @@ public:
void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; }
const QUuid& getDataSourceUUID() const { return _dataSourceUUID; }
int parseData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
virtual void init();
void simulate(float deltaTime) { }
@ -229,10 +229,10 @@ private:
bool _readRenderFullVBO;
int _setupNewVoxelsForDrawingLastElapsed;
uint64_t _setupNewVoxelsForDrawingLastFinished;
uint64_t _lastViewCulling;
uint64_t _lastViewIsChanging;
uint64_t _lastAudit;
quint64 _setupNewVoxelsForDrawingLastFinished;
quint64 _lastViewCulling;
quint64 _lastViewIsChanging;
quint64 _lastAudit;
int _lastViewCullingElapsed;
bool _hasRecentlyChanged;

View file

@ -12,7 +12,6 @@
#include <glm/gtx/vector_angle.hpp>
#include <NodeList.h>
#include <NodeTypes.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
@ -336,11 +335,11 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
return false;
}
int Avatar::parseData(unsigned char* sourceBuffer, int numBytes) {
int Avatar::parseData(const QByteArray& packet) {
// change in position implies movement
glm::vec3 oldPosition = _position;
int bytesRead = AvatarData::parseData(sourceBuffer, numBytes);
int bytesRead = AvatarData::parseData(packet);
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;

View file

@ -114,7 +114,7 @@ public:
virtual bool isMyAvatar() { return false; }
int parseData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);

View file

@ -199,15 +199,11 @@ void AvatarManager::processDataServerResponse(const QString& userString, const Q
}
void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
unsigned char packetData[MAX_PACKET_SIZE];
memcpy(packetData, datagram.data(), datagram.size());
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
int bytesRead = numBytesForPacketHeader(datagram);
int bytesRead = numBytesPacketHeader;
unsigned char avatarData[MAX_PACKET_SIZE];
int numBytesDummyPacketHeader = populateTypeAndVersion(avatarData, PACKET_TYPE_HEAD_DATA);
QByteArray dummyAvatarByteArray = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
int numDummyByteArrayHeaderBytes = dummyAvatarByteArray.size();
// enumerate over all of the avatars in this packet
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
@ -234,18 +230,17 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const
}
// copy the rest of the packet to the avatarData holder so we can read the next Avatar from there
memcpy(avatarData + numBytesDummyPacketHeader, packetData + bytesRead, datagram.size() - bytesRead);
dummyAvatarByteArray.resize(numDummyByteArrayHeaderBytes);
dummyAvatarByteArray += datagram.mid(bytesRead);
// have the matching (or new) avatar parse the data from the packet
bytesRead += matchingAvatar->parseData(avatarData, datagram.size() - bytesRead);
bytesRead += matchingAvatar->parseData(dummyAvatarByteArray);
}
}
void AvatarManager::processKillAvatar(const QByteArray& datagram) {
// read the node id
QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(reinterpret_cast<const unsigned char*>
(datagram.data())),
NUM_BYTES_RFC4122_UUID));
QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID));
// remove the avatar with that UUID from our hash, if it exists
AvatarHash::iterator matchedAvatar = _avatarHash.find(nodeUUID);

View file

@ -12,7 +12,6 @@
#include <glm/gtx/vector_angle.hpp>
#include <NodeList.h>
#include <NodeTypes.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
@ -471,18 +470,8 @@ void MyAvatar::loadData(QSettings* settings) {
}
void MyAvatar::sendKillAvatar() {
unsigned char packet[MAX_PACKET_SIZE];
unsigned char* packetPosition = packet;
packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_AVATAR);
NodeList* nodeList = NodeList::getInstance();
QByteArray rfcUUID = nodeList->getOwnerUUID().toRfc4122();
memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size());
packetPosition += rfcUUID.size();
nodeList->broadcastToNodes(packet, packetPosition - packet, QSet<NODE_TYPE>() << NODE_TYPE_AVATAR_MIXER);
QByteArray killPacket = byteArrayWithPopluatedHeader(PacketTypeKillAvatar);
NodeList::getInstance()->broadcastToNodes(killPacket, NodeSet() << NodeType::AvatarMixer);
}
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {

View file

@ -87,7 +87,7 @@ void Profile::updatePosition(const glm::vec3 position) {
if (_lastPosition != position) {
static timeval lastPositionSend = {};
const uint64_t DATA_SERVER_POSITION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
const quint64 DATA_SERVER_POSITION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
const float DATA_SERVER_POSITION_CHANGE_THRESHOLD_METERS = 1;
if (usecTimestampNow() - usecTimestamp(&lastPositionSend) >= DATA_SERVER_POSITION_UPDATE_INTERVAL_USECS &&
@ -115,10 +115,10 @@ void Profile::updateOrientation(const glm::quat& orientation) {
if (_lastOrientation == eulerAngles) {
return;
}
const uint64_t DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
const quint64 DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
const float DATA_SERVER_ORIENTATION_CHANGE_THRESHOLD_DEGREES = 5.0f;
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
if (now - _lastOrientationSend >= DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS &&
glm::distance(_lastOrientation, eulerAngles) >= DATA_SERVER_ORIENTATION_CHANGE_THRESHOLD_DEGREES) {
DataServerClient::putValueForKeyAndUserString(DataServerKey::Orientation, QString(createByteArray(eulerAngles)),

View file

@ -57,7 +57,7 @@ private:
QString _lastDomain;
glm::vec3 _lastPosition;
glm::vec3 _lastOrientation;
uint64_t _lastOrientationSend;
quint64 _lastOrientationSend;
QUrl _faceModelURL;
QUrl _skeletonModelURL;
};

View file

@ -56,7 +56,7 @@ Faceshift::Faceshift() :
}
bool Faceshift::isActive() const {
const uint64_t ACTIVE_TIMEOUT_USECS = 1000000;
const quint64 ACTIVE_TIMEOUT_USECS = 1000000;
return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS;
}

View file

@ -90,7 +90,7 @@ private:
bool _tcpEnabled;
int _tcpRetryCount;
bool _tracking;
uint64_t _lastTrackingStateReceived;
quint64 _lastTrackingStateReceived;
glm::quat _headRotation;
glm::vec3 _headAngularVelocity;

View file

@ -25,7 +25,7 @@ public slots:
private:
uint64_t _lastMovement;
quint64 _lastMovement;
};
#endif /* defined(__interface__SixenseManager__) */

View file

@ -60,7 +60,7 @@ void Transmitter::resetLevels() {
void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) {
// Packet's first byte is 'T'
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(packetData));
const int ROTATION_MARKER_SIZE = 1; // 'R' = Rotation (clockwise about x,y,z)
const int ACCELERATION_MARKER_SIZE = 1; // 'A' = Acceleration (x,y,z)

View file

@ -59,7 +59,7 @@ namespace starfield {
using namespace std;
typedef uint32_t nuint;
typedef uint64_t wuint;
typedef quint64 wuint;
}

View file

@ -224,9 +224,9 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
void VoxelStatsDialog::showAllOctreeServers() {
int serverCount = 0;
showOctreeServersOfType(serverCount, NODE_TYPE_VOXEL_SERVER, "Voxel",
showOctreeServersOfType(serverCount, NodeType::VoxelServer, "Voxel",
Application::getInstance()->getVoxelServerJurisdictions());
showOctreeServersOfType(serverCount, NODE_TYPE_PARTICLE_SERVER, "Particle",
showOctreeServersOfType(serverCount, NodeType::ParticleServer, "Particle",
Application::getInstance()->getParticleServerJurisdictions());
if (_voxelServerLabelsCount > serverCount) {
@ -239,7 +239,7 @@ void VoxelStatsDialog::showAllOctreeServers() {
}
}
void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serverType, const char* serverTypeName,
void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t serverType, const char* serverTypeName,
NodeToJurisdictionMap& serverJurisdictions) {
QLocale locale(QLocale::English);
@ -247,7 +247,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
// only send to the NodeTypes that are NodeType_t_VOXEL_SERVER
if (node->getType() == serverType) {
serverCount++;

View file

@ -44,7 +44,7 @@ protected:
void RemoveStatItem(int item);
void showAllOctreeServers();
void showOctreeServersOfType(int& serverNumber, NODE_TYPE serverType,
void showOctreeServersOfType(int& serverNumber, NodeType_t serverType,
const char* serverTypeName, NodeToJurisdictionMap& serverJurisdictions);
private:

View file

@ -45,45 +45,28 @@ void AudioInjector::injectAudio() {
NodeList* nodeList = NodeList::getInstance();
// setup the packet for injected audio
unsigned char injectedAudioPacket[MAX_PACKET_SIZE];
unsigned char* currentPacketPosition = injectedAudioPacket;
QByteArray injectAudioPacket = byteArrayWithPopluatedHeader(PacketTypeInjectAudio);
QDataStream packetStream(&injectAudioPacket, QIODevice::Append);
int numBytesPacketHeader = populateTypeAndVersion(injectedAudioPacket, PACKET_TYPE_INJECT_AUDIO);
currentPacketPosition += numBytesPacketHeader;
// pack the session UUID for this Node
QByteArray rfcSessionUUID = NodeList::getInstance()->getOwnerUUID().toRfc4122();
memcpy(currentPacketPosition, rfcSessionUUID.constData(), rfcSessionUUID.size());
currentPacketPosition += rfcSessionUUID.size();
// pick a random UUID to use for this stream
QUuid randomStreamUUID = QUuid::createUuid();
QByteArray rfcStreamUUID = randomStreamUUID.toRfc4122();
memcpy(currentPacketPosition, rfcStreamUUID, rfcStreamUUID.size());
currentPacketPosition += rfcStreamUUID.size();
packetStream << QUuid::createUuid();
// pack the flag for loopback
bool loopbackFlag = (_options.getLoopbackAudioInterface() == NULL);
memcpy(currentPacketPosition, &loopbackFlag, sizeof(loopbackFlag));
currentPacketPosition += sizeof(loopbackFlag);
uchar loopbackFlag = (uchar) (_options.getLoopbackAudioInterface() == NULL);
packetStream << loopbackFlag;
// pack the position for injected audio
memcpy(currentPacketPosition, &_options.getPosition(), sizeof(_options.getPosition()));
currentPacketPosition += sizeof(_options.getPosition());
packetStream.writeRawData(reinterpret_cast<const char*>(&_options.getPosition()), sizeof(_options.getPosition()));
// pack our orientation for injected audio
memcpy(currentPacketPosition, &_options.getOrientation(), sizeof(_options.getOrientation()));
currentPacketPosition += sizeof(_options.getOrientation());
packetStream.writeRawData(reinterpret_cast<const char*>(&_options.getOrientation()), sizeof(_options.getOrientation()));
// pack zero for radius
float radius = 0;
memcpy(currentPacketPosition, &radius, sizeof(radius));
currentPacketPosition += sizeof(radius);
packetStream << radius;
// pack 255 for attenuation byte
uchar volume = MAX_INJECTOR_VOLUME * _options.getVolume();
memcpy(currentPacketPosition, &volume, sizeof(volume));
currentPacketPosition += sizeof(volume);
quint8 volume = MAX_INJECTOR_VOLUME * _options.getVolume();
packetStream << volume;
timeval startTime = {};
gettimeofday(&startTime, NULL);
@ -91,24 +74,26 @@ void AudioInjector::injectAudio() {
int currentSendPosition = 0;
int numPreAudioDataBytes = injectAudioPacket.size();
// loop to send off our audio in NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL byte chunks
while (currentSendPosition < soundByteArray.size()) {
int bytesToCopy = std::min(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL,
soundByteArray.size() - currentSendPosition);
// copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
memcpy(currentPacketPosition, soundByteArray.data() + currentSendPosition,
bytesToCopy);
// resize the QByteArray to the right size
injectAudioPacket.resize(numPreAudioDataBytes + bytesToCopy);
// copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
memcpy(injectAudioPacket.data() + numPreAudioDataBytes, soundByteArray.data() + currentSendPosition, bytesToCopy);
// grab our audio mixer from the NodeList, if it exists
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
// send off this audio packet
nodeList->getNodeSocket().writeDatagram((char*) injectedAudioPacket,
(currentPacketPosition - injectedAudioPacket) + bytesToCopy,
nodeList->getNodeSocket().writeDatagram(injectAudioPacket,
audioMixer->getActiveSocket()->getAddress(),
audioMixer->getActiveSocket()->getPort());
}

View file

@ -50,9 +50,9 @@ void AudioRingBuffer::resizeForFrameSize(qint64 numFrameSamples) {
_endOfLastWrite = _buffer;
}
int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
return writeData((char*) sourceBuffer + numBytesPacketHeader, numBytes - numBytesPacketHeader);
int AudioRingBuffer::parseData(const QByteArray& packet) {
int numBytesPacketHeader = numBytesForPacketHeader(packet);
return writeData(packet.data() + numBytesPacketHeader, packet.size() - numBytesPacketHeader);
}
qint64 AudioRingBuffer::readSamples(int16_t* destination, qint64 maxSamples) {

View file

@ -44,7 +44,7 @@ public:
int getSampleCapacity() const { return _sampleCapacity; }
int parseData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
qint64 readSamples(int16_t* destination, qint64 maxSamples);
qint64 writeSamples(const int16_t* source, qint64 maxSamples);

View file

@ -26,29 +26,31 @@ InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier)
const uchar MAX_INJECTOR_VOLUME = 255;
int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer);
int InjectedAudioRingBuffer::parseData(const QByteArray& packet) {
// setup a data stream to read from this packet
QDataStream packetStream(packet);
packetStream.skipRawData(numBytesForPacketHeader(packet));
// push past the UUID for this node and the stream identifier
currentBuffer += (NUM_BYTES_RFC4122_UUID * 2);
// push past the stream identifier
packetStream.skipRawData(NUM_BYTES_RFC4122_UUID);
// pull the loopback flag and set our boolean
uchar shouldLoopback;
memcpy(&shouldLoopback, currentBuffer, sizeof(shouldLoopback));
currentBuffer += sizeof(shouldLoopback);
packetStream >> shouldLoopback;
_shouldLoopbackForNode = (shouldLoopback == 1);
// use parsePositionalData in parent PostionalAudioRingBuffer class to pull common positional data
currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos())));
// pull out the radius for this injected source - if it's zero this is a point source
memcpy(&_radius, currentBuffer, sizeof(_radius));
currentBuffer += sizeof(_radius);
packetStream >> _radius;
unsigned int attenuationByte = *(currentBuffer++);
quint8 attenuationByte = 0;
packetStream >> attenuationByte;
_attenuationRatio = attenuationByte / (float) MAX_INJECTOR_VOLUME;
currentBuffer += writeData((char*) currentBuffer, numBytes - (currentBuffer - sourceBuffer));
packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(),
packet.size() - packetStream.device()->pos()));
return currentBuffer - sourceBuffer;
return packetStream.device()->pos();
}

View file

@ -17,7 +17,7 @@ class InjectedAudioRingBuffer : public PositionalAudioRingBuffer {
public:
InjectedAudioRingBuffer(const QUuid& streamIdentifier = QUuid());
int parseData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
const QUuid& getStreamIdentifier() const { return _streamIdentifier; }
float getRadius() const { return _radius; }

View file

@ -35,23 +35,24 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
PositionalAudioRingBuffer::~PositionalAudioRingBuffer() {
}
int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer);
currentBuffer += NUM_BYTES_RFC4122_UUID; // the source UUID
currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
currentBuffer += writeData((char*) currentBuffer, numBytes - (currentBuffer - sourceBuffer));
int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
QDataStream packetStream(packet);
// skip the packet header (includes the source UUID)
packetStream.skipRawData(numBytesForPacketHeader(packet));
packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos())));
packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(),
packet.size() - packetStream.device()->pos()));
return currentBuffer - sourceBuffer;
return packetStream.device()->pos();
}
int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer, int numBytes) {
unsigned char* currentBuffer = sourceBuffer;
memcpy(&_position, currentBuffer, sizeof(_position));
currentBuffer += sizeof(_position);
memcpy(&_orientation, currentBuffer, sizeof(_orientation));
currentBuffer += sizeof(_orientation);
int PositionalAudioRingBuffer::parsePositionalData(const QByteArray& positionalByteArray) {
QDataStream packetStream(positionalByteArray);
packetStream.readRawData(reinterpret_cast<char*>(&_position), sizeof(_position));
packetStream.readRawData(reinterpret_cast<char*>(&_orientation), sizeof(_orientation));
// if this node sent us a NaN for first float in orientation then don't consider this good audio and bail
if (isnan(_orientation.x)) {
@ -59,7 +60,7 @@ int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer,
return 0;
}
return currentBuffer - sourceBuffer;
return packetStream.device()->pos();
}
bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) {

View file

@ -24,9 +24,9 @@ public:
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type);
~PositionalAudioRingBuffer();
int parseData(unsigned char* sourceBuffer, int numBytes);
int parsePositionalData(unsigned char* sourceBuffer, int numBytes);
int parseListenModeData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
int parsePositionalData(const QByteArray& positionalByteArray);
int parseListenModeData(const QByteArray& listenModeByteArray);
bool shouldBeAddedToMix(int numJitterBufferSamples);

View file

@ -52,9 +52,7 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position);
}
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
unsigned char* bufferStart = destinationBuffer;
QByteArray AvatarData::toByteArray() {
// TODO: DRY this up to a shared method
// that can pack any type given the number of bytes
// and return the number of bytes to push the pointer
@ -68,9 +66,14 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
_handData = new HandData(this);
}
// Body world position
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
destinationBuffer += sizeof(float) * 3;
QByteArray avatarDataByteArray;
avatarDataByteArray.resize(MAX_PACKET_SIZE);
unsigned char* destinationBuffer = reinterpret_cast<unsigned char*>(avatarDataByteArray.data());
unsigned char* startPosition = destinationBuffer;
memcpy(destinationBuffer, &_position, sizeof(_position));
destinationBuffer += sizeof(_position);
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
@ -85,6 +88,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_roll);
// Head lean X,Z (head lateral and fwd/back motion relative to torso)
memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways));
destinationBuffer += sizeof(_headData->_leanSideways);
@ -150,11 +154,11 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
// leap hand data
destinationBuffer += _handData->encodeRemoteData(destinationBuffer);
return destinationBuffer - bufferStart;
return avatarDataByteArray.left(destinationBuffer - startPosition);
}
// called on the other nodes - assigns it to my views of the others
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
int AvatarData::parseData(const QByteArray& packet) {
// lazily allocate memory for HeadData in case we're not an Avatar instance
if (!_headData) {
@ -166,67 +170,68 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
_handData = new HandData(this);
}
// increment to push past the packet header
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
sourceBuffer += numBytesPacketHeader;
QDataStream packetStream(packet);
packetStream.skipRawData(numBytesForPacketHeader(packet));
unsigned char* startPosition = sourceBuffer;
// push past the node session UUID
sourceBuffer += NUM_BYTES_RFC4122_UUID;
// Body world position
memcpy(&_position, sourceBuffer, sizeof(float) * 3);
sourceBuffer += sizeof(float) * 3;
packetStream.readRawData(reinterpret_cast<char*>(&_position), sizeof(_position));
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll);
// Body scale
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale);
uint16_t twoByteHolder;
packetStream >> twoByteHolder;
unpackFloatAngleFromTwoByte(&twoByteHolder, &_bodyYaw);
packetStream >> twoByteHolder;
unpackFloatAngleFromTwoByte(&twoByteHolder, &_bodyPitch);
packetStream >> twoByteHolder;
unpackFloatAngleFromTwoByte(&twoByteHolder, &_bodyRoll);
// body scale
packetStream >> twoByteHolder;
unpackFloatRatioFromTwoByte(reinterpret_cast<const unsigned char*>(&twoByteHolder), _targetScale);
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
float headYaw, headPitch, headRoll;
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll);
packetStream >> twoByteHolder;
unpackFloatAngleFromTwoByte(&twoByteHolder, &headYaw);
packetStream >> twoByteHolder;
unpackFloatAngleFromTwoByte(&twoByteHolder, &headPitch);
packetStream >> twoByteHolder;
unpackFloatAngleFromTwoByte(&twoByteHolder, &headRoll);
_headData->setYaw(headYaw);
_headData->setPitch(headPitch);
_headData->setRoll(headRoll);
// Head position relative to pelvis
memcpy(&_headData->_leanSideways, sourceBuffer, sizeof(_headData->_leanSideways));
sourceBuffer += sizeof(float);
memcpy(&_headData->_leanForward, sourceBuffer, sizeof(_headData->_leanForward));
sourceBuffer += sizeof(_headData->_leanForward);
packetStream >> _headData->_leanSideways;
packetStream >> _headData->_leanForward;
// Hand Position - is relative to body position
glm::vec3 handPositionRelative;
memcpy(&handPositionRelative, sourceBuffer, sizeof(float) * 3);
packetStream.readRawData(reinterpret_cast<char*>(&handPositionRelative), sizeof(handPositionRelative));
_handPosition = _position + handPositionRelative;
sourceBuffer += sizeof(float) * 3;
// Lookat Position
memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition));
sourceBuffer += sizeof(_headData->_lookAtPosition);
packetStream.readRawData(reinterpret_cast<char*>(&_headData->_lookAtPosition), sizeof(_headData->_lookAtPosition));
// Instantaneous audio loudness (used to drive facial animation)
//sourceBuffer += unpackFloatFromByte(sourceBuffer, _audioLoudness, MAX_AUDIO_LOUDNESS);
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);
packetStream >> _headData->_audioLoudness;
// the rest is a chat message
int chatMessageSize = *sourceBuffer++;
_chatMessage = string((char*)sourceBuffer, chatMessageSize);
sourceBuffer += chatMessageSize * sizeof(char);
quint8 chatMessageSize;
packetStream >> chatMessageSize;
_chatMessage = string(packet.data() + packetStream.device()->pos(), chatMessageSize);
packetStream.skipRawData(chatMessageSize);
// voxel sending features...
unsigned char bitItems = 0;
bitItems = (unsigned char)*sourceBuffer++;
packetStream >> bitItems;
// key state, stored as a semi-nibble in the bitItems
_keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT);
@ -239,34 +244,31 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
// If it is connected, pack up the data
if (_headData->_isFaceshiftConnected) {
memcpy(&_headData->_leftEyeBlink, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);
memcpy(&_headData->_rightEyeBlink, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);
memcpy(&_headData->_averageLoudness, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);
memcpy(&_headData->_browAudioLift, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);
packetStream >> _headData->_leftEyeBlink;
packetStream >> _headData->_rightEyeBlink;
packetStream >> _headData->_averageLoudness;
packetStream >> _headData->_browAudioLift;
_headData->_blendshapeCoefficients.resize(*sourceBuffer++);
memcpy(_headData->_blendshapeCoefficients.data(), sourceBuffer,
_headData->_blendshapeCoefficients.size() * sizeof(float));
sourceBuffer += _headData->_blendshapeCoefficients.size() * sizeof(float);
quint8 numBlendshapeCoefficients;
packetStream >> numBlendshapeCoefficients;
_headData->_blendshapeCoefficients.resize(numBlendshapeCoefficients);
packetStream.readRawData(reinterpret_cast<char*>(_headData->_blendshapeCoefficients.data()),
numBlendshapeCoefficients * sizeof(float));
}
// pupil dilation
sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f);
quint8 pupilByte;
packetStream >> pupilByte;
unpackFloatFromByte(&pupilByte, _headData->_pupilDilation, 1.0f);
// leap hand data
if (sourceBuffer - startPosition < numBytes) {
if (packetStream.device()->pos() < packet.size()) {
// check passed, bytes match
sourceBuffer += _handData->decodeRemoteData(sourceBuffer);
packetStream.skipRawData(_handData->decodeRemoteData(packet.mid(packetStream.device()->pos())));
}
return sourceBuffer - startPosition;
return packetStream.device()->pos();
}
void AvatarData::setClampedTargetScale(float targetScale) {

View file

@ -19,7 +19,7 @@ typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
typedef unsigned long long quint64;
#define PRId64 "I64d"
#else
#include <inttypes.h>
@ -83,8 +83,8 @@ public:
glm::vec3 getHandPosition() const;
void setHandPosition(const glm::vec3& handPosition);
int getBroadcastData(unsigned char* destinationBuffer);
int parseData(unsigned char* sourceBuffer, int numBytes);
QByteArray toByteArray();
int parseData(const QByteArray& packet);
// Body Rotation
float getBodyYaw() const { return _bodyYaw; }

View file

@ -157,10 +157,11 @@ int HandData::encodeRemoteData(unsigned char* destinationBuffer) {
return destinationBuffer - startPosition;
}
int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
const unsigned char* startPosition = sourceBuffer;
unsigned int numHands = *sourceBuffer++;
int HandData::decodeRemoteData(const QByteArray& dataByteArray) {
QDataStream packetStream(dataByteArray);
quint8 numHands;
packetStream >> numHands;
for (unsigned int handIndex = 0; handIndex < numHands; ++handIndex) {
if (handIndex >= getNumPalms())
@ -169,9 +170,18 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
glm::vec3 handPosition;
glm::vec3 handNormal;
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, handPosition, fingerVectorRadix);
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, handNormal, fingerVectorRadix);
unsigned int numFingers = *sourceBuffer++;
qint16 twoByteHolder;
packetStream >> twoByteHolder;
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder),
handPosition, fingerVectorRadix);
packetStream >> twoByteHolder;
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder),
handNormal, fingerVectorRadix);
quint8 numFingers;
packetStream >> numFingers;
palm.setRawPosition(handPosition);
palm.setRawNormal(handNormal);
@ -186,8 +196,14 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
glm::vec3 tipPosition;
glm::vec3 rootPosition;
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, tipPosition, fingerVectorRadix);
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, rootPosition, fingerVectorRadix);
packetStream >> twoByteHolder;
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder), tipPosition,
fingerVectorRadix);
packetStream >> twoByteHolder;
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder), rootPosition,
fingerVectorRadix);
finger.setRawTipPosition(tipPosition);
finger.setRawRootPosition(rootPosition);
@ -207,11 +223,14 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
}
// One byte for error checking safety.
unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition);
unsigned char checkLength = *sourceBuffer++;
unsigned char requiredLength = packetStream.device()->pos();
unsigned char checkLength;
packetStream >> checkLength;
assert(checkLength == requiredLength);
return sourceBuffer - startPosition;
return packetStream.device()->pos();
}
void HandData::setFingerTrailLength(unsigned int length) {

View file

@ -73,7 +73,7 @@ public:
// Use these for sending and receiving hand data
int encodeRemoteData(unsigned char* destinationBuffer);
int decodeRemoteData(unsigned char* sourceBuffer);
int decodeRemoteData(const QByteArray& dataByteArray);
/// Checks for penetration between the described sphere and the hand.
/// \param penetratorCenter the center of the penetration test sphere
@ -228,7 +228,7 @@ private:
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
bool _isCollidingWithPalm;
uint64_t _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
quint64 _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
};
#endif /* defined(__hifi__HandData__) */

View file

@ -16,7 +16,7 @@
QUuid readSessionID(const QByteArray& data, const HifiSockAddr& sender, int& headerPlusIDSize) {
// get the header size
int headerSize = numBytesForPacketHeader(reinterpret_cast<const unsigned char*>(data.constData()));
int headerSize = numBytesForPacketHeader(data);
// read the session id
const int UUID_BYTES = 16;

View file

@ -39,63 +39,64 @@ void OctreeInboundPacketProcessor::resetStats() {
}
void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr,
unsigned char* packetData, ssize_t packetLength) {
void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
bool debugProcessPacket = _myServer->wantsVerboseDebug();
if (debugProcessPacket) {
printf("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%ld\n", packetData, packetLength);
printf("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%d\n", &packet, packet.size());
}
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
int numBytesPacketHeader = numBytesForPacketHeader(packet);
// Ask our tree subclass if it can handle the incoming packet...
PACKET_TYPE packetType = packetData[0];
PacketType packetType = packetTypeForPacket(packet);
if (_myServer->getOctree()->handlesEditPacketType(packetType)) {
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
_receivedPacketCount++;
SharedNodePointer senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
const unsigned char* packetData = reinterpret_cast<const unsigned char*>(packet.data());
unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
uint64_t sentAt = (*((uint64_t*)(packetData + numBytesPacketHeader + sizeof(sequence))));
uint64_t arrivedAt = usecTimestampNow();
uint64_t transitTime = arrivedAt - sentAt;
quint64 sentAt = (*((quint64*)(packetData + numBytesPacketHeader + sizeof(sequence))));
quint64 arrivedAt = usecTimestampNow();
quint64 transitTime = arrivedAt - sentAt;
int editsInPacket = 0;
uint64_t processTime = 0;
uint64_t lockWaitTime = 0;
quint64 processTime = 0;
quint64 lockWaitTime = 0;
if (_myServer->wantsDebugReceiving()) {
qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount
<< " command from client receivedBytes=" << packetLength
<< " command from client receivedBytes=" << packet.size()
<< " sequence=" << sequence << " transitTime=" << transitTime << " usecs";
}
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
unsigned char* editData = (unsigned char*)&packetData[atByte];
while (atByte < packetLength) {
int maxSize = packetLength - atByte;
while (atByte < packet.size()) {
int maxSize = packet.size() - atByte;
if (debugProcessPacket) {
printf("OctreeInboundPacketProcessor::processPacket() %c "
"packetData=%p packetLength=%ld voxelData=%p atByte=%d maxSize=%d\n",
packetType, packetData, packetLength, editData, atByte, maxSize);
"packetData=%p packetLength=%d voxelData=%p atByte=%d maxSize=%d\n",
packetType, packetData, packet.size(), editData, atByte, maxSize);
}
uint64_t startLock = usecTimestampNow();
quint64 startLock = usecTimestampNow();
_myServer->getOctree()->lockForWrite();
uint64_t startProcess = usecTimestampNow();
quint64 startProcess = usecTimestampNow();
int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType,
packetData,
packetLength,
reinterpret_cast<const unsigned char*>(packet.data()),
packet.size(),
editData, maxSize, senderNode.data());
_myServer->getOctree()->unlock();
uint64_t endProcess = usecTimestampNow();
quint64 endProcess = usecTimestampNow();
editsInPacket++;
uint64_t thisProcessTime = endProcess - startProcess;
uint64_t thisLockWaitTime = startProcess - startLock;
quint64 thisProcessTime = endProcess - startProcess;
quint64 thisLockWaitTime = startProcess - startLock;
processTime += thisProcessTime;
lockWaitTime += thisLockWaitTime;
@ -106,8 +107,8 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
if (debugProcessPacket) {
printf("OctreeInboundPacketProcessor::processPacket() DONE LOOPING FOR %c "
"packetData=%p packetLength=%ld voxelData=%p atByte=%d\n",
packetType, packetData, packetLength, editData, atByte);
"packetData=%p packetLength=%d voxelData=%p atByte=%d\n",
packetType, packetData, packet.size(), editData, atByte);
}
// Make sure our Node and NodeList knows we've heard from this node.
@ -125,12 +126,12 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
}
trackInboundPackets(nodeUUID, sequence, transitTime, editsInPacket, processTime, lockWaitTime);
} else {
qDebug("unknown packet ignored... packetData[0]=%c", packetData[0]);
qDebug("unknown packet ignored... packetType=%d", packetType);
}
}
void OctreeInboundPacketProcessor::trackInboundPackets(const QUuid& nodeUUID, int sequence, uint64_t transitTime,
int editsInPacket, uint64_t processTime, uint64_t lockWaitTime) {
void OctreeInboundPacketProcessor::trackInboundPackets(const QUuid& nodeUUID, int sequence, quint64 transitTime,
int editsInPacket, quint64 processTime, quint64 lockWaitTime) {
_totalTransitTime += transitTime;
_totalProcessTime += processTime;

View file

@ -20,21 +20,21 @@ class SingleSenderStats {
public:
SingleSenderStats();
uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
uint64_t getTotalElementsProcessed() const { return _totalElementsInPacket; }
uint64_t getTotalPacketsProcessed() const { return _totalPackets; }
uint64_t getAverageProcessTimePerElement() const
quint64 getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
quint64 getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
quint64 getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
quint64 getTotalElementsProcessed() const { return _totalElementsInPacket; }
quint64 getTotalPacketsProcessed() const { return _totalPackets; }
quint64 getAverageProcessTimePerElement() const
{ return _totalElementsInPacket == 0 ? 0 : _totalProcessTime / _totalElementsInPacket; }
uint64_t getAverageLockWaitTimePerElement() const
quint64 getAverageLockWaitTimePerElement() const
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
uint64_t _totalTransitTime;
uint64_t _totalProcessTime;
uint64_t _totalLockWaitTime;
uint64_t _totalElementsInPacket;
uint64_t _totalPackets;
quint64 _totalTransitTime;
quint64 _totalProcessTime;
quint64 _totalLockWaitTime;
quint64 _totalElementsInPacket;
quint64 _totalPackets;
};
typedef std::map<QUuid, SingleSenderStats> NodeToSenderStatsMap;
@ -48,14 +48,14 @@ class OctreeInboundPacketProcessor : public ReceivedPacketProcessor {
public:
OctreeInboundPacketProcessor(OctreeServer* myServer);
uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
uint64_t getTotalElementsProcessed() const { return _totalElementsInPacket; }
uint64_t getTotalPacketsProcessed() const { return _totalPackets; }
uint64_t getAverageProcessTimePerElement() const
quint64 getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
quint64 getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
quint64 getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
quint64 getTotalElementsProcessed() const { return _totalElementsInPacket; }
quint64 getTotalPacketsProcessed() const { return _totalPackets; }
quint64 getAverageProcessTimePerElement() const
{ return _totalElementsInPacket == 0 ? 0 : _totalProcessTime / _totalElementsInPacket; }
uint64_t getAverageLockWaitTimePerElement() const
quint64 getAverageLockWaitTimePerElement() const
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
void resetStats();
@ -63,20 +63,20 @@ public:
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
protected:
virtual void processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength);
virtual void processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
private:
void trackInboundPackets(const QUuid& nodeUUID, int sequence, uint64_t transitTime,
int voxelsInPacket, uint64_t processTime, uint64_t lockWaitTime);
void trackInboundPackets(const QUuid& nodeUUID, int sequence, quint64 transitTime,
int voxelsInPacket, quint64 processTime, quint64 lockWaitTime);
OctreeServer* _myServer;
int _receivedPacketCount;
uint64_t _totalTransitTime;
uint64_t _totalProcessTime;
uint64_t _totalLockWaitTime;
uint64_t _totalElementsInPacket;
uint64_t _totalPackets;
quint64 _totalTransitTime;
quint64 _totalProcessTime;
quint64 _totalLockWaitTime;
quint64 _totalElementsInPacket;
quint64 _totalPackets;
NodeToSenderStatsMap _singleSenderStats;
};

View file

@ -69,7 +69,7 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
// How long has it been since we've sent one, if we're still under our max time, then keep considering
// this packet for suppression
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
long sinceFirstSuppressedPacket = now - _firstSuppressedPacket;
const long MAX_TIME_BETWEEN_DUPLICATE_PACKETS = 1000 * 1000; // 1 second.
@ -110,7 +110,7 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) {
}
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
int numBytesPacketHeader = populateTypeAndVersion(_octreePacket, getMyPacketType());
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(_octreePacket), getMyPacketType());
_octreePacketAt = _octreePacket + numBytesPacketHeader;
_octreePacketAvailableBytes -= numBytesPacketHeader;
@ -233,7 +233,7 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
}
// save that we know the view has been sent.
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
setLastTimeBagEmpty(now); // is this what we want? poor names
}

View file

@ -27,7 +27,7 @@ public:
OctreeQueryNode();
virtual ~OctreeQueryNode();
virtual PACKET_TYPE getMyPacketType() const = 0;
virtual PacketType getMyPacketType() const = 0;
void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header
@ -67,8 +67,8 @@ public:
bool moveShouldDump() const;
uint64_t getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }
void setLastTimeBagEmpty(uint64_t lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; }
quint64 getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }
void setLastTimeBagEmpty(quint64 lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; }
bool getCurrentPacketIsColor() const { return _currentPacketIsColor; }
bool getCurrentPacketIsCompressed() const { return _currentPacketIsCompressed; }
@ -98,13 +98,13 @@ private:
unsigned char* _lastOctreePacket;
int _lastOctreePacketLength;
int _duplicatePacketCount;
uint64_t _firstSuppressedPacket;
quint64 _firstSuppressedPacket;
int _maxSearchLevel;
int _maxLevelReachedInLastSearch;
ViewFrustum _currentViewFrustum;
ViewFrustum _lastKnownViewFrustum;
uint64_t _lastTimeBagEmpty;
quint64 _lastTimeBagEmpty;
bool _viewFrustumChanging;
bool _viewFrustumJustStoppedChanging;
bool _currentPacketIsColor;

View file

@ -14,8 +14,8 @@
#include "OctreeServer.h"
#include "OctreeServerConsts.h"
uint64_t startSceneSleepTime = 0;
uint64_t endSceneSleepTime = 0;
quint64 startSceneSleepTime = 0;
quint64 endSceneSleepTime = 0;
OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer) :
_nodeUUID(nodeUUID),
@ -25,7 +25,7 @@ OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer
}
bool OctreeSendThread::process() {
uint64_t start = usecTimestampNow();
quint64 start = usecTimestampNow();
bool gotLock = false;
// don't do any send processing until the initial load of the octree is complete...
@ -79,16 +79,16 @@ bool OctreeSendThread::process() {
return isStillRunning(); // keep running till they terminate us
}
uint64_t OctreeSendThread::_usleepTime = 0;
uint64_t OctreeSendThread::_usleepCalls = 0;
quint64 OctreeSendThread::_usleepTime = 0;
quint64 OctreeSendThread::_usleepCalls = 0;
uint64_t OctreeSendThread::_totalBytes = 0;
uint64_t OctreeSendThread::_totalWastedBytes = 0;
uint64_t OctreeSendThread::_totalPackets = 0;
quint64 OctreeSendThread::_totalBytes = 0;
quint64 OctreeSendThread::_totalWastedBytes = 0;
quint64 OctreeSendThread::_totalPackets = 0;
int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) {
bool debug = _myServer->wantsDebugSending();
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
bool packetSent = false; // did we send a packet?
int packetsSent = 0;
@ -101,7 +101,7 @@ int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, in
}
const unsigned char* messageData = nodeData->getPacket();
int numBytesPacketHeader = numBytesForPacketHeader(messageData);
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(messageData));
const unsigned char* dataAt = messageData + numBytesPacketHeader;
dataAt += sizeof(OCTREE_PACKET_FLAGS);
OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
@ -283,7 +283,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
// If the current view frustum has changed OR we have nothing to send, then search against
// the current view frustum for things to send.
if (viewFrustumChanged || nodeData->nodeBag.isEmpty()) {
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
qDebug("(viewFrustumChanged=%s || nodeData->nodeBag.isEmpty() =%s)...",
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()));
@ -310,7 +310,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
if (!viewFrustumChanged && !nodeData->getWantDelta()) {
// only set our last sent time if we weren't resetting due to frustum change
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
nodeData->setLastTimeBagEmpty(now);
}
@ -374,9 +374,9 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
// If we have something in our nodeBag, then turn them into packets and send them out...
if (!nodeData->nodeBag.isEmpty()) {
int bytesWritten = 0;
uint64_t start = usecTimestampNow();
uint64_t startCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
uint64_t startCompressCalls = OctreePacketData::getCompressContentCalls();
quint64 start = usecTimestampNow();
quint64 startCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
quint64 startCompressCalls = OctreePacketData::getCompressContentCalls();
int clientMaxPacketsPerInterval = std::max(1,(nodeData->getMaxOctreePacketsPerSecond() / INTERVALS_PER_SECOND));
int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
@ -533,13 +533,13 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
}
uint64_t end = usecTimestampNow();
quint64 end = usecTimestampNow();
int elapsedmsec = (end - start)/1000;
uint64_t endCompressCalls = OctreePacketData::getCompressContentCalls();
quint64 endCompressCalls = OctreePacketData::getCompressContentCalls();
int elapsedCompressCalls = endCompressCalls - startCompressCalls;
uint64_t endCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
quint64 endCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
int elapsedCompressTimeMsecs = endCompressTimeMsecs - startCompressTimeMsecs;

View file

@ -21,12 +21,12 @@ class OctreeSendThread : public GenericThread {
public:
OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer);
static uint64_t _totalBytes;
static uint64_t _totalWastedBytes;
static uint64_t _totalPackets;
static quint64 _totalBytes;
static quint64 _totalWastedBytes;
static quint64 _totalPackets;
static uint64_t _usleepTime;
static uint64_t _usleepCalls;
static quint64 _usleepTime;
static quint64 _usleepCalls;
protected:
/// Implements generic processing behavior for this thread.

View file

@ -28,8 +28,8 @@ void OctreeServer::attachQueryNodeToNode(Node* newNode) {
}
}
OctreeServer::OctreeServer(const unsigned char* dataBuffer, int numBytes) :
ThreadedAssignment(dataBuffer, numBytes),
OctreeServer::OctreeServer(const QByteArray& packet) :
ThreadedAssignment(packet),
_argc(0),
_argv(NULL),
_parsedArgV(NULL),
@ -120,7 +120,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
}
if (showStats) {
uint64_t checkSum;
quint64 checkSum;
// return a 200
QString statsString("<html><doc>\r\n<pre>\r\n");
statsString += QString("<b>Your %1 Server is running... <a href='/'>[RELOAD]</a></b>\r\n").arg(getMyServerName());
@ -140,9 +140,9 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
statsString += "\r\n";
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
const int USECS_PER_MSEC = 1000;
uint64_t msecsElapsed = (now - _startedUSecs) / USECS_PER_MSEC;
quint64 msecsElapsed = (now - _startedUSecs) / USECS_PER_MSEC;
const int MSECS_PER_SEC = 1000;
const int SECS_PER_MIN = 60;
const int MIN_PER_HOUR = 60;
@ -175,7 +175,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
statsString += "\r\n";
uint64_t msecsElapsed = getLoadElapsedTime() / USECS_PER_MSEC;;
quint64 msecsElapsed = getLoadElapsedTime() / USECS_PER_MSEC;;
float seconds = (msecsElapsed % MSECS_PER_MIN)/(float)MSECS_PER_SEC;
int minutes = (msecsElapsed/(MSECS_PER_MIN)) % MIN_PER_HOUR;
int hours = (msecsElapsed/(MSECS_PER_MIN * MIN_PER_HOUR));
@ -226,12 +226,12 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
// display outbound packet stats
statsString += QString("<b>%1 Outbound Packet Statistics...</b>\r\n").arg(getMyServerName());
uint64_t totalOutboundPackets = OctreeSendThread::_totalPackets;
uint64_t totalOutboundBytes = OctreeSendThread::_totalBytes;
uint64_t totalWastedBytes = OctreeSendThread::_totalWastedBytes;
uint64_t totalBytesOfOctalCodes = OctreePacketData::getTotalBytesOfOctalCodes();
uint64_t totalBytesOfBitMasks = OctreePacketData::getTotalBytesOfBitMasks();
uint64_t totalBytesOfColor = OctreePacketData::getTotalBytesOfColor();
quint64 totalOutboundPackets = OctreeSendThread::_totalPackets;
quint64 totalOutboundBytes = OctreeSendThread::_totalBytes;
quint64 totalWastedBytes = OctreeSendThread::_totalWastedBytes;
quint64 totalBytesOfOctalCodes = OctreePacketData::getTotalBytesOfOctalCodes();
quint64 totalBytesOfBitMasks = OctreePacketData::getTotalBytesOfBitMasks();
quint64 totalBytesOfColor = OctreePacketData::getTotalBytesOfColor();
const int COLUMN_WIDTH = 10;
statsString += QString(" Total Outbound Packets: %1 packets\r\n")
@ -256,13 +256,13 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
// display inbound packet stats
statsString += QString().sprintf("<b>%s Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n",
getMyServerName());
uint64_t averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
uint64_t averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
uint64_t averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
uint64_t averageProcessTimePerElement = _octreeInboundPacketProcessor->getAverageProcessTimePerElement();
uint64_t averageLockWaitTimePerElement = _octreeInboundPacketProcessor->getAverageLockWaitTimePerElement();
uint64_t totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
uint64_t totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed();
quint64 averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
quint64 averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
quint64 averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
quint64 averageProcessTimePerElement = _octreeInboundPacketProcessor->getAverageProcessTimePerElement();
quint64 averageLockWaitTimePerElement = _octreeInboundPacketProcessor->getAverageLockWaitTimePerElement();
quint64 totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
quint64 totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed();
float averageElementsPerPacket = totalPacketsProcessed == 0 ? 0 : totalElementsProcessed / totalPacketsProcessed;
@ -432,7 +432,7 @@ void OctreeServer::setArguments(int argc, char** argv) {
void OctreeServer::parsePayload() {
if (getNumPayloadBytes() > 0) {
if (getPayload().size() > 0) {
QString config((const char*) _payload);
// Now, parse the config
@ -461,26 +461,23 @@ void OctreeServer::parsePayload() {
void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
NodeList* nodeList = NodeList::getInstance();
PACKET_TYPE packetType = dataByteArray[0];
PacketType packetType = packetTypeForPacket(dataByteArray);
if (packetType == getMyQueryMessageType()) {
bool debug = false;
if (debug) {
qDebug() << "Got PACKET_TYPE_VOXEL_QUERY at" << usecTimestampNow();
qDebug() << "Got PacketType_VOXEL_QUERY at" << usecTimestampNow();
}
int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) dataByteArray.data());
// If we got a PACKET_TYPE_VOXEL_QUERY, then we're talking to an NODE_TYPE_AVATAR, and we
// If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we
// need to make sure we have it in our nodeList.
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesPacketHeader,
NUM_BYTES_RFC4122_UUID));
QUuid nodeUUID;
deconstructPacketHeader(dataByteArray, nodeUUID);
SharedNodePointer node = nodeList->nodeWithUUID(nodeUUID);
if (node) {
nodeList->updateNodeWithData(node.data(), senderSockAddr, (unsigned char *) dataByteArray.data(),
dataByteArray.size());
nodeList->updateNodeWithData(node.data(), senderSockAddr, dataByteArray);
if (!node->getActiveSocket()) {
// we don't have an active socket for this node, but they're talking to us
// this means they've heard from us and can reply, let's assume public is active
@ -491,16 +488,13 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo
nodeData->initializeOctreeSendThread(this, nodeUUID);
}
}
} else if (packetType == PACKET_TYPE_JURISDICTION_REQUEST) {
_jurisdictionSender->queueReceivedPacket(senderSockAddr, (unsigned char*) dataByteArray.data(),
dataByteArray.size());
} else if (packetType == PacketTypeJurisdictionRequest) {
_jurisdictionSender->queueReceivedPacket(senderSockAddr, dataByteArray);
} else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) {
_octreeInboundPacketProcessor->queueReceivedPacket(senderSockAddr, (unsigned char*) dataByteArray.data(),
dataByteArray.size());
_octreeInboundPacketProcessor->queueReceivedPacket(senderSockAddr, dataByteArray);
} else {
// let processNodeData handle it.
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(),
dataByteArray.size());
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
}
}
@ -512,7 +506,7 @@ void OctreeServer::run() {
Logging::setTargetName(getMyLoggingServerTargetName());
// Now would be a good time to parse our arguments, if we got them as assignment
if (getNumPayloadBytes() > 0) {
if (getPayload().size() > 0) {
parsePayload();
}
@ -558,7 +552,7 @@ void OctreeServer::run() {
nodeList->setOwnerType(getMyNodeType());
// we need to ask the DS about agents so we can ping/reply with them
nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
setvbuf(stdout, NULL, _IOLBF, 0);

View file

@ -28,7 +28,7 @@
class OctreeServer : public ThreadedAssignment, public HTTPRequestHandler {
Q_OBJECT
public:
OctreeServer(const unsigned char* dataBuffer, int numBytes);
OctreeServer(const QByteArray& packet);
~OctreeServer();
/// allows setting of run arguments
@ -45,13 +45,13 @@ public:
bool isInitialLoadComplete() const { return (_persistThread) ? _persistThread->isInitialLoadComplete() : true; }
bool isPersistEnabled() const { return (_persistThread) ? true : false; }
uint64_t getLoadElapsedTime() const { return (_persistThread) ? _persistThread->getLoadElapsedTime() : 0; }
quint64 getLoadElapsedTime() const { return (_persistThread) ? _persistThread->getLoadElapsedTime() : 0; }
// Subclasses must implement these methods
virtual OctreeQueryNode* createOctreeQueryNode() = 0;
virtual Octree* createTree() = 0;
virtual unsigned char getMyNodeType() const = 0;
virtual PACKET_TYPE getMyQueryMessageType() const = 0;
virtual PacketType getMyQueryMessageType() const = 0;
virtual const char* getMyServerName() const = 0;
virtual const char* getMyLoggingServerTargetName() const = 0;
virtual const char* getMyDefaultPersistFilename() const = 0;
@ -94,7 +94,7 @@ protected:
static OctreeServer* _instance;
time_t _started;
uint64_t _startedUSecs;
quint64 _startedUSecs;
};
#endif // __octree_server__OctreeServer__

View file

@ -15,14 +15,14 @@
#include <PacketHeaders.h>
#include "JurisdictionListener.h"
JurisdictionListener::JurisdictionListener(NODE_TYPE type) :
JurisdictionListener::JurisdictionListener(NodeType_t type) :
_packetSender(JurisdictionListener::DEFAULT_PACKETS_PER_SECOND)
{
_nodeType = type;
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &JurisdictionListener::nodeKilled);
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)", type);
//qDebug("JurisdictionListener::JurisdictionListener(NodeType_t type=%c)", type);
// tell our NodeList we want to hear about nodes with our node type
NodeList::getInstance()->addNodeTypeToInterestSet(type);
@ -39,7 +39,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
static unsigned char buffer[MAX_PACKET_SIZE];
unsigned char* bufferOut = &buffer[0];
ssize_t sizeOut = populateTypeAndVersion(bufferOut, PACKET_TYPE_JURISDICTION_REQUEST);
ssize_t sizeOut = populatePacketHeader(reinterpret_cast<char*>(bufferOut), PacketTypeJurisdictionRequest);
int nodeCount = 0;
NodeList* nodeList = NodeList::getInstance();
@ -48,7 +48,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
if (nodeList->getNodeActiveSocketOrPing(node.data()) &&
node->getType() == getNodeType()) {
const HifiSockAddr* nodeAddress = node->getActiveSocket();
_packetSender.queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
_packetSender.queuePacketForSending(*nodeAddress, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
nodeCount++;
}
}
@ -63,14 +63,14 @@ bool JurisdictionListener::queueJurisdictionRequest() {
return isStillRunning();
}
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet) {
//qDebug() << "JurisdictionListener::processPacket()";
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
if (packetTypeForPacket(packet) == PacketTypeJurisdictionRequest) {
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
if (node) {
QUuid nodeUUID = node->getUUID();
JurisdictionMap map;
map.unpackFromMessage(packetData, packetLength);
map.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
_jurisdictions[nodeUUID] = map;
}
}

View file

@ -18,8 +18,8 @@
#include "JurisdictionMap.h"
/// Sends out PACKET_TYPE_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
/// the PACKET_TYPE_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
/// Sends out PacketType_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
/// the PacketType_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
/// and adding them to the processing queue by calling queueReceivedPacket()
class JurisdictionListener : public ReceivedPacketProcessor {
@ -28,32 +28,32 @@ public:
static const int DEFAULT_PACKETS_PER_SECOND = 1;
static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps
JurisdictionListener(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER);
JurisdictionListener(NodeType_t type = NodeType::VoxelServer);
virtual bool process();
NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; };
NODE_TYPE getNodeType() const { return _nodeType; }
void setNodeType(NODE_TYPE type) { _nodeType = type; }
NodeType_t getNodeType() const { return _nodeType; }
void setNodeType(NodeType_t type) { _nodeType = type; }
public slots:
/// Called by NodeList to inform us that a node has been killed.
void nodeKilled(SharedNodePointer node);
protected:
/// Callback for processing of received packets. Will process any queued PACKET_TYPE_JURISDICTION and update the
/// Callback for processing of received packets. Will process any queued PacketType_JURISDICTION and update the
/// jurisdiction map member variable
/// \param sockaddr& senderAddress the address of the sender
/// \param packetData pointer to received data
/// \param ssize_t packetLength size of received data
/// \thread "this" individual processing thread
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
virtual void processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet);
private:
NodeToJurisdictionMap _jurisdictions;
NODE_TYPE _nodeType;
NodeType_t _nodeType;
bool queueJurisdictionRequest();

View file

@ -92,7 +92,7 @@ void JurisdictionMap::clear() {
_endNodes.clear();
}
JurisdictionMap::JurisdictionMap(NODE_TYPE type) : _rootOctalCode(NULL) {
JurisdictionMap::JurisdictionMap(NodeType_t type) : _rootOctalCode(NULL) {
_nodeType = type;
unsigned char* rootCode = new unsigned char[1];
*rootCode = 0;
@ -262,10 +262,10 @@ bool JurisdictionMap::writeToFile(const char* filename) {
return true;
}
int JurisdictionMap::packEmptyJurisdictionIntoMessage(NODE_TYPE type, unsigned char* destinationBuffer, int availableBytes) {
int JurisdictionMap::packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned char* destinationBuffer, int availableBytes) {
unsigned char* bufferStart = destinationBuffer;
int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_JURISDICTION);
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeJurisdiction);
destinationBuffer += headerLength;
// Pack the Node Type in first byte
@ -283,11 +283,11 @@ int JurisdictionMap::packEmptyJurisdictionIntoMessage(NODE_TYPE type, unsigned c
int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
unsigned char* bufferStart = destinationBuffer;
int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_JURISDICTION);
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeJurisdiction);
destinationBuffer += headerLength;
// Pack the Node Type in first byte
NODE_TYPE type = getNodeType();
NodeType_t type = getNodeType();
memcpy(destinationBuffer, &type, sizeof(type));
destinationBuffer += sizeof(type);
@ -324,12 +324,12 @@ int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int avail
return destinationBuffer - bufferStart; // includes header!
}
int JurisdictionMap::unpackFromMessage(unsigned char* sourceBuffer, int availableBytes) {
int JurisdictionMap::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) {
clear();
unsigned char* startPosition = sourceBuffer;
const unsigned char* startPosition = sourceBuffer;
// increment to push past the packet header
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(sourceBuffer));
sourceBuffer += numBytesPacketHeader;
int remainingBytes = availableBytes - numBytesPacketHeader;

View file

@ -16,7 +16,7 @@
#include <QtCore/QString>
#include <QtCore/QUuid>
#include <NodeTypes.h>
#include <Node.h>
class JurisdictionMap {
public:
@ -27,7 +27,7 @@ public:
};
// standard constructors
JurisdictionMap(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER); // default constructor
JurisdictionMap(NodeType_t type = NodeType::VoxelServer); // default constructor
JurisdictionMap(const JurisdictionMap& other); // copy constructor
// standard assignment
@ -56,16 +56,16 @@ public:
void copyContents(unsigned char* rootCodeIn, const std::vector<unsigned char*>& endNodesIn);
int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes);
int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes);
int packIntoMessage(unsigned char* destinationBuffer, int availableBytes);
/// Available to pack an empty or unknown jurisdiction into a network packet, used when no JurisdictionMap is available
static int packEmptyJurisdictionIntoMessage(NODE_TYPE type, unsigned char* destinationBuffer, int availableBytes);
static int packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned char* destinationBuffer, int availableBytes);
void displayDebugDetails() const;
NODE_TYPE getNodeType() const { return _nodeType; }
void setNodeType(NODE_TYPE type) { _nodeType = type; }
NodeType_t getNodeType() const { return _nodeType; }
void setNodeType(NodeType_t type) { _nodeType = type; }
private:
void copyContents(const JurisdictionMap& other); // use assignment instead
@ -74,7 +74,7 @@ private:
unsigned char* _rootOctalCode;
std::vector<unsigned char*> _endNodes;
NODE_TYPE _nodeType;
NodeType_t _nodeType;
};
/// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are

View file

@ -16,7 +16,7 @@
#include "JurisdictionSender.h"
JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NODE_TYPE type) :
JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NodeType_t type) :
ReceivedPacketProcessor(),
_jurisdictionMap(map),
_packetSender(JurisdictionSender::DEFAULT_PACKETS_PER_SECOND)
@ -28,11 +28,11 @@ JurisdictionSender::~JurisdictionSender() {
}
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
if (packetData[0] == PACKET_TYPE_JURISDICTION_REQUEST) {
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
if (node) {
QUuid nodeUUID = node->getUUID();
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet) {
if (packetTypeForPacket(packet) == PacketTypeJurisdictionRequest) {
QUuid nodeUUID;
deconstructPacketHeader(packet, nodeUUID);
if (!nodeUUID.isNull()) {
lockRequestingNodes();
_nodesRequestingJurisdictions.push(nodeUUID);
unlockRequestingNodes();
@ -66,7 +66,7 @@ bool JurisdictionSender::process() {
if (node->getActiveSocket() != NULL) {
const HifiSockAddr* nodeAddress = node->getActiveSocket();
_packetSender.queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
_packetSender.queuePacketForSending(*nodeAddress, QByteArray(reinterpret_cast<char *>(bufferOut), sizeOut));
nodeCount++;
}
}

View file

@ -18,7 +18,7 @@
#include <ReceivedPacketProcessor.h>
#include "JurisdictionMap.h"
/// Will process PACKET_TYPE_JURISDICTION_REQUEST packets and send out PACKET_TYPE_JURISDICTION packets
/// Will process PacketType_JURISDICTION_REQUEST packets and send out PacketType_JURISDICTION packets
/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
/// and adding them to the processing queue by calling queueReceivedPacket()
class JurisdictionSender : public ReceivedPacketProcessor {
@ -26,18 +26,18 @@ class JurisdictionSender : public ReceivedPacketProcessor {
public:
static const int DEFAULT_PACKETS_PER_SECOND = 1;
JurisdictionSender(JurisdictionMap* map, NODE_TYPE type = NODE_TYPE_VOXEL_SERVER);
JurisdictionSender(JurisdictionMap* map, NodeType_t type = NodeType::VoxelServer);
~JurisdictionSender();
void setJurisdiction(JurisdictionMap* map) { _jurisdictionMap = map; }
virtual bool process();
NODE_TYPE getNodeType() const { return _nodeType; }
void setNodeType(NODE_TYPE type) { _nodeType = type; }
NodeType_t getNodeType() const { return _nodeType; }
void setNodeType(NodeType_t type) { _nodeType = type; }
protected:
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
virtual void processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet);
/// Locks all the resources of the thread.
void lockRequestingNodes() { _requestingNodeMutex.lock(); }
@ -50,7 +50,7 @@ private:
QMutex _requestingNodeMutex;
JurisdictionMap* _jurisdictionMap;
std::queue<QUuid> _nodesRequestingJurisdictions;
NODE_TYPE _nodeType;
NodeType_t _nodeType;
PacketSender _packetSender;
};

View file

@ -444,9 +444,9 @@ void Octree::eraseAllOctreeElements() {
void Octree::processRemoveOctreeElementsBitstream(const unsigned char* bitstream, int bufferSizeBytes) {
//unsigned short int itemNumber = (*((unsigned short int*)&bitstream[sizeof(PACKET_HEADER)]));
int numBytesPacketHeader = numBytesForPacketHeader(bitstream);
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(bitstream));
unsigned short int sequence = (*((unsigned short int*)(bitstream + numBytesPacketHeader)));
uint64_t sentAt = (*((uint64_t*)(bitstream + numBytesPacketHeader + sizeof(sequence))));
quint64 sentAt = (*((quint64*)(bitstream + numBytesPacketHeader + sizeof(sequence))));
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
@ -1323,13 +1323,16 @@ bool Octree::readFromSVOFile(const char* fileName) {
// before reading the file, check to see if this version of the Octree supports file versions
if (getWantSVOfileVersions()) {
// if so, read the first byte of the file and see if it matches the expected version code
PACKET_TYPE expectedType = expectedDataPacketType();
PACKET_TYPE gotType = *dataAt;
PacketType expectedType = expectedDataPacketType();
PacketType gotType;
memcpy(&gotType, dataAt, sizeof(gotType));
if (gotType == expectedType) {
dataAt += sizeof(expectedType);
dataLength -= sizeof(expectedType);
PACKET_VERSION expectedVersion = versionForPacketType(expectedType);
PACKET_VERSION gotVersion = *dataAt;
PacketVersion expectedVersion = versionForPacketType(expectedType);
PacketVersion gotVersion = *dataAt;
if (gotVersion == expectedVersion) {
dataAt += sizeof(expectedVersion);
dataLength -= sizeof(expectedVersion);
@ -1366,9 +1369,9 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* node) {
// before reading the file, check to see if this version of the Octree supports file versions
if (getWantSVOfileVersions()) {
// if so, read the first byte of the file and see if it matches the expected version code
PACKET_TYPE expectedType = expectedDataPacketType();
PACKET_VERSION expectedVersion = versionForPacketType(expectedType);
file.write(&expectedType, sizeof(expectedType));
PacketType expectedType = expectedDataPacketType();
PacketVersion expectedVersion = versionForPacketType(expectedType);
file.write(reinterpret_cast<char*>(&expectedType), sizeof(expectedType));
file.write(&expectedVersion, sizeof(expectedVersion));
}

View file

@ -47,7 +47,7 @@ const bool WANT_OCCLUSION_CULLING = true;
const int DONT_CHOP = 0;
const int NO_BOUNDARY_ADJUST = 0;
const int LOW_RES_MOVING_ADJUST = 1;
const uint64_t IGNORE_LAST_SENT = 0;
const quint64 IGNORE_LAST_SENT = 0;
#define IGNORE_SCENE_STATS NULL
#define IGNORE_VIEW_FRUSTUM NULL
@ -67,7 +67,7 @@ public:
bool wantOcclusionCulling;
int boundaryLevelAdjust;
float octreeElementSizeScale;
uint64_t lastViewFrustumSent;
quint64 lastViewFrustumSent;
bool forceSendScene;
OctreeSceneStats* stats;
CoverageMap* map;
@ -100,7 +100,7 @@ public:
CoverageMap* map = IGNORE_COVERAGE_MAP,
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
float octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
uint64_t lastViewFrustumSent = IGNORE_LAST_SENT,
quint64 lastViewFrustumSent = IGNORE_LAST_SENT,
bool forceSendScene = true,
OctreeSceneStats* stats = IGNORE_SCENE_STATS,
JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP) :
@ -187,10 +187,10 @@ public:
// These methods will allow the OctreeServer to send your tree inbound edit packets of your
// own definition. Implement these to allow your octree based server to support editing
virtual bool getWantSVOfileVersions() const { return false; }
virtual PACKET_TYPE expectedDataPacketType() const { return PACKET_TYPE_UNKNOWN; }
virtual bool handlesEditPacketType(PACKET_TYPE packetType) const { return false; }
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
unsigned char* editData, int maxLength, Node* senderNode) { return 0; }
virtual PacketType expectedDataPacketType() const { return PacketTypeUnknown; }
virtual bool handlesEditPacketType(PacketType packetType) const { return false; }
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
const unsigned char* editData, int maxLength, Node* senderNode) { return 0; }
virtual void update() { }; // nothing to do by default

View file

@ -24,7 +24,7 @@ const glm::vec3 IDENTITY_RIGHT = glm::vec3( 1.0f, 0.0f, 0.0f);
const glm::vec3 IDENTITY_UP = glm::vec3( 0.0f, 1.0f, 0.0f);
const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f,-1.0f);
const uint64_t CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
const quint64 CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
const int TREE_SCALE = 16384; // ~10 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe

View file

@ -17,7 +17,7 @@
#include "OctreeEditPacketSender.h"
EditPacketBuffer::EditPacketBuffer(PACKET_TYPE type, unsigned char* buffer, ssize_t length, QUuid nodeUUID) {
EditPacketBuffer::EditPacketBuffer(PacketType type, unsigned char* buffer, ssize_t length, QUuid nodeUUID) {
_nodeUUID = nodeUUID;
_currentType = type;
_currentSize = length;
@ -93,16 +93,16 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
if (nodeList->getNodeActiveSocketOrPing(node.data())) {
const HifiSockAddr* nodeAddress = node->getActiveSocket();
queuePacketForSending(*nodeAddress, buffer, length);
queuePacketForSending(*nodeAddress, QByteArray(reinterpret_cast<char*>(buffer), length));
// debugging output...
bool wantDebugging = false;
if (wantDebugging) {
int numBytesPacketHeader = numBytesForPacketHeader(buffer);
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<char*>(buffer));
unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader)));
uint64_t createdAt = (*((uint64_t*)(buffer + numBytesPacketHeader + sizeof(sequence))));
uint64_t queuedAt = usecTimestampNow();
uint64_t transitTime = queuedAt - createdAt;
quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence))));
quint64 queuedAt = usecTimestampNow();
quint64 transitTime = queuedAt - createdAt;
qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
" - command to node bytes=" << length <<
@ -141,7 +141,7 @@ void OctreeEditPacketSender::processPreServerExistsPackets() {
}
}
void OctreeEditPacketSender::queuePendingPacketToNodes(PACKET_TYPE type, unsigned char* buffer, ssize_t length) {
void OctreeEditPacketSender::queuePendingPacketToNodes(PacketType type, unsigned char* buffer, ssize_t length) {
// If we're asked to save messages while waiting for voxel servers to arrive, then do so...
if (_maxPendingMessages > 0) {
EditPacketBuffer* packet = new EditPacketBuffer(type, buffer, length);
@ -163,7 +163,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
assert(serversExist()); // we must have jurisdictions to be here!!
int headerBytes = numBytesForPacketHeader(buffer) + sizeof(short) + sizeof(uint64_t);
int headerBytes = numBytesForPacketHeader(reinterpret_cast<char*>(buffer)) + sizeof(short) + sizeof(quint64);
unsigned char* octCode = buffer + headerBytes; // skip the packet header to get to the octcode
// We want to filter out edit messages for servers based on the server's Jurisdiction
@ -189,7 +189,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
// NOTE: codeColorBuffer - is JUST the octcode/color and does not contain the packet header!
void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) {
void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned char* codeColorBuffer, ssize_t length) {
if (!_shouldSend) {
return; // bail early
@ -289,28 +289,28 @@ void OctreeEditPacketSender::releaseQueuedMessages() {
}
void OctreeEditPacketSender::releaseQueuedPacket(EditPacketBuffer& packetBuffer) {
if (packetBuffer._currentSize > 0 && packetBuffer._currentType != PACKET_TYPE_UNKNOWN) {
if (packetBuffer._currentSize > 0 && packetBuffer._currentType != PacketTypeUnknown) {
//qDebug() << "OctreeEditPacketSender::releaseQueuedPacket() line:" << __LINE__;
queuePacketToNode(packetBuffer._nodeUUID, &packetBuffer._currentBuffer[0], packetBuffer._currentSize);
}
packetBuffer._currentSize = 0;
packetBuffer._currentType = PACKET_TYPE_UNKNOWN;
packetBuffer._currentType = PacketTypeUnknown;
}
void OctreeEditPacketSender::initializePacket(EditPacketBuffer& packetBuffer, PACKET_TYPE type) {
packetBuffer._currentSize = populateTypeAndVersion(&packetBuffer._currentBuffer[0], type);
void OctreeEditPacketSender::initializePacket(EditPacketBuffer& packetBuffer, PacketType type) {
packetBuffer._currentSize = populatePacketHeader(reinterpret_cast<char*>(&packetBuffer._currentBuffer[0]), type);
// pack in sequence number
// pack in sequence numbers
unsigned short int* sequenceAt = (unsigned short int*)&packetBuffer._currentBuffer[packetBuffer._currentSize];
*sequenceAt = _sequenceNumber;
packetBuffer._currentSize += sizeof(unsigned short int); // nudge past sequence
_sequenceNumber++;
// pack in timestamp
uint64_t now = usecTimestampNow();
uint64_t* timeAt = (uint64_t*)&packetBuffer._currentBuffer[packetBuffer._currentSize];
quint64 now = usecTimestampNow();
quint64* timeAt = (quint64*)&packetBuffer._currentBuffer[packetBuffer._currentSize];
*timeAt = now;
packetBuffer._currentSize += sizeof(uint64_t); // nudge past timestamp
packetBuffer._currentSize += sizeof(quint64); // nudge past timestamp
packetBuffer._currentType = type;
}

View file

@ -18,10 +18,10 @@
/// Used for construction of edit packets
class EditPacketBuffer {
public:
EditPacketBuffer() : _nodeUUID(), _currentType(PACKET_TYPE_UNKNOWN), _currentSize(0) { }
EditPacketBuffer(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length, const QUuid nodeUUID = QUuid());
EditPacketBuffer() : _nodeUUID(), _currentType(PacketTypeUnknown), _currentSize(0) { }
EditPacketBuffer(PacketType type, unsigned char* codeColorBuffer, ssize_t length, const QUuid nodeUUID = QUuid());
QUuid _nodeUUID;
PACKET_TYPE _currentType;
PacketType _currentType;
unsigned char _currentBuffer[MAX_PACKET_SIZE];
ssize_t _currentSize;
};
@ -36,7 +36,7 @@ public:
/// Queues a single edit message. Will potentially send a pending multi-command packet. Determines which server
/// node or nodes the packet should be sent to. Can be called even before servers are known, in which case up to
/// MaxPendingMessages will be buffered and processed when servers are known.
void queueOctreeEditMessage(PACKET_TYPE type, unsigned char* buffer, ssize_t length);
void queueOctreeEditMessage(PacketType type, unsigned char* buffer, ssize_t length);
/// Releases all queued messages even if those messages haven't filled an MTU packet. This will move the packed message
/// packets onto the send queue. If running in threaded mode, the caller does not need to do any further processing to
@ -92,9 +92,9 @@ public:
protected:
bool _shouldSend;
void queuePacketToNode(const QUuid& nodeID, unsigned char* buffer, ssize_t length);
void queuePendingPacketToNodes(PACKET_TYPE type, unsigned char* buffer, ssize_t length);
void queuePendingPacketToNodes(PacketType type, unsigned char* buffer, ssize_t length);
void queuePacketToNodes(unsigned char* buffer, ssize_t length);
void initializePacket(EditPacketBuffer& packetBuffer, PACKET_TYPE type);
void initializePacket(EditPacketBuffer& packetBuffer, PacketType type);
void releaseQueuedPacket(EditPacketBuffer& packetBuffer); // releases specific queued packet
void processPreServerExistsPackets();

View file

@ -23,11 +23,11 @@
#include "OctreeElement.h"
#include "Octree.h"
uint64_t OctreeElement::_voxelMemoryUsage = 0;
uint64_t OctreeElement::_octcodeMemoryUsage = 0;
uint64_t OctreeElement::_externalChildrenMemoryUsage = 0;
uint64_t OctreeElement::_voxelNodeCount = 0;
uint64_t OctreeElement::_voxelNodeLeafCount = 0;
quint64 OctreeElement::_voxelMemoryUsage = 0;
quint64 OctreeElement::_octcodeMemoryUsage = 0;
quint64 OctreeElement::_externalChildrenMemoryUsage = 0;
quint64 OctreeElement::_voxelNodeCount = 0;
quint64 OctreeElement::_voxelNodeLeafCount = 0;
OctreeElement::OctreeElement() {
// Note: you must call init() from your subclass, otherwise the OctreeElement will not be properly
@ -270,23 +270,23 @@ void OctreeElement::auditChildren(const char* label) const {
#endif // def HAS_AUDIT_CHILDREN
uint64_t OctreeElement::_getChildAtIndexTime = 0;
uint64_t OctreeElement::_getChildAtIndexCalls = 0;
uint64_t OctreeElement::_setChildAtIndexTime = 0;
uint64_t OctreeElement::_setChildAtIndexCalls = 0;
quint64 OctreeElement::_getChildAtIndexTime = 0;
quint64 OctreeElement::_getChildAtIndexCalls = 0;
quint64 OctreeElement::_setChildAtIndexTime = 0;
quint64 OctreeElement::_setChildAtIndexCalls = 0;
#ifdef BLENDED_UNION_CHILDREN
uint64_t OctreeElement::_singleChildrenCount = 0;
uint64_t OctreeElement::_twoChildrenOffsetCount = 0;
uint64_t OctreeElement::_twoChildrenExternalCount = 0;
uint64_t OctreeElement::_threeChildrenOffsetCount = 0;
uint64_t OctreeElement::_threeChildrenExternalCount = 0;
uint64_t OctreeElement::_couldStoreFourChildrenInternally = 0;
uint64_t OctreeElement::_couldNotStoreFourChildrenInternally = 0;
quint64 OctreeElement::_singleChildrenCount = 0;
quint64 OctreeElement::_twoChildrenOffsetCount = 0;
quint64 OctreeElement::_twoChildrenExternalCount = 0;
quint64 OctreeElement::_threeChildrenOffsetCount = 0;
quint64 OctreeElement::_threeChildrenExternalCount = 0;
quint64 OctreeElement::_couldStoreFourChildrenInternally = 0;
quint64 OctreeElement::_couldNotStoreFourChildrenInternally = 0;
#endif
uint64_t OctreeElement::_externalChildrenCount = 0;
uint64_t OctreeElement::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
quint64 OctreeElement::_externalChildrenCount = 0;
quint64 OctreeElement::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
OctreeElement* OctreeElement::getChildAtIndex(int childIndex) const {
#ifdef SIMPLE_CHILD_ARRAY
@ -494,17 +494,17 @@ void OctreeElement::retrieveTwoChildren(OctreeElement*& childOne, OctreeElement*
}
void OctreeElement::decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, int64_t& offsetThree) const {
const uint64_t ENCODE_BITS = 21;
const uint64_t ENCODE_MASK = 0xFFFFF;
const uint64_t ENCODE_MASK_SIGN = 0x100000;
const quint64 ENCODE_BITS = 21;
const quint64 ENCODE_MASK = 0xFFFFF;
const quint64 ENCODE_MASK_SIGN = 0x100000;
uint64_t offsetEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK;
uint64_t offsetEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK;
uint64_t offsetEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK);
quint64 offsetEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK;
quint64 offsetEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK;
quint64 offsetEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK);
uint64_t signEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK_SIGN;
uint64_t signEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK_SIGN;
uint64_t signEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK_SIGN);
quint64 signEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK_SIGN;
quint64 signEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK_SIGN;
quint64 signEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK_SIGN);
bool oneNegative = signEncodedOne == ENCODE_MASK_SIGN;
bool twoNegative = signEncodedTwo == ENCODE_MASK_SIGN;
@ -516,11 +516,11 @@ void OctreeElement::decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, i
}
void OctreeElement::encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree) {
const uint64_t ENCODE_BITS = 21;
const uint64_t ENCODE_MASK = 0xFFFFF;
const uint64_t ENCODE_MASK_SIGN = 0x100000;
const quint64 ENCODE_BITS = 21;
const quint64 ENCODE_MASK = 0xFFFFF;
const quint64 ENCODE_MASK_SIGN = 0x100000;
uint64_t offsetEncodedOne, offsetEncodedTwo, offsetEncodedThree;
quint64 offsetEncodedOne, offsetEncodedTwo, offsetEncodedThree;
if (offsetOne < 0) {
offsetEncodedOne = ((-offsetOne & ENCODE_MASK) | ENCODE_MASK_SIGN);
} else {

View file

@ -132,9 +132,9 @@ public:
bool isDirty() const { return _isDirty; }
void clearDirtyBit() { _isDirty = false; }
void setDirtyBit() { _isDirty = true; }
bool hasChangedSince(uint64_t time) const { return (_lastChanged > time); }
bool hasChangedSince(quint64 time) const { return (_lastChanged > time); }
void markWithChangedTime();
uint64_t getLastChanged() const { return _lastChanged; }
quint64 getLastChanged() const { return _lastChanged; }
void handleSubtreeChanged(Octree* myTree);
// Used by VoxelSystem for rendering in/out of view and LOD
@ -158,28 +158,28 @@ public:
static unsigned long getInternalNodeCount() { return _voxelNodeCount - _voxelNodeLeafCount; }
static unsigned long getLeafNodeCount() { return _voxelNodeLeafCount; }
static uint64_t getVoxelMemoryUsage() { return _voxelMemoryUsage; }
static uint64_t getOctcodeMemoryUsage() { return _octcodeMemoryUsage; }
static uint64_t getExternalChildrenMemoryUsage() { return _externalChildrenMemoryUsage; }
static uint64_t getTotalMemoryUsage() { return _voxelMemoryUsage + _octcodeMemoryUsage + _externalChildrenMemoryUsage; }
static quint64 getVoxelMemoryUsage() { return _voxelMemoryUsage; }
static quint64 getOctcodeMemoryUsage() { return _octcodeMemoryUsage; }
static quint64 getExternalChildrenMemoryUsage() { return _externalChildrenMemoryUsage; }
static quint64 getTotalMemoryUsage() { return _voxelMemoryUsage + _octcodeMemoryUsage + _externalChildrenMemoryUsage; }
static uint64_t getGetChildAtIndexTime() { return _getChildAtIndexTime; }
static uint64_t getGetChildAtIndexCalls() { return _getChildAtIndexCalls; }
static uint64_t getSetChildAtIndexTime() { return _setChildAtIndexTime; }
static uint64_t getSetChildAtIndexCalls() { return _setChildAtIndexCalls; }
static quint64 getGetChildAtIndexTime() { return _getChildAtIndexTime; }
static quint64 getGetChildAtIndexCalls() { return _getChildAtIndexCalls; }
static quint64 getSetChildAtIndexTime() { return _setChildAtIndexTime; }
static quint64 getSetChildAtIndexCalls() { return _setChildAtIndexCalls; }
#ifdef BLENDED_UNION_CHILDREN
static uint64_t getSingleChildrenCount() { return _singleChildrenCount; }
static uint64_t getTwoChildrenOffsetCount() { return _twoChildrenOffsetCount; }
static uint64_t getTwoChildrenExternalCount() { return _twoChildrenExternalCount; }
static uint64_t getThreeChildrenOffsetCount() { return _threeChildrenOffsetCount; }
static uint64_t getThreeChildrenExternalCount() { return _threeChildrenExternalCount; }
static uint64_t getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; }
static uint64_t getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; }
static quint64 getSingleChildrenCount() { return _singleChildrenCount; }
static quint64 getTwoChildrenOffsetCount() { return _twoChildrenOffsetCount; }
static quint64 getTwoChildrenExternalCount() { return _twoChildrenExternalCount; }
static quint64 getThreeChildrenOffsetCount() { return _threeChildrenOffsetCount; }
static quint64 getThreeChildrenExternalCount() { return _threeChildrenExternalCount; }
static quint64 getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; }
static quint64 getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; }
#endif
static uint64_t getExternalChildrenCount() { return _externalChildrenCount; }
static uint64_t getChildrenCount(int childCount) { return _childrenCount[childCount]; }
static quint64 getExternalChildrenCount() { return _externalChildrenCount; }
static quint64 getChildrenCount(int childCount) { return _childrenCount[childCount]; }
#ifdef BLENDED_UNION_CHILDREN
#ifdef HAS_AUDIT_CHILDREN
@ -227,7 +227,7 @@ protected:
unsigned char* pointer;
} _octalCode;
uint64_t _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes
quint64 _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes
/// Client and server, pointers to child nodes, various encodings
#ifdef SIMPLE_CHILD_ARRAY
@ -245,7 +245,7 @@ protected:
union children_t {
OctreeElement* single;
int32_t offsetsTwoChildren[2];
uint64_t offsetsThreeChildrenEncoded;
quint64 offsetsThreeChildrenEncoded;
OctreeElement** external;
} _children;
#ifdef HAS_AUDIT_CHILDREN
@ -278,29 +278,29 @@ protected:
//static QReadWriteLock _updateHooksLock;
static std::vector<OctreeElementUpdateHook*> _updateHooks;
static uint64_t _voxelNodeCount;
static uint64_t _voxelNodeLeafCount;
static quint64 _voxelNodeCount;
static quint64 _voxelNodeLeafCount;
static uint64_t _voxelMemoryUsage;
static uint64_t _octcodeMemoryUsage;
static uint64_t _externalChildrenMemoryUsage;
static quint64 _voxelMemoryUsage;
static quint64 _octcodeMemoryUsage;
static quint64 _externalChildrenMemoryUsage;
static uint64_t _getChildAtIndexTime;
static uint64_t _getChildAtIndexCalls;
static uint64_t _setChildAtIndexTime;
static uint64_t _setChildAtIndexCalls;
static quint64 _getChildAtIndexTime;
static quint64 _getChildAtIndexCalls;
static quint64 _setChildAtIndexTime;
static quint64 _setChildAtIndexCalls;
#ifdef BLENDED_UNION_CHILDREN
static uint64_t _singleChildrenCount;
static uint64_t _twoChildrenOffsetCount;
static uint64_t _twoChildrenExternalCount;
static uint64_t _threeChildrenOffsetCount;
static uint64_t _threeChildrenExternalCount;
static uint64_t _couldStoreFourChildrenInternally;
static uint64_t _couldNotStoreFourChildrenInternally;
static quint64 _singleChildrenCount;
static quint64 _twoChildrenOffsetCount;
static quint64 _twoChildrenExternalCount;
static quint64 _threeChildrenOffsetCount;
static quint64 _threeChildrenExternalCount;
static quint64 _couldStoreFourChildrenInternally;
static quint64 _couldNotStoreFourChildrenInternally;
#endif
static uint64_t _externalChildrenCount;
static uint64_t _childrenCount[NUMBER_OF_CHILDREN + 1];
static quint64 _externalChildrenCount;
static quint64 _childrenCount[NUMBER_OF_CHILDREN + 1];
};
#endif /* defined(__hifi__OctreeElement__) */

View file

@ -10,12 +10,12 @@
#include "OctreePacketData.h"
bool OctreePacketData::_debug = false;
uint64_t OctreePacketData::_totalBytesOfOctalCodes = 0;
uint64_t OctreePacketData::_totalBytesOfBitMasks = 0;
uint64_t OctreePacketData::_totalBytesOfColor = 0;
uint64_t OctreePacketData::_totalBytesOfValues = 0;
uint64_t OctreePacketData::_totalBytesOfPositions = 0;
uint64_t OctreePacketData::_totalBytesOfRawData = 0;
quint64 OctreePacketData::_totalBytesOfOctalCodes = 0;
quint64 OctreePacketData::_totalBytesOfBitMasks = 0;
quint64 OctreePacketData::_totalBytesOfColor = 0;
quint64 OctreePacketData::_totalBytesOfValues = 0;
quint64 OctreePacketData::_totalBytesOfPositions = 0;
quint64 OctreePacketData::_totalBytesOfRawData = 0;
@ -272,7 +272,7 @@ bool OctreePacketData::appendValue(uint32_t value) {
return success;
}
bool OctreePacketData::appendValue(uint64_t value) {
bool OctreePacketData::appendValue(quint64 value) {
const unsigned char* data = (const unsigned char*)&value;
int length = sizeof(value);
bool success = append(data, length);
@ -347,8 +347,8 @@ bool OctreePacketData::appendRawData(const unsigned char* data, int length) {
return success;
}
uint64_t OctreePacketData::_compressContentTime = 0;
uint64_t OctreePacketData::_compressContentCalls = 0;
quint64 OctreePacketData::_compressContentTime = 0;
quint64 OctreePacketData::_compressContentCalls = 0;
bool OctreePacketData::compressContent() {
PerformanceWarning warn(false, "OctreePacketData::compressContent()", false, &_compressContentTime, &_compressContentCalls);

View file

@ -25,11 +25,13 @@
typedef unsigned char OCTREE_PACKET_FLAGS;
typedef uint16_t OCTREE_PACKET_SEQUENCE;
typedef uint64_t OCTREE_PACKET_SENT_TIME;
typedef quint64 OCTREE_PACKET_SENT_TIME;
typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE;
const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE;
const int OCTREE_PACKET_HEADER_SIZE = (sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION) + sizeof(OCTREE_PACKET_FLAGS)
+ sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME));
// this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType could be as small as one byte
const int OCTREE_PACKET_HEADER_SIZE = MAX_PACKET_HEADER_BYTES + sizeof(OCTREE_PACKET_FLAGS)
+ sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME);
const int MAX_OCTREE_PACKET_DATA_SIZE = MAX_PACKET_SIZE - OCTREE_PACKET_HEADER_SIZE;
@ -60,7 +62,7 @@ private:
int _bytesOfColor;
};
/// Handles packing of the data portion of PACKET_TYPE_OCTREE_DATA messages.
/// Handles packing of the data portion of PacketType_OCTREE_DATA messages.
class OctreePacketData {
public:
OctreePacketData(bool enableCompression = false, int maxFinalizedSize = MAX_OCTREE_PACKET_DATA_SIZE);
@ -122,7 +124,7 @@ public:
bool appendValue(uint32_t value);
/// appends a unsigned 64 bit int to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(uint64_t value);
bool appendValue(quint64 value);
/// appends a float value to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(float value);
@ -171,11 +173,11 @@ public:
/// displays contents for debugging
void debugContent();
static uint64_t getCompressContentTime() { return _compressContentTime; } /// total time spent compressing content
static uint64_t getCompressContentCalls() { return _compressContentCalls; } /// total calls to compress content
static uint64_t getTotalBytesOfOctalCodes() { return _totalBytesOfOctalCodes; } /// total bytes for octal codes
static uint64_t getTotalBytesOfBitMasks() { return _totalBytesOfBitMasks; } /// total bytes of bitmasks
static uint64_t getTotalBytesOfColor() { return _totalBytesOfColor; } /// total bytes of color
static quint64 getCompressContentTime() { return _compressContentTime; } /// total time spent compressing content
static quint64 getCompressContentCalls() { return _compressContentCalls; } /// total calls to compress content
static quint64 getTotalBytesOfOctalCodes() { return _totalBytesOfOctalCodes; } /// total bytes for octal codes
static quint64 getTotalBytesOfBitMasks() { return _totalBytesOfBitMasks; } /// total bytes of bitmasks
static quint64 getTotalBytesOfColor() { return _totalBytesOfColor; } /// total bytes of color
private:
/// appends raw bytes, might fail if byte would cause packet to be too large
@ -211,15 +213,15 @@ private:
static bool _debug;
static uint64_t _compressContentTime;
static uint64_t _compressContentCalls;
static quint64 _compressContentTime;
static quint64 _compressContentCalls;
static uint64_t _totalBytesOfOctalCodes;
static uint64_t _totalBytesOfBitMasks;
static uint64_t _totalBytesOfColor;
static uint64_t _totalBytesOfValues;
static uint64_t _totalBytesOfPositions;
static uint64_t _totalBytesOfRawData;
static quint64 _totalBytesOfOctalCodes;
static quint64 _totalBytesOfBitMasks;
static quint64 _totalBytesOfColor;
static quint64 _totalBytesOfValues;
static quint64 _totalBytesOfPositions;
static quint64 _totalBytesOfRawData;
};
#endif /* defined(__hifi__OctreePacketData__) */

View file

@ -25,7 +25,7 @@ OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename,
bool OctreePersistThread::process() {
if (!_initialLoadComplete) {
uint64_t loadStarted = usecTimestampNow();
quint64 loadStarted = usecTimestampNow();
qDebug() << "loading Octrees from file: " << _filename << "...";
bool persistantFileRead;
@ -37,7 +37,7 @@ bool OctreePersistThread::process() {
}
_tree->unlock();
uint64_t loadDone = usecTimestampNow();
quint64 loadDone = usecTimestampNow();
_loadTimeUSecs = loadDone - loadStarted;
_tree->clearDirtyBit(); // the tree is clean since we just loaded it
@ -63,8 +63,8 @@ bool OctreePersistThread::process() {
}
if (isStillRunning()) {
uint64_t MSECS_TO_USECS = 1000;
uint64_t USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
quint64 MSECS_TO_USECS = 1000;
quint64 USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
usleep(USECS_TO_SLEEP);
// do our updates then check to save...
@ -72,9 +72,9 @@ bool OctreePersistThread::process() {
_tree->update();
_tree->unlock();
uint64_t now = usecTimestampNow();
uint64_t sinceLastSave = now - _lastCheck;
uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS;
quint64 now = usecTimestampNow();
quint64 sinceLastSave = now - _lastCheck;
quint64 intervalToCheck = _persistInterval * MSECS_TO_USECS;
if (sinceLastSave > intervalToCheck) {
// check the dirty bit and persist here...

View file

@ -24,7 +24,7 @@ public:
OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL);
bool isInitialLoadComplete() const { return _initialLoadComplete; }
uint64_t getLoadElapsedTime() const { return _loadTimeUSecs; }
quint64 getLoadElapsedTime() const { return _loadTimeUSecs; }
signals:
void loadCompleted();
@ -38,8 +38,8 @@ private:
int _persistInterval;
bool _initialLoadComplete;
uint64_t _loadTimeUSecs;
uint64_t _lastCheck;
quint64 _loadTimeUSecs;
quint64 _lastCheck;
};
#endif // __Octree_server__OctreePersistThread__

View file

@ -95,13 +95,13 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) {
}
// called on the other nodes - assigns it to my views of the others
int OctreeQuery::parseData(unsigned char* sourceBuffer, int numBytes) {
int OctreeQuery::parseData(const QByteArray& packet) {
// increment to push past the packet header
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
sourceBuffer += numBytesPacketHeader;
int numBytesPacketHeader = numBytesForPacketHeader(packet);
unsigned char* startPosition = sourceBuffer;
const unsigned char* startPosition = reinterpret_cast<const unsigned char*>(packet.data());
const unsigned char* sourceBuffer = startPosition + numBytesPacketHeader;
// push past the node session UUID
sourceBuffer += NUM_BYTES_RFC4122_UUID;

View file

@ -20,7 +20,7 @@ typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
typedef unsigned long long quint64;
#define PRId64 "I64d"
#else
#include <inttypes.h>
@ -55,7 +55,7 @@ public:
virtual ~OctreeQuery();
int getBroadcastData(unsigned char* destinationBuffer);
int parseData(unsigned char* sourceBuffer, int numBytes);
int parseData(const QByteArray& packet);
QUuid& getUUID() { return _uuid; }
void setUUID(const QUuid& uuid) { _uuid = uuid; }

View file

@ -36,18 +36,17 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Hifi
unsigned char command = *packetData;
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
PACKET_TYPE expectedType = getExpectedPacketType();
PacketType expectedType = getExpectedPacketType();
if(command == expectedType) {
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PACKET_TYPE",showTimingDetails);
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails);
// if we are getting inbound packets, then our tree is also viewing, and we should remember that fact.
_tree->setIsViewing(true);
const unsigned char* dataAt = packetData + numBytesPacketHeader;
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(dataByteArray.data()) + numBytesPacketHeader;
OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt));
dataAt += sizeof(OCTREE_PACKET_FLAGS);

View file

@ -13,9 +13,9 @@
#include <glm/glm.hpp>
#include <stdint.h>
#include <NodeTypes.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include "Octree.h"
#include "OctreePacketData.h"
#include "ViewFrustum.h"
@ -37,9 +37,9 @@ public:
virtual ~OctreeRenderer();
virtual Octree* createTree() = 0;
virtual NODE_TYPE getMyNodeType() const = 0;
virtual PACKET_TYPE getMyQueryMessageType() const = 0;
virtual PACKET_TYPE getExpectedPacketType() const = 0;
virtual NodeType_t getMyNodeType() const = 0;
virtual PacketType getMyQueryMessageType() const = 0;
virtual PacketType getExpectedPacketType() const = 0;
virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0;
/// process incoming data

View file

@ -379,7 +379,7 @@ void OctreeSceneStats::childBitsRemoved(bool includesExistsBits, bool includesCo
int OctreeSceneStats::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
unsigned char* bufferStart = destinationBuffer;
int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_OCTREE_STATS);
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeOctreeStats);
destinationBuffer += headerLength;
memcpy(destinationBuffer, &_start, sizeof(_start));
@ -476,11 +476,11 @@ int OctreeSceneStats::packIntoMessage(unsigned char* destinationBuffer, int avai
return destinationBuffer - bufferStart; // includes header!
}
int OctreeSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availableBytes) {
unsigned char* startPosition = sourceBuffer;
int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) {
const unsigned char* startPosition = sourceBuffer;
// increment to push past the packet header
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(sourceBuffer));
sourceBuffer += numBytesPacketHeader;
memcpy(&_start, sourceBuffer, sizeof(_start));
@ -691,7 +691,7 @@ OctreeSceneStats::ItemInfo OctreeSceneStats::_ITEMS[] = {
};
const char* OctreeSceneStats::getItemValue(Item item) {
const uint64_t USECS_PER_SECOND = 1000 * 1000;
const quint64 USECS_PER_SECOND = 1000 * 1000;
int calcFPS, calcAverageFPS, calculatedKBPS;
switch(item) {
case ITEM_ELAPSED: {
@ -797,16 +797,16 @@ const char* OctreeSceneStats::getItemValue(Item item) {
return _itemValueBuffer;
}
void OctreeSceneStats::trackIncomingOctreePacket(unsigned char* messageData, ssize_t messageLength,
void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
bool wasStatsPacket, int nodeClockSkewUsec) {
_incomingPacket++;
_incomingBytes += messageLength;
_incomingBytes += packet.size();
if (!wasStatsPacket) {
_incomingWastedBytes += (MAX_PACKET_SIZE - messageLength);
_incomingWastedBytes += (MAX_PACKET_SIZE - packet.size());
}
int numBytesPacketHeader = numBytesForPacketHeader(messageData);
unsigned char* dataAt = messageData + numBytesPacketHeader;
int numBytesPacketHeader = numBytesForPacketHeader(packet);
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
//VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));
dataAt += sizeof(OCTREE_PACKET_FLAGS);

View file

@ -88,7 +88,7 @@ public:
int packIntoMessage(unsigned char* destinationBuffer, int availableBytes);
/// Unpack the details of the statistics from a buffer typically received as a network packet
int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes);
int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes);
/// Indicates that a scene has been completed and the statistics are ready to be sent
bool isReadyToSend() const { return _isReadyToSend; }
@ -153,8 +153,7 @@ public:
unsigned long getLastFullElapsedTime() const { return _lastFullElapsed; }
// Used in client implementations to track individual octree packets
void trackIncomingOctreePacket(unsigned char* messageData, ssize_t messageLength,
bool wasStatsPacket, int nodeClockSkewUsec);
void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec);
unsigned int getIncomingPackets() const { return _incomingPacket; }
unsigned long getIncomingBytes() const { return _incomingBytes; }
@ -173,17 +172,17 @@ private:
// scene timing data in usecs
bool _isStarted;
uint64_t _start;
uint64_t _end;
uint64_t _elapsed;
uint64_t _lastFullElapsed;
quint64 _start;
quint64 _end;
quint64 _elapsed;
quint64 _lastFullElapsed;
SimpleMovingAverage _elapsedAverage;
SimpleMovingAverage _bitsPerOctreeAverage;
uint64_t _totalEncodeTime;
uint64_t _lastFullTotalEncodeTime;
uint64_t _encodeStart;
quint64 _totalEncodeTime;
quint64 _lastFullTotalEncodeTime;
quint64 _encodeStart;
// scene octree related data
unsigned long _totalElements;

View file

@ -29,7 +29,7 @@ public:
void setJurisdictionListener(JurisdictionListener* jurisdictionListener);
void init();
virtual NODE_TYPE getServerNodeType() const = 0;
virtual NodeType_t getServerNodeType() const = 0;
virtual OctreeEditPacketSender* createPacketSender() = 0;
public slots:

View file

@ -19,13 +19,13 @@ public:
OctreeQueryNode(),
_lastDeletedParticlesSentAt(0) { };
virtual PACKET_TYPE getMyPacketType() const { return PACKET_TYPE_PARTICLE_DATA; }
virtual PacketType getMyPacketType() const { return PacketTypeParticleData; }
uint64_t getLastDeletedParticlesSentAt() const { return _lastDeletedParticlesSentAt; }
void setLastDeletedParticlesSentAt(uint64_t sentAt) { _lastDeletedParticlesSentAt = sentAt; }
quint64 getLastDeletedParticlesSentAt() const { return _lastDeletedParticlesSentAt; }
void setLastDeletedParticlesSentAt(quint64 sentAt) { _lastDeletedParticlesSentAt = sentAt; }
private:
uint64_t _lastDeletedParticlesSentAt;
quint64 _lastDeletedParticlesSentAt;
};
#endif /* defined(__hifi__ParticleNodeData__) */

View file

@ -17,7 +17,7 @@ const char* PARTICLE_SERVER_NAME = "Particle";
const char* PARTICLE_SERVER_LOGGING_TARGET_NAME = "particle-server";
const char* LOCAL_PARTICLES_PERSIST_FILE = "resources/particles.svo";
ParticleServer::ParticleServer(const unsigned char* dataBuffer, int numBytes) : OctreeServer(dataBuffer, numBytes) {
ParticleServer::ParticleServer(const QByteArray& packet) : OctreeServer(packet) {
// nothing special to do here...
}
@ -47,7 +47,7 @@ void ParticleServer::particleCreated(const Particle& newParticle, Node* node) {
unsigned char outputBuffer[MAX_PACKET_SIZE];
unsigned char* copyAt = outputBuffer;
int numBytesPacketHeader = populateTypeAndVersion(outputBuffer, PACKET_TYPE_PARTICLE_ADD_RESPONSE);
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeParticleAddResponse);
int packetLength = numBytesPacketHeader;
copyAt += numBytesPacketHeader;
@ -76,7 +76,7 @@ bool ParticleServer::hasSpecialPacketToSend(Node* node) {
// check to see if any new particles have been added since we last sent to this node...
ParticleNodeData* nodeData = static_cast<ParticleNodeData*>(node->getLinkedData());
if (nodeData) {
uint64_t deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
quint64 deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
ParticleTree* tree = static_cast<ParticleTree*>(_tree);
shouldSendDeletedParticles = tree->hasParticlesDeletedSince(deletedParticlesSentAt);
@ -91,8 +91,8 @@ int ParticleServer::sendSpecialPacket(Node* node) {
ParticleNodeData* nodeData = static_cast<ParticleNodeData*>(node->getLinkedData());
if (nodeData) {
uint64_t deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
uint64_t deletePacketSentAt = usecTimestampNow();
quint64 deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
quint64 deletePacketSentAt = usecTimestampNow();
ParticleTree* tree = static_cast<ParticleTree*>(_tree);
bool hasMoreToSend = true;
@ -102,7 +102,7 @@ int ParticleServer::sendSpecialPacket(Node* node) {
hasMoreToSend = tree->encodeParticlesDeletedSince(deletedParticlesSentAt,
outputBuffer, MAX_PACKET_SIZE, packetLength);
//qDebug() << "sending PACKET_TYPE_PARTICLE_ERASE packetLength:" << packetLength;
//qDebug() << "sending PacketType_PARTICLE_ERASE packetLength:" << packetLength;
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) outputBuffer, packetLength,
node->getActiveSocket()->getAddress(),
@ -121,11 +121,11 @@ void ParticleServer::pruneDeletedParticles() {
if (tree->hasAnyDeletedParticles()) {
//qDebug() << "there are some deleted particles to consider...";
uint64_t earliestLastDeletedParticlesSent = usecTimestampNow() + 1; // in the future
quint64 earliestLastDeletedParticlesSent = usecTimestampNow() + 1; // in the future
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
if (otherNode->getLinkedData()) {
ParticleNodeData* nodeData = static_cast<ParticleNodeData*>(otherNode->getLinkedData());
uint64_t nodeLastDeletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
quint64 nodeLastDeletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
if (nodeLastDeletedParticlesSentAt < earliestLastDeletedParticlesSent) {
earliestLastDeletedParticlesSent = nodeLastDeletedParticlesSentAt;
}

View file

@ -20,14 +20,14 @@
class ParticleServer : public OctreeServer, public NewlyCreatedParticleHook {
Q_OBJECT
public:
ParticleServer(const unsigned char* dataBuffer, int numBytes);
ParticleServer(const QByteArray& packet);
~ParticleServer();
// Subclasses must implement these methods
virtual OctreeQueryNode* createOctreeQueryNode();
virtual Octree* createTree();
virtual unsigned char getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; }
virtual PACKET_TYPE getMyQueryMessageType() const { return PACKET_TYPE_PARTICLE_QUERY; }
virtual unsigned char getMyNodeType() const { return NodeType::ParticleServer; }
virtual PacketType getMyQueryMessageType() const { return PacketTypeParticleQuery; }
virtual const char* getMyServerName() const { return PARTICLE_SERVER_NAME; }
virtual const char* getMyLoggingServerTargetName() const { return PARTICLE_SERVER_LOGGING_TARGET_NAME; }
virtual const char* getMyDefaultPersistFilename() const { return LOCAL_PARTICLES_PERSIST_FILE; }

View file

@ -45,9 +45,9 @@ uint32_t Particle::getNextCreatorTokenID() {
return creatorTokenID;
}
void Particle::handleAddParticleResponse(unsigned char* packetData , int packetLength) {
unsigned char* dataAt = packetData;
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
void Particle::handleAddParticleResponse(const QByteArray& packet) {
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data());
int numBytesPacketHeader = numBytesForPacketHeader(packet);
dataAt += numBytesPacketHeader;
uint32_t creatorTokenID;
@ -64,7 +64,6 @@ void Particle::handleAddParticleResponse(unsigned char* packetData , int packetL
_tokenIDsToIDs[creatorTokenID] = particleID;
}
Particle::Particle() {
rgbColor noColor = { 0, 0, 0 };
init(glm::vec3(0,0,0), 0, noColor, glm::vec3(0,0,0),
@ -109,7 +108,7 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3
} else {
_id = id;
}
uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
_lastEdited = now;
_lastUpdated = now;
_created = now; // will get updated as appropriate in setAge()
@ -210,8 +209,8 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
int Particle::expectedBytes() {
int expectedBytes = sizeof(uint32_t) // id
+ sizeof(float) // age
+ sizeof(uint64_t) // last updated
+ sizeof(uint64_t) // lasted edited
+ sizeof(quint64) // last updated
+ sizeof(quint64) // lasted edited
+ sizeof(float) // radius
+ sizeof(glm::vec3) // position
+ sizeof(rgbColor) // color
@ -340,10 +339,10 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
return bytesRead;
}
Particle Particle::fromEditPacket(const unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid) {
Particle Particle::fromEditPacket(unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid) {
Particle newParticle; // id and _lastUpdated will get set here...
unsigned char* dataAt = data;
const unsigned char* dataAt = data;
processedBytes = 0;
// the first part of the data is our octcode...
@ -546,7 +545,7 @@ void Particle::debugDump() const {
printf(" color:%d,%d,%d\n", _color[0], _color[1], _color[2]);
}
bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID id, const ParticleProperties& properties,
bool Particle::encodeParticleEditMessageDetails(PacketType command, ParticleID id, const ParticleProperties& properties,
unsigned char* bufferOut, int sizeIn, int& sizeOut) {
bool success = true; // assume the best
@ -591,13 +590,13 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
copyAt += sizeof(id.creatorTokenID);
sizeOut += sizeof(id.creatorTokenID);
}
// lastEdited
uint64_t lastEdited = properties.getLastEdited();
quint64 lastEdited = properties.getLastEdited();
memcpy(copyAt, &lastEdited, sizeof(lastEdited));
copyAt += sizeof(lastEdited);
sizeOut += sizeof(lastEdited);
// For new particles, all remaining items are mandatory, for an edited particle, All of the remaining items are
// optional, and may or may not be included based on their included values in the properties included bits
uint16_t packetContainsBits = properties.getChangedBits();
@ -758,9 +757,9 @@ void Particle::adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssiz
}
// lastEdited
uint64_t lastEditedInLocalTime;
quint64 lastEditedInLocalTime;
memcpy(&lastEditedInLocalTime, dataAt, sizeof(lastEditedInLocalTime));
uint64_t lastEditedInServerTime = lastEditedInLocalTime + clockSkew;
quint64 lastEditedInServerTime = lastEditedInLocalTime + clockSkew;
memcpy(dataAt, &lastEditedInServerTime, sizeof(lastEditedInServerTime));
const bool wantDebug = false;
if (wantDebug) {
@ -818,14 +817,14 @@ void Particle::applyHardCollision(const CollisionInfo& collisionInfo) {
const float MIN_EXPECTED_FRAME_PERIOD = 0.005f; // 1/200th of a second
const float MIN_VALID_SPEED = 9.8 * MIN_EXPECTED_FRAME_PERIOD / (float)(TREE_SCALE);
void Particle::update(const uint64_t& now) {
void Particle::update(const quint64& now) {
float timeElapsed = (float)(now - _lastUpdated) / (float)(USECS_PER_SECOND);
_lastUpdated = now;
// calculate our default shouldDie state... then allow script to change it if it wants...
float speed = glm::length(_velocity);
bool isStopped = (speed < MIN_VALID_SPEED);
const uint64_t REALLY_OLD = 30 * USECS_PER_SECOND; // 30 seconds
const quint64 REALLY_OLD = 30 * USECS_PER_SECOND; // 30 seconds
bool isReallyOld = ((now - _created) > REALLY_OLD);
bool isInHand = getInHand();
bool shouldDie = (getAge() > getLifetime()) || getShouldDie() || (!isInHand && isStopped && isReallyOld);
@ -954,7 +953,7 @@ void Particle::collisionWithVoxel(VoxelDetail* voxelDetails) {
void Particle::setAge(float age) {
uint64_t ageInUsecs = age * USECS_PER_SECOND;
quint64 ageInUsecs = age * USECS_PER_SECOND;
_created = usecTimestampNow() - ageInUsecs;
}

View file

@ -89,7 +89,7 @@ public:
const glm::quat& getModelRotation() const { return _modelRotation; }
float getModelScale() const { return _modelScale; }
uint64_t getLastEdited() const { return _lastEdited; }
quint64 getLastEdited() const { return _lastEdited; }
uint16_t getChangedBits() const;
/// set position in meter units
@ -136,7 +136,7 @@ private:
uint32_t _id;
bool _idSet;
uint64_t _lastEdited;
quint64 _lastEdited;
bool _positionChanged;
bool _colorChanged;
@ -194,7 +194,7 @@ public:
Particle(const ParticleID& particleID, const ParticleProperties& properties);
/// creates an NEW particle from an PACKET_TYPE_PARTICLE_ADD_OR_EDIT edit data buffer
static Particle fromEditPacket(unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid);
static Particle fromEditPacket(const unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid);
virtual ~Particle();
virtual void init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity,
@ -231,11 +231,11 @@ public:
ParticleProperties getProperties() const;
/// The last updated/simulated time of this particle from the time perspective of the authoritative server/source
uint64_t getLastUpdated() const { return _lastUpdated; }
quint64 getLastUpdated() const { return _lastUpdated; }
/// The last edited time of this particle from the time perspective of the authoritative server/source
uint64_t getLastEdited() const { return _lastEdited; }
void setLastEdited(uint64_t lastEdited) { _lastEdited = lastEdited; }
quint64 getLastEdited() const { return _lastEdited; }
void setLastEdited(quint64 lastEdited) { _lastEdited = lastEdited; }
/// lifetime of the particle in seconds
float getAge() const { return static_cast<float>(usecTimestampNow() - _created) / static_cast<float>(USECS_PER_SECOND); }
@ -283,14 +283,14 @@ public:
int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
static int expectedBytes();
static bool encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID id, const ParticleProperties& details,
static bool encodeParticleEditMessageDetails(PacketType command, ParticleID id, const ParticleProperties& details,
unsigned char* bufferOut, int sizeIn, int& sizeOut);
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
void applyHardCollision(const CollisionInfo& collisionInfo);
void update(const uint64_t& now);
void update(const quint64& now);
void collisionWithParticle(Particle* other);
void collisionWithVoxel(VoxelDetail* voxel);
@ -312,7 +312,7 @@ public:
// these methods allow you to create particles, and later edit them.
static uint32_t getIDfromCreatorTokenID(uint32_t creatorTokenID);
static uint32_t getNextCreatorTokenID();
static void handleAddParticleResponse(unsigned char* packetData , int packetLength);
static void handleAddParticleResponse(const QByteArray& packet);
protected:
static VoxelEditPacketSender* _voxelEditSender;
@ -349,11 +349,11 @@ protected:
uint32_t _creatorTokenID;
bool _newlyCreated;
uint64_t _lastUpdated;
uint64_t _lastEdited;
quint64 _lastUpdated;
quint64 _lastEdited;
// this doesn't go on the wire, we send it as lifetime
uint64_t _created;
quint64 _created;
// used by the static interfaces for creator token ids
static uint32_t _nextCreatorTokenID;

View file

@ -127,7 +127,7 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
ParticleID particleAid(particleA->getID());
propertiesA.copyFromParticle(*particleA);
propertiesA.setVelocity(particleA->getVelocity() * (float)TREE_SCALE);
_packetSender->queueParticleEditMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleAid, propertiesA);
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleAid, propertiesA);
// handle B particle
particleB->setVelocity(particleB->getVelocity() + axialVelocity * (2.0f * massA / totalMass));
@ -135,7 +135,7 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
ParticleID particleBid(particleB->getID());
propertiesB.copyFromParticle(*particleB);
propertiesB.setVelocity(particleB->getVelocity() * (float)TREE_SCALE);
_packetSender->queueParticleEditMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleBid, propertiesB);
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleBid, propertiesB);
_packetSender->releaseQueuedMessages();
@ -202,9 +202,10 @@ void ParticleCollisionSystem::queueParticlePropertiesUpdate(Particle* particle)
ParticleProperties properties;
ParticleID particleID(particle->getID());
properties.copyFromParticle(*particle);
properties.setPosition(particle->getPosition() * (float)TREE_SCALE);
properties.setVelocity(particle->getVelocity() * (float)TREE_SCALE);
_packetSender->queueParticleEditMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleID, properties);
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleID, properties);
}

View file

@ -16,7 +16,7 @@
#include "Particle.h"
void ParticleEditPacketSender::sendEditParticleMessage(PACKET_TYPE type, ParticleID particleID, const ParticleProperties& properties) {
void ParticleEditPacketSender::sendEditParticleMessage(PacketType type, ParticleID particleID, const ParticleProperties& properties) {
// allows app to disable sending if for example voxels have been disabled
if (!_shouldSend) {
return; // bail early
@ -42,7 +42,7 @@ void ParticleEditPacketSender::adjustEditPacketForClockSkew(unsigned char* codeC
}
void ParticleEditPacketSender::queueParticleEditMessage(PACKET_TYPE type, ParticleID particleID,
void ParticleEditPacketSender::queueParticleEditMessage(PacketType type, ParticleID particleID,
const ParticleProperties& properties) {
if (!_shouldSend) {
return; // bail early

View file

@ -20,16 +20,16 @@ class ParticleEditPacketSender : public OctreeEditPacketSender {
public:
/// Send particle add message immediately
/// NOTE: ParticleProperties assumes that all distances are in meter units
void sendEditParticleMessage(PACKET_TYPE type, ParticleID particleID, const ParticleProperties& properties);
void sendEditParticleMessage(PacketType type, ParticleID particleID, const ParticleProperties& properties);
/// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines
/// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in
/// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known.
/// NOTE: ParticleProperties assumes that all distances are in meter units
void queueParticleEditMessage(PACKET_TYPE type, ParticleID particleID, const ParticleProperties& properties);
void queueParticleEditMessage(PacketType type, ParticleID particleID, const ParticleProperties& properties);
// My server type is the particle server
virtual unsigned char getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; }
virtual unsigned char getMyNodeType() const { return NodeType::ParticleServer; }
virtual void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
};
#endif // __shared__ParticleEditPacketSender__

View file

@ -19,14 +19,15 @@ ParticleTreeElement* ParticleTree::createNewElement(unsigned char * octalCode) {
return newElement;
}
bool ParticleTree::handlesEditPacketType(PACKET_TYPE packetType) const {
bool ParticleTree::handlesEditPacketType(PacketType packetType) const {
// we handle these types of "edit" packets
switch (packetType) {
case PACKET_TYPE_PARTICLE_ADD_OR_EDIT:
case PACKET_TYPE_PARTICLE_ERASE:
case PacketTypeParticleAddOrEdit:
case PacketTypeParticleErase:
return true;
default:
return false;
}
return false;
}
class FindAndDeleteParticlesArgs {
@ -185,9 +186,10 @@ bool ParticleTree::findAndUpdateParticleIDOperation(OctreeElement* element, void
return keepSearching;
}
void ParticleTree::handleAddParticleResponse(unsigned char* packetData , int packetLength) {
unsigned char* dataAt = packetData;
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
void ParticleTree::handleAddParticleResponse(const QByteArray& packet) {
int numBytesPacketHeader = numBytesForPacketHeader(packet);
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
dataAt += numBytesPacketHeader;
uint32_t creatorTokenID;
@ -384,13 +386,13 @@ const Particle* ParticleTree::findParticleByID(uint32_t id, bool alreadyLocked)
}
int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
unsigned char* editData, int maxLength, Node* senderNode) {
int ParticleTree::processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
const unsigned char* editData, int maxLength, Node* senderNode) {
int processedBytes = 0;
// we handle these types of "edit" packets
switch (packetType) {
case PACKET_TYPE_PARTICLE_ADD_OR_EDIT: {
case PacketTypeParticleAddOrEdit: {
bool isValid;
Particle newParticle = Particle::fromEditPacket(editData, maxLength, processedBytes, this, isValid);
if (isValid) {
@ -403,10 +405,14 @@ int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* p
// TODO: wire in support here for server to get PACKET_TYPE_PARTICLE_ERASE messages
// instead of using PACKET_TYPE_PARTICLE_ADD_OR_EDIT messages to delete particles
case PACKET_TYPE_PARTICLE_ERASE: {
case PacketTypeParticleErase:
processedBytes = 0;
} break;
break;
default:
processedBytes = 0;
break;
}
return processedBytes;
}
@ -472,7 +478,7 @@ void ParticleTree::update() {
storeParticle(args._movingParticles[i]);
} else {
uint32_t particleID = args._movingParticles[i].getID();
uint64_t deletedAt = usecTimestampNow();
quint64 deletedAt = usecTimestampNow();
_recentlyDeletedParticlesLock.lockForWrite();
_recentlyDeletedParticleIDs.insert(deletedAt, particleID);
_recentlyDeletedParticlesLock.unlock();
@ -484,12 +490,12 @@ void ParticleTree::update() {
}
bool ParticleTree::hasParticlesDeletedSince(uint64_t sinceTime) {
bool ParticleTree::hasParticlesDeletedSince(quint64 sinceTime) {
// we can probably leverage the ordered nature of QMultiMap to do this quickly...
bool hasSomethingNewer = false;
_recentlyDeletedParticlesLock.lockForRead();
QMultiMap<uint64_t, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
QMultiMap<quint64, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
while (iterator != _recentlyDeletedParticleIDs.constEnd()) {
//qDebug() << "considering... time/key:" << iterator.key();
if (iterator.key() > sinceTime) {
@ -503,13 +509,13 @@ bool ParticleTree::hasParticlesDeletedSince(uint64_t sinceTime) {
}
// sinceTime is an in/out parameter - it will be side effected with the last time sent out
bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned char* outputBuffer, size_t maxLength,
bool ParticleTree::encodeParticlesDeletedSince(quint64& sinceTime, unsigned char* outputBuffer, size_t maxLength,
size_t& outputLength) {
bool hasMoreToSend = true;
unsigned char* copyAt = outputBuffer;
size_t numBytesPacketHeader = populateTypeAndVersion(outputBuffer, PACKET_TYPE_PARTICLE_ERASE);
size_t numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeParticleErase);
copyAt += numBytesPacketHeader;
outputLength = numBytesPacketHeader;
@ -522,7 +528,7 @@ bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned cha
// we keep a multi map of particle IDs to timestamps, we only want to include the particle IDs that have been
// deleted since we last sent to this node
_recentlyDeletedParticlesLock.lockForRead();
QMultiMap<uint64_t, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
QMultiMap<quint64, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
while (iterator != _recentlyDeletedParticleIDs.constEnd()) {
QList<uint32_t> values = _recentlyDeletedParticleIDs.values(iterator.key());
for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
@ -565,13 +571,15 @@ bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned cha
}
// called by the server when it knows all nodes have been sent deleted packets
void ParticleTree::forgetParticlesDeletedBefore(uint64_t sinceTime) {
QSet<uint64_t> keysToRemove;
void ParticleTree::forgetParticlesDeletedBefore(quint64 sinceTime) {
//qDebug() << "forgetParticlesDeletedBefore()";
QSet<quint64> keysToRemove;
_recentlyDeletedParticlesLock.lockForWrite();
QMultiMap<uint64_t, uint32_t>::iterator iterator = _recentlyDeletedParticleIDs.begin();
QMultiMap<quint64, uint32_t>::iterator iterator = _recentlyDeletedParticleIDs.begin();
// First find all the keys in the map that are older and need to be deleted
// First find all the keys in the map that are older and need to be deleted
while (iterator != _recentlyDeletedParticleIDs.end()) {
if (iterator.key() <= sinceTime) {
keysToRemove << iterator.key();
@ -579,8 +587,9 @@ void ParticleTree::forgetParticlesDeletedBefore(uint64_t sinceTime) {
++iterator;
}
// Now run through the keysToRemove and remove them
foreach (uint64_t value, keysToRemove) {
// Now run through the keysToRemove and remove them
foreach (quint64 value, keysToRemove) {
//qDebug() << "removing the key, _recentlyDeletedParticleIDs.remove(value); time/key:" << value;
_recentlyDeletedParticleIDs.remove(value);
}
@ -595,7 +604,7 @@ void ParticleTree::processEraseMessage(const QByteArray& dataByteArray, const Hi
const unsigned char* dataAt = packetData;
size_t packetLength = dataByteArray.size();
size_t numBytesPacketHeader = numBytesForPacketHeader(packetData);
size_t numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
size_t processedBytes = numBytesPacketHeader;
dataAt += numBytesPacketHeader;

View file

@ -32,10 +32,10 @@ public:
// These methods will allow the OctreeServer to send your tree inbound edit packets of your
// own definition. Implement these to allow your octree based server to support editing
virtual bool getWantSVOfileVersions() const { return true; }
virtual PACKET_TYPE expectedDataPacketType() const { return PACKET_TYPE_PARTICLE_DATA; }
virtual bool handlesEditPacketType(PACKET_TYPE packetType) const;
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
unsigned char* editData, int maxLength, Node* senderNode);
virtual PacketType expectedDataPacketType() const { return PacketTypeParticleData; }
virtual bool handlesEditPacketType(PacketType packetType) const;
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
const unsigned char* editData, int maxLength, Node* senderNode);
virtual void update();
@ -63,12 +63,12 @@ public:
void removeNewlyCreatedHook(NewlyCreatedParticleHook* hook);
bool hasAnyDeletedParticles() const { return _recentlyDeletedParticleIDs.size() > 0; }
bool hasParticlesDeletedSince(uint64_t sinceTime);
bool encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned char* packetData, size_t maxLength, size_t& outputLength);
void forgetParticlesDeletedBefore(uint64_t sinceTime);
bool hasParticlesDeletedSince(quint64 sinceTime);
bool encodeParticlesDeletedSince(quint64& sinceTime, unsigned char* packetData, size_t maxLength, size_t& outputLength);
void forgetParticlesDeletedBefore(quint64 sinceTime);
void processEraseMessage(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr, Node* sourceNode);
void handleAddParticleResponse(unsigned char* packetData , int packetLength);
void handleAddParticleResponse(const QByteArray& packet);
private:
@ -89,7 +89,7 @@ private:
QReadWriteLock _recentlyDeletedParticlesLock;
QMultiMap<uint64_t, uint32_t> _recentlyDeletedParticleIDs;
QMultiMap<quint64, uint32_t> _recentlyDeletedParticleIDs;
};
#endif /* defined(__hifi__ParticleTree__) */

View file

@ -16,7 +16,7 @@ ParticlesScriptingInterface::ParticlesScriptingInterface() :
}
void ParticlesScriptingInterface::queueParticleMessage(PACKET_TYPE packetType,
void ParticlesScriptingInterface::queueParticleMessage(PacketType packetType,
ParticleID particleID, const ParticleProperties& properties) {
getParticlePacketSender()->queueParticleEditMessage(packetType, particleID, properties);
}
@ -29,7 +29,7 @@ ParticleID ParticlesScriptingInterface::addParticle(const ParticleProperties& pr
ParticleID id(NEW_PARTICLE, creatorTokenID, false );
// queue the packet
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, id, properties);
queueParticleMessage(PacketTypeParticleAddOrEdit, id, properties);
// If we have a local particle tree set, then also update it.
if (_particleTree) {
@ -87,7 +87,7 @@ ParticleID ParticlesScriptingInterface::editParticle(ParticleID particleID, cons
if (actualID != UNKNOWN_PARTICLE_ID) {
particleID.id = actualID;
particleID.isKnownID = true;
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleID, properties);
queueParticleMessage(PacketTypeParticleAddOrEdit, particleID, properties);
}
// If we have a local particle tree set, then also update it. We can do this even if we don't know
@ -97,13 +97,14 @@ ParticleID ParticlesScriptingInterface::editParticle(ParticleID particleID, cons
_particleTree->updateParticle(particleID, properties);
_particleTree->unlock();
}
return particleID;
}
// TODO: This deleteParticle() method uses the PACKET_TYPE_PARTICLE_ADD_OR_EDIT message to send
// TODO: This deleteParticle() method uses the PacketType_PARTICLE_ADD_OR_EDIT message to send
// a changed particle with a shouldDie() property set to true. This works and is currently the only
// way to tell the particle server to delete a particle. But we should change this to use the PACKET_TYPE_PARTICLE_ERASE
// way to tell the particle server to delete a particle. But we should change this to use the PacketType_PARTICLE_ERASE
// message which takes a list of particle id's to delete.
void ParticlesScriptingInterface::deleteParticle(ParticleID particleID) {
@ -126,7 +127,7 @@ void ParticlesScriptingInterface::deleteParticle(ParticleID particleID) {
particleID.isKnownID = true;
//qDebug() << "ParticlesScriptingInterface::deleteParticle(), queueParticleMessage......";
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleID, properties);
queueParticleMessage(PacketTypeParticleAddOrEdit, particleID, properties);
// If we have a local particle tree set, then also update it.
if (_particleTree) {

Some files were not shown because too many files have changed in this diff Show more