mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 19:24:32 +02:00
move voxel receiving into class
This commit is contained in:
parent
6e2e58a1e4
commit
70344cdaf2
6 changed files with 213 additions and 91 deletions
|
@ -216,7 +216,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
|
||||
#endif
|
||||
_stopNetworkReceiveThread(false),
|
||||
_stopProcessVoxelsThread(false),
|
||||
_voxelReceiver(this),
|
||||
_packetCount(0),
|
||||
_packetsPerSecond(0),
|
||||
_bytesPerSecond(0),
|
||||
|
@ -368,9 +368,9 @@ void Application::initializeGL() {
|
|||
}
|
||||
|
||||
// create thread for parsing of voxel data independent of the main network and rendering threads
|
||||
_voxelReceiver.initialize(_enableProcessVoxelsThread);
|
||||
if (_enableProcessVoxelsThread) {
|
||||
pthread_create(&_processVoxelsThread, NULL, processVoxels, NULL);
|
||||
qDebug("Voxel parsing thread created.\n");
|
||||
qDebug("Voxel parsing thread created.\n");
|
||||
}
|
||||
|
||||
// call terminate before exiting
|
||||
|
@ -1178,10 +1178,7 @@ void Application::terminate() {
|
|||
pthread_join(_networkReceiveThread, NULL);
|
||||
}
|
||||
|
||||
if (_enableProcessVoxelsThread) {
|
||||
_stopProcessVoxelsThread = true;
|
||||
pthread_join(_processVoxelsThread, NULL);
|
||||
}
|
||||
_voxelReceiver.terminate();
|
||||
}
|
||||
|
||||
void Application::sendAvatarVoxelURLMessage(const QUrl& url) {
|
||||
|
@ -2580,7 +2577,7 @@ void Application::update(float deltaTime) {
|
|||
|
||||
// parse voxel packets
|
||||
if (!_enableProcessVoxelsThread) {
|
||||
processVoxels(0);
|
||||
_voxelReceiver.threadRoutine();
|
||||
}
|
||||
|
||||
//loop through all the other avatars and simulate them...
|
||||
|
@ -4034,75 +4031,6 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
|
|||
return statsMessageLength;
|
||||
}
|
||||
|
||||
// Receive packets from other nodes/servers and decide what to do with them!
|
||||
void* Application::processVoxels(void* args) {
|
||||
Application* app = Application::getInstance();
|
||||
while (!app->_stopProcessVoxelsThread) {
|
||||
|
||||
// check to see if the UI thread asked us to kill the voxel tree. since we're the only thread allowed to do that
|
||||
if (app->_wantToKillLocalVoxels) {
|
||||
app->_voxels.killLocalVoxels();
|
||||
app->_wantToKillLocalVoxels = false;
|
||||
}
|
||||
|
||||
while (app->_voxelPackets.size() > 0) {
|
||||
NetworkPacket& packet = app->_voxelPackets.front();
|
||||
app->processVoxelPacket(packet.getSenderAddress(), packet.getData(), packet.getLength());
|
||||
app->_voxelPackets.erase(app->_voxelPackets.begin());
|
||||
}
|
||||
|
||||
if (!app->_enableProcessVoxelsThread) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (app->_enableProcessVoxelsThread) {
|
||||
pthread_exit(0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Application::queueVoxelPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
_voxelPackets.push_back(NetworkPacket(senderAddress, packetData, packetLength));
|
||||
}
|
||||
|
||||
void Application::processVoxelPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
PerformanceWarning warn(_renderPipelineWarnings->isChecked(),"processVoxelPacket()");
|
||||
ssize_t messageLength = packetLength;
|
||||
|
||||
// note: PACKET_TYPE_VOXEL_STATS can have PACKET_TYPE_VOXEL_DATA or PACKET_TYPE_VOXEL_DATA_MONOCHROME
|
||||
// immediately following them inside the same packet. So, we process the PACKET_TYPE_VOXEL_STATS first
|
||||
// then process any remaining bytes as if it was another packet
|
||||
if (packetData[0] == PACKET_TYPE_VOXEL_STATS) {
|
||||
|
||||
int statsMessageLength = parseVoxelStats(packetData, messageLength, senderAddress);
|
||||
if (messageLength > statsMessageLength) {
|
||||
packetData += statsMessageLength;
|
||||
messageLength -= statsMessageLength;
|
||||
if (!packetVersionMatch(packetData)) {
|
||||
return; // bail since piggyback data doesn't match our versioning
|
||||
}
|
||||
} else {
|
||||
return; // bail since no piggyback data
|
||||
}
|
||||
} // fall through to piggyback message
|
||||
|
||||
if (_renderVoxels->isChecked()) {
|
||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
if (voxelServer && socketMatch(voxelServer->getActiveSocket(), &senderAddress)) {
|
||||
voxelServer->lock();
|
||||
if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) {
|
||||
_environment.parseData(&senderAddress, packetData, messageLength);
|
||||
} else {
|
||||
_voxels.setDataSourceID(voxelServer->getNodeID());
|
||||
_voxels.parseData(packetData, messageLength);
|
||||
_voxels.setDataSourceID(UNKNOWN_NODE_ID);
|
||||
}
|
||||
voxelServer->unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive packets from other nodes/servers and decide what to do with them!
|
||||
void* Application::networkReceive(void* args) {
|
||||
sockaddr senderAddress;
|
||||
|
@ -4110,12 +4038,6 @@ void* Application::networkReceive(void* args) {
|
|||
|
||||
Application* app = Application::getInstance();
|
||||
while (!app->_stopNetworkReceiveThread) {
|
||||
// check to see if the UI thread asked us to kill the voxel tree. since we're the only thread allowed to do that
|
||||
if (app->_wantToKillLocalVoxels) {
|
||||
app->_voxels.killLocalVoxels();
|
||||
app->_wantToKillLocalVoxels = false;
|
||||
}
|
||||
|
||||
if (NodeList::getInstance()->getNodeSocket()->receive(&senderAddress, app->_incomingPacket, &bytesReceived)) {
|
||||
|
||||
app->_packetCount++;
|
||||
|
@ -4139,7 +4061,7 @@ void* Application::networkReceive(void* args) {
|
|||
case PACKET_TYPE_VOXEL_STATS:
|
||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||
// add this packet to our list of voxel packets and process them on the voxel processing
|
||||
app->queueVoxelPacket(senderAddress, app->_incomingPacket, bytesReceived);
|
||||
app->_voxelReceiver.queuePacket(senderAddress, app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_BULK_AVATAR_DATA:
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "ToolsPalette.h"
|
||||
#include "ViewFrustum.h"
|
||||
#include "VoxelFade.h"
|
||||
#include "VoxelPacketReceiver.h"
|
||||
#include "VoxelSystem.h"
|
||||
#include "Webcam.h"
|
||||
#include "PieMenu.h"
|
||||
|
@ -72,6 +73,8 @@ static const float NODE_KILLED_BLUE = 0.0f;
|
|||
class Application : public QApplication, public NodeListHook {
|
||||
Q_OBJECT
|
||||
|
||||
friend class VoxelPacketReceiver;
|
||||
|
||||
public:
|
||||
static Application* getInstance() { return static_cast<Application*>(QCoreApplication::instance()); }
|
||||
|
||||
|
@ -263,10 +266,6 @@ private:
|
|||
static void attachNewHeadToNode(Node *newNode);
|
||||
static void* networkReceive(void* args); // network receive thread
|
||||
|
||||
static void* processVoxels(void* args); // voxel parsing thread
|
||||
void processVoxelPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
void queueVoxelPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
// methodes handling menu settings
|
||||
typedef void(*settingsAction)(QSettings*, QAction*);
|
||||
static void loadAction(QSettings* set, QAction* action);
|
||||
|
@ -457,9 +456,7 @@ private:
|
|||
bool _stopNetworkReceiveThread;
|
||||
|
||||
bool _enableProcessVoxelsThread;
|
||||
pthread_t _processVoxelsThread;
|
||||
bool _stopProcessVoxelsThread;
|
||||
std::vector<NetworkPacket> _voxelPackets;
|
||||
VoxelPacketReceiver _voxelReceiver;
|
||||
|
||||
|
||||
unsigned char _incomingPacket[MAX_PACKET_SIZE];
|
||||
|
|
62
interface/src/VoxelPacketReceiver.cpp
Normal file
62
interface/src/VoxelPacketReceiver.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// VoxelPacketReceiver.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Threaded or non-threaded voxel packet receiver for the Application
|
||||
//
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "VoxelPacketReceiver.h"
|
||||
|
||||
VoxelPacketReceiver::VoxelPacketReceiver(Application* app) :
|
||||
_app(app) {
|
||||
}
|
||||
|
||||
void VoxelPacketReceiver::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
PerformanceWarning warn(_app->_renderPipelineWarnings->isChecked(),"processVoxelPacket()");
|
||||
ssize_t messageLength = packetLength;
|
||||
|
||||
// check to see if the UI thread asked us to kill the voxel tree. since we're the only thread allowed to do that
|
||||
if (_app->_wantToKillLocalVoxels) {
|
||||
_app->_voxels.killLocalVoxels();
|
||||
_app->_wantToKillLocalVoxels = false;
|
||||
}
|
||||
|
||||
// note: PACKET_TYPE_VOXEL_STATS can have PACKET_TYPE_VOXEL_DATA or PACKET_TYPE_VOXEL_DATA_MONOCHROME
|
||||
// immediately following them inside the same packet. So, we process the PACKET_TYPE_VOXEL_STATS first
|
||||
// then process any remaining bytes as if it was another packet
|
||||
if (packetData[0] == PACKET_TYPE_VOXEL_STATS) {
|
||||
|
||||
int statsMessageLength = _app->parseVoxelStats(packetData, messageLength, senderAddress);
|
||||
if (messageLength > statsMessageLength) {
|
||||
packetData += statsMessageLength;
|
||||
messageLength -= statsMessageLength;
|
||||
if (!packetVersionMatch(packetData)) {
|
||||
return; // bail since piggyback data doesn't match our versioning
|
||||
}
|
||||
} else {
|
||||
return; // bail since no piggyback data
|
||||
}
|
||||
} // fall through to piggyback message
|
||||
|
||||
if (_app->_renderVoxels->isChecked()) {
|
||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
if (voxelServer && socketMatch(voxelServer->getActiveSocket(), &senderAddress)) {
|
||||
voxelServer->lock();
|
||||
if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) {
|
||||
_app->_environment.parseData(&senderAddress, packetData, messageLength);
|
||||
} else {
|
||||
_app->_voxels.setDataSourceID(voxelServer->getNodeID());
|
||||
_app->_voxels.parseData(packetData, messageLength);
|
||||
_app->_voxels.setDataSourceID(UNKNOWN_NODE_ID);
|
||||
}
|
||||
voxelServer->unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
interface/src/VoxelPacketReceiver.h
Normal file
26
interface/src/VoxelPacketReceiver.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// VoxelPacketReceiver.h
|
||||
// interface
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Voxel Packet Receiver
|
||||
//
|
||||
|
||||
#ifndef __shared__VoxelPacketReceiver__
|
||||
#define __shared__VoxelPacketReceiver__
|
||||
|
||||
#include <PacketReceiver.h>
|
||||
|
||||
class Application;
|
||||
|
||||
class VoxelPacketReceiver : public PacketReceiver {
|
||||
public:
|
||||
VoxelPacketReceiver(Application* app);
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
private:
|
||||
Application* _app;
|
||||
};
|
||||
#endif // __shared__VoxelPacketReceiver__
|
70
libraries/shared/src/PacketReceiver.cpp
Normal file
70
libraries/shared/src/PacketReceiver.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// PacketReceiver.cpp
|
||||
// shared
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Threaded or non-threaded packet receiver.
|
||||
//
|
||||
|
||||
#include "PacketReceiver.h"
|
||||
|
||||
PacketReceiver::PacketReceiver() :
|
||||
_stopThread(false),
|
||||
_isThreaded(false) // assume non-threaded, must call initialize()
|
||||
{
|
||||
}
|
||||
|
||||
PacketReceiver::~PacketReceiver() {
|
||||
terminate();
|
||||
}
|
||||
|
||||
void PacketReceiver::initialize(bool isThreaded) {
|
||||
_isThreaded = isThreaded;
|
||||
if (_isThreaded) {
|
||||
pthread_create(&_thread, NULL, PacketReceiverThreadEntry, this);
|
||||
}
|
||||
}
|
||||
|
||||
void PacketReceiver::terminate() {
|
||||
if (_isThreaded) {
|
||||
_stopThread = true;
|
||||
pthread_join(_thread, NULL);
|
||||
_isThreaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PacketReceiver::queuePacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
_packets.push_back(NetworkPacket(senderAddress, packetData, packetLength));
|
||||
}
|
||||
|
||||
void PacketReceiver::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
// Default implementation does nothing... packet is discarded
|
||||
}
|
||||
|
||||
void* PacketReceiver::threadRoutine() {
|
||||
while (!_stopThread) {
|
||||
while (_packets.size() > 0) {
|
||||
NetworkPacket& packet = _packets.front();
|
||||
processPacket(packet.getSenderAddress(), packet.getData(), packet.getLength());
|
||||
_packets.erase(_packets.begin());
|
||||
}
|
||||
|
||||
// In non-threaded mode, this will break each time you call it so it's the
|
||||
// callers responsibility to continuously call this method
|
||||
if (!_isThreaded) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isThreaded) {
|
||||
pthread_exit(0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" void* PacketReceiverThreadEntry(void* arg) {
|
||||
PacketReceiver* packetReceiver = (PacketReceiver*)arg;
|
||||
return packetReceiver->threadRoutine();
|
||||
}
|
45
libraries/shared/src/PacketReceiver.h
Normal file
45
libraries/shared/src/PacketReceiver.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// PacketReceiver.h
|
||||
// shared
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Threaded or non-threaded packet receiver.
|
||||
//
|
||||
|
||||
#ifndef __shared__PacketReceiver__
|
||||
#define __shared__PacketReceiver__
|
||||
|
||||
#include "NetworkPacket.h"
|
||||
|
||||
class PacketReceiver {
|
||||
public:
|
||||
PacketReceiver();
|
||||
virtual ~PacketReceiver();
|
||||
|
||||
// Call this when your network receive gets a packet
|
||||
void queuePacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
// implement this to process the incoming packets
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
// Call to start the thread
|
||||
void initialize(bool isThreaded);
|
||||
|
||||
// Call when you're ready to stop the thread
|
||||
void terminate();
|
||||
|
||||
// If you're running in non-threaded mode, you must call this regularly
|
||||
void* threadRoutine();
|
||||
|
||||
private:
|
||||
bool _stopThread;
|
||||
bool _isThreaded;
|
||||
pthread_t _thread;
|
||||
std::vector<NetworkPacket> _packets;
|
||||
};
|
||||
|
||||
extern "C" void* PacketReceiverThreadEntry(void* arg);
|
||||
|
||||
#endif // __shared__PacketReceiver__
|
Loading…
Reference in a new issue