setup subclass for threaded assignments

This commit is contained in:
Stephen Birarda 2013-12-03 10:22:13 -08:00
parent 6ce8c12cb7
commit c3b6a7b24c
10 changed files with 81 additions and 45 deletions

View file

@ -80,7 +80,7 @@ void AssignmentClient::readPendingDatagrams() {
qDebug() << "Dropping received assignment since we are currently running one.\n"; qDebug() << "Dropping received assignment since we are currently running one.\n";
} else { } else {
// construct the deployed assignment from the packet data // construct the deployed assignment from the packet data
_currentAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes); _currentAssignment = (ThreadedAssignment*) AssignmentFactory::unpackAssignment(packetData, receivedBytes);
qDebug() << "Received an assignment -" << *_currentAssignment << "\n"; qDebug() << "Received an assignment -" << *_currentAssignment << "\n";
@ -95,7 +95,7 @@ void AssignmentClient::readPendingDatagrams() {
// start the deployed assignment // start the deployed assignment
QThread* workerThread = new QThread(this); QThread* workerThread = new QThread(this);
connect(workerThread, SIGNAL(started()), _currentAssignment, SLOT(setup())); connect(workerThread, SIGNAL(started()), _currentAssignment, SLOT(run()));
connect(_currentAssignment, SIGNAL(finished()), this, SLOT(assignmentCompleted())); connect(_currentAssignment, SIGNAL(finished()), this, SLOT(assignmentCompleted()));
connect(_currentAssignment, SIGNAL(finished()), workerThread, SLOT(quit())); connect(_currentAssignment, SIGNAL(finished()), workerThread, SLOT(quit()));

View file

@ -11,6 +11,8 @@
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include "ThreadedAssignment.h"
class AssignmentClient : public QCoreApplication { class AssignmentClient : public QCoreApplication {
Q_OBJECT Q_OBJECT
public: public:
@ -24,7 +26,7 @@ private slots:
void assignmentCompleted(); void assignmentCompleted();
private: private:
Assignment _requestAssignment; Assignment _requestAssignment;
Assignment* _currentAssignment; ThreadedAssignment* _currentAssignment;
}; };
#endif /* defined(__hifi__AssignmentClient__) */ #endif /* defined(__hifi__AssignmentClient__) */

View file

@ -0,0 +1,32 @@
//
// ThreadedAssignment.cpp
// hifi
//
// Created by Stephen Birarda on 12/3/2013.
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include "ThreadedAssignment.h"
ThreadedAssignment::ThreadedAssignment(const unsigned char* dataBuffer, int numBytes) :
Assignment(dataBuffer, numBytes),
_isFinished(false)
{
}
void ThreadedAssignment::setFinished(bool isFinished) {
_isFinished = isFinished;
if (_isFinished) {
emit finished();
}
}
void ThreadedAssignment::checkInWithDomainServerOrExit() {
if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
setFinished(true);
} else {
NodeList::getInstance()->sendDomainServerCheckIn();
}
}

View file

@ -0,0 +1,34 @@
//
// ThreadedAssignment.h
// hifi
//
// Created by Stephen Birarda on 12/3/2013.
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#ifndef __hifi__ThreadedAssignment__
#define __hifi__ThreadedAssignment__
#include <Assignment.h>
class ThreadedAssignment : public Assignment {
Q_OBJECT
public:
ThreadedAssignment(const unsigned char* dataBuffer, int numBytes);
void setFinished(bool isFinished);
public slots:
/// threaded run of assignment
virtual void run() = 0;
virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) = 0;
protected:
bool _isFinished;
private slots:
void checkInWithDomainServerOrExit();
signals:
void finished();
};
#endif /* defined(__hifi__ThreadedAssignment__) */

View file

@ -68,8 +68,7 @@ void attachNewBufferToNode(Node *newNode) {
} }
AudioMixer::AudioMixer(const unsigned char* dataBuffer, int numBytes) : AudioMixer::AudioMixer(const unsigned char* dataBuffer, int numBytes) :
Assignment(dataBuffer, numBytes), ThreadedAssignment(dataBuffer, numBytes)
_isFinished(false)
{ {
} }
@ -251,21 +250,13 @@ void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSock
} }
} }
void AudioMixer::checkInWithDomainServerOrExit() { void AudioMixer::run() {
if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
_isFinished = true;
emit finished();
} else {
NodeList::getInstance()->sendDomainServerCheckIn();
}
}
NodeList* nodeList = NodeList::getInstance();
void AudioMixer::setup() {
// change the logging target name while this is running // change the logging target name while this is running
Logging::setTargetName(AUDIO_MIXER_LOGGING_TARGET_NAME); Logging::setTargetName(AUDIO_MIXER_LOGGING_TARGET_NAME);
NodeList *nodeList = NodeList::getInstance();
nodeList->setOwnerType(NODE_TYPE_AUDIO_MIXER); nodeList->setOwnerType(NODE_TYPE_AUDIO_MIXER);
const char AUDIO_MIXER_NODE_TYPES_OF_INTEREST[2] = { NODE_TYPE_AGENT, NODE_TYPE_AUDIO_INJECTOR }; const char AUDIO_MIXER_NODE_TYPES_OF_INTEREST[2] = { NODE_TYPE_AGENT, NODE_TYPE_AUDIO_INJECTOR };
@ -281,13 +272,6 @@ void AudioMixer::setup() {
connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000);
run();
}
void AudioMixer::run() {
NodeList* nodeList = NodeList::getInstance();
int nextFrame = 0; int nextFrame = 0;
timeval startTime; timeval startTime;

View file

@ -9,28 +9,23 @@
#ifndef __hifi__AudioMixer__ #ifndef __hifi__AudioMixer__
#define __hifi__AudioMixer__ #define __hifi__AudioMixer__
#include <Assignment.h>
#include <AudioRingBuffer.h> #include <AudioRingBuffer.h>
#include "../ThreadedAssignment.h"
class PositionalAudioRingBuffer; class PositionalAudioRingBuffer;
class AvatarAudioRingBuffer; class AvatarAudioRingBuffer;
/// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients. /// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients.
class AudioMixer : public Assignment { class AudioMixer : public ThreadedAssignment {
Q_OBJECT Q_OBJECT
public: public:
AudioMixer(const unsigned char* dataBuffer, int numBytes); AudioMixer(const unsigned char* dataBuffer, int numBytes);
public slots: public slots:
/// performs setup for the audio mixer /// threaded run of assignment
void setup();
/// performs run of audio mixer
void run(); void run();
void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
signals:
void finished();
private: private:
/// adds one buffer to the mix for a listening node /// adds one buffer to the mix for a listening node
void addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuffer* bufferToAdd, void addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuffer* bufferToAdd,
@ -41,9 +36,6 @@ private:
int16_t _clientSamples[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2]; int16_t _clientSamples[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2];
bool _isFinished;
private slots:
void checkInWithDomainServerOrExit();
}; };
#endif /* defined(__hifi__AudioMixer__) */ #endif /* defined(__hifi__AudioMixer__) */

View file

@ -21,7 +21,6 @@
#include "Agent.h" #include "Agent.h"
#include "Assignment.h" #include "Assignment.h"
#include "AssignmentClient.h" #include "AssignmentClient.h"
#include "AssignmentFactory.h"
#include "audio/AudioMixer.h" #include "audio/AudioMixer.h"
#include "avatars/AvatarMixer.h" #include "avatars/AvatarMixer.h"

View file

@ -211,10 +211,6 @@ int Assignment::packToBuffer(unsigned char* buffer) {
return numPackedBytes; return numPackedBytes;
} }
void Assignment::run() {
// run method ovveridden by subclasses
}
QDebug operator<<(QDebug debug, const Assignment &assignment) { QDebug operator<<(QDebug debug, const Assignment &assignment) {
debug.nospace() << "UUID: " << assignment.getUUID().toString().toStdString().c_str() << debug.nospace() << "UUID: " << assignment.getUUID().toString().toStdString().c_str() <<
", Type: " << assignment.getType(); ", Type: " << assignment.getType();

View file

@ -90,9 +90,6 @@ public:
// implement parseData to return 0 so we can be a subclass of NodeData // implement parseData to return 0 so we can be a subclass of NodeData
int parseData(unsigned char* sourceBuffer, int numBytes) { return 0; } int parseData(unsigned char* sourceBuffer, int numBytes) { return 0; }
/// threaded run of assignment
virtual void run();
friend QDebug operator<<(QDebug debug, const Assignment& assignment); friend QDebug operator<<(QDebug debug, const Assignment& assignment);
friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment); friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment);
friend QDataStream& operator>>(QDataStream &in, Assignment& assignment); friend QDataStream& operator>>(QDataStream &in, Assignment& assignment);

View file

@ -34,7 +34,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
case PACKET_TYPE_DOMAIN: case PACKET_TYPE_DOMAIN:
case PACKET_TYPE_DOMAIN_LIST_REQUEST: case PACKET_TYPE_DOMAIN_LIST_REQUEST:
case PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY: case PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY:
return 1; return 2;
case PACKET_TYPE_VOXEL_QUERY: case PACKET_TYPE_VOXEL_QUERY:
return 1; return 1;