mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #4209 from sethalves/rework-bandwidth-meter
Consolidate Network Bandwidth Metrics
This commit is contained in:
commit
6483df69a4
22 changed files with 464 additions and 299 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -38,3 +38,5 @@ interface/resources/visage/*
|
|||
|
||||
# Ignore interfaceCache for Linux users
|
||||
interface/interfaceCache/
|
||||
|
||||
TAGS
|
||||
|
|
|
@ -201,6 +201,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
auto lodManager = DependencyManager::set<LODManager>();
|
||||
auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
|
||||
auto dialogsManager = DependencyManager::set<DialogsManager>();
|
||||
auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>();
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
auto speechRecognizer = DependencyManager::set<SpeechRecognizer>();
|
||||
#endif
|
||||
|
@ -241,10 +242,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_mousePressed(false),
|
||||
_enableProcessOctreeThread(true),
|
||||
_octreeProcessor(),
|
||||
_inPacketsPerSecond(0),
|
||||
_outPacketsPerSecond(0),
|
||||
_inBytesPerSecond(0),
|
||||
_outBytesPerSecond(0),
|
||||
_nodeBoundsDisplay(this),
|
||||
_previousScriptLocation(),
|
||||
_applicationOverlay(),
|
||||
|
@ -433,6 +430,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(saveScripts()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
|
||||
|
||||
// hook up bandwidth estimator
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
connect(nodeList.data(), SIGNAL(dataSent(const quint8, const int)),
|
||||
bandwidthRecorder.data(), SLOT(updateOutboundData(const quint8, const int)));
|
||||
connect(nodeList.data(), SIGNAL(dataReceived(const quint8, const int)),
|
||||
bandwidthRecorder.data(), SLOT(updateInboundData(const quint8, const int)));
|
||||
|
||||
// check first run...
|
||||
bool firstRun = SettingHandles::firstRun.get();
|
||||
if (firstRun) {
|
||||
|
@ -771,25 +775,8 @@ void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum)
|
|||
|
||||
void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
|
||||
foreach(NodeType_t type, destinationNodeTypes) {
|
||||
|
||||
// Perform the broadcast for one type
|
||||
int nReceivingNodes = DependencyManager::get<NodeList>()->broadcastToNodes(packet, NodeSet() << type);
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise)
|
||||
double bandwidth_amount = nReceivingNodes * packet.size();
|
||||
switch (type) {
|
||||
case NodeType::Agent:
|
||||
case NodeType::AvatarMixer:
|
||||
_bandwidthRecorder.avatarsChannel->output.updateValue(bandwidth_amount);
|
||||
_bandwidthRecorder.totalChannel->input.updateValue(bandwidth_amount);
|
||||
break;
|
||||
case NodeType::EntityServer:
|
||||
_bandwidthRecorder.octreeChannel->output.updateValue(bandwidth_amount);
|
||||
_bandwidthRecorder.totalChannel->output.updateValue(bandwidth_amount);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
DependencyManager::get<NodeList>()->broadcastToNodes(packet, NodeSet() << type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1390,15 +1377,8 @@ void Application::timer() {
|
|||
float diffTime = (float)_timerStart.nsecsElapsed() / 1000000000.0f;
|
||||
|
||||
_fps = (float)_frameCount / diffTime;
|
||||
|
||||
_inPacketsPerSecond = (float) _datagramProcessor.getInPacketCount() / diffTime;
|
||||
_outPacketsPerSecond = (float) _datagramProcessor.getOutPacketCount() / diffTime;
|
||||
_inBytesPerSecond = (float) _datagramProcessor.getInByteCount() / diffTime;
|
||||
_outBytesPerSecond = (float) _datagramProcessor.getOutByteCount() / diffTime;
|
||||
_frameCount = 0;
|
||||
|
||||
_datagramProcessor.resetCounters();
|
||||
|
||||
_timerStart.start();
|
||||
|
||||
// ask the node list to check in with the domain server
|
||||
|
@ -2383,10 +2363,6 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
|
||||
// make sure we still have an active socket
|
||||
nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||
_bandwidthRecorder.octreeChannel->output.updateValue(packetLength);
|
||||
_bandwidthRecorder.totalChannel->output.updateValue(packetLength);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -3374,8 +3350,6 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin
|
|||
}
|
||||
|
||||
void Application::packetSent(quint64 length) {
|
||||
_bandwidthRecorder.octreeChannel->output.updateValue(length);
|
||||
_bandwidthRecorder.totalChannel->output.updateValue(length);
|
||||
}
|
||||
|
||||
const QString SETTINGS_KEY = "Settings";
|
||||
|
|
|
@ -202,16 +202,11 @@ public:
|
|||
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
|
||||
|
||||
FaceTracker* getActiveFaceTracker();
|
||||
BandwidthRecorder* getBandwidthRecorder() { return &_bandwidthRecorder; }
|
||||
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
|
||||
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
|
||||
Overlays& getOverlays() { return _overlays; }
|
||||
|
||||
float getFps() const { return _fps; }
|
||||
float getInPacketsPerSecond() const { return _inPacketsPerSecond; }
|
||||
float getOutPacketsPerSecond() const { return _outPacketsPerSecond; }
|
||||
float getInBytesPerSecond() const { return _inBytesPerSecond; }
|
||||
float getOutBytesPerSecond() const { return _outBytesPerSecond; }
|
||||
const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
||||
void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
||||
|
||||
|
@ -484,9 +479,6 @@ private:
|
|||
|
||||
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
|
||||
|
||||
BandwidthRecorder _bandwidthRecorder;
|
||||
|
||||
|
||||
AvatarManager _avatarManager;
|
||||
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
|
||||
|
||||
|
@ -535,11 +527,6 @@ private:
|
|||
OctreePacketProcessor _octreeProcessor;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
|
||||
int _inPacketsPerSecond;
|
||||
int _outPacketsPerSecond;
|
||||
int _inBytesPerSecond;
|
||||
int _outBytesPerSecond;
|
||||
|
||||
StDev _idleLoopStdev;
|
||||
float _idleLoopMeasuredJitter;
|
||||
|
||||
|
|
|
@ -768,9 +768,6 @@ void Audio::handleAudioInput() {
|
|||
int packetBytes = currentPacketPtr - audioDataPacket;
|
||||
nodeList->writeDatagram(audioDataPacket, packetBytes, audioMixer);
|
||||
_outgoingAvatarAudioSequenceNumber++;
|
||||
|
||||
Application::getInstance()->getBandwidthRecorder()->audioChannel->output.updateValue(packetBytes);
|
||||
Application::getInstance()->getBandwidthRecorder()->totalChannel->output.updateValue(packetBytes);
|
||||
}
|
||||
delete[] inputAudioSamples;
|
||||
}
|
||||
|
@ -828,9 +825,6 @@ void Audio::addReceivedAudioToStream(const QByteArray& audioByteArray) {
|
|||
// Audio output must exist and be correctly set up if we're going to process received audio
|
||||
_receivedAudioStream.parseData(audioByteArray);
|
||||
}
|
||||
|
||||
Application::getInstance()->getBandwidthRecorder()->audioChannel->input.updateValue(audioByteArray.size());
|
||||
Application::getInstance()->getBandwidthRecorder()->totalChannel->input.updateValue(audioByteArray.size());
|
||||
}
|
||||
|
||||
void Audio::parseAudioEnvironmentData(const QByteArray &packet) {
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
//
|
||||
// BandwidthMeter.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Seth Alves on 2015-1-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Based on code by Tobias Schwinger
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <GeometryCache.h>
|
||||
#include "BandwidthRecorder.h"
|
||||
|
||||
|
||||
BandwidthRecorder::Channel::Channel(char const* const caption,
|
||||
char const* unitCaption,
|
||||
double unitScale,
|
||||
unsigned colorRGBA) :
|
||||
caption(caption),
|
||||
unitCaption(unitCaption),
|
||||
unitScale(unitScale),
|
||||
colorRGBA(colorRGBA)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
BandwidthRecorder::BandwidthRecorder() {
|
||||
}
|
||||
|
||||
|
||||
BandwidthRecorder::~BandwidthRecorder() {
|
||||
delete audioChannel;
|
||||
delete avatarsChannel;
|
||||
delete octreeChannel;
|
||||
delete metavoxelsChannel;
|
||||
delete totalChannel;
|
||||
}
|
||||
|
||||
|
||||
BandwidthRecorder::Stream::Stream(float msToAverage) : _value(0.0f), _msToAverage(msToAverage) {
|
||||
_prevTime.start();
|
||||
}
|
||||
|
||||
|
||||
void BandwidthRecorder::Stream::updateValue(double amount) {
|
||||
|
||||
// Determine elapsed time
|
||||
double dt = (double)_prevTime.nsecsElapsed() / 1000000.0; // ns to ms
|
||||
|
||||
// Ignore this value when timer imprecision yields dt = 0
|
||||
if (dt == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_prevTime.start();
|
||||
|
||||
// Compute approximate average
|
||||
_value = glm::mix(_value, amount / dt,
|
||||
glm::clamp(dt / _msToAverage, 0.0, 1.0));
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
//
|
||||
// BandwidthRecorder.h
|
||||
//
|
||||
// Created by Seth Alves on 2015-1-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Based on code by Tobias Schwinger
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#ifndef hifi_BandwidthRecorder_h
|
||||
#define hifi_BandwidthRecorder_h
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
class BandwidthRecorder {
|
||||
public:
|
||||
BandwidthRecorder();
|
||||
~BandwidthRecorder();
|
||||
|
||||
// keep track of data rate in one direction
|
||||
class Stream {
|
||||
public:
|
||||
Stream(float msToAverage = 3000.0f);
|
||||
void updateValue(double amount);
|
||||
double getValue() const { return _value; }
|
||||
private:
|
||||
double _value; // Current value.
|
||||
double _msToAverage; // Milliseconds to average.
|
||||
QElapsedTimer _prevTime; // Time of last feed.
|
||||
};
|
||||
|
||||
// keep track of data rate in two directions as well as units and style to use during display
|
||||
class Channel {
|
||||
public:
|
||||
Channel(char const* const caption, char const* unitCaption, double unitScale, unsigned colorRGBA);
|
||||
Stream input;
|
||||
Stream output;
|
||||
char const* const caption;
|
||||
char const* unitCaption;
|
||||
double unitScale;
|
||||
unsigned colorRGBA;
|
||||
};
|
||||
|
||||
// create the channels we keep track of
|
||||
Channel* audioChannel = new Channel("Audio", "Kbps", 8000.0 / 1024.0, 0x33cc99ff);
|
||||
Channel* avatarsChannel = new Channel("Avatars", "Kbps", 8000.0 / 1024.0, 0xffef40c0);
|
||||
Channel* octreeChannel = new Channel("Octree", "Kbps", 8000.0 / 1024.0, 0xd0d0d0a0);
|
||||
Channel* metavoxelsChannel = new Channel("Metavoxels", "Kbps", 8000.0 / 1024.0, 0xd0d0d0a0);
|
||||
Channel* totalChannel = new Channel("Total", "Kbps", 8000.0 / 1024.0, 0xd0d0d0a0);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -39,8 +39,7 @@ void DatagramProcessor::processDatagrams() {
|
|||
|
||||
while (DependencyManager::get<NodeList>()->getNodeSocket().hasPendingDatagrams()) {
|
||||
incomingPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
||||
nodeList->getNodeSocket().readDatagram(incomingPacket.data(), incomingPacket.size(),
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||
nodeList->readDatagram(incomingPacket, senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||
|
||||
_inPacketCount++;
|
||||
_inByteCount += incomingPacket.size();
|
||||
|
@ -73,7 +72,6 @@ void DatagramProcessor::processDatagrams() {
|
|||
|
||||
if (audioMixer) {
|
||||
audioMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||
audioMixer->recordBytesReceived(incomingPacket.size());
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -82,8 +80,6 @@ void DatagramProcessor::processDatagrams() {
|
|||
// this will keep creatorTokenIDs to IDs mapped correctly
|
||||
EntityItemID::handleAddEntityResponse(incomingPacket);
|
||||
application->getEntities()->getTree()->handleAddEntityResponse(incomingPacket);
|
||||
application->_bandwidthRecorder.octreeChannel->input.updateValue(incomingPacket.size());
|
||||
application->_bandwidthRecorder.totalChannel->input.updateValue(incomingPacket.size());
|
||||
break;
|
||||
case PacketTypeEntityData:
|
||||
case PacketTypeEntityErase:
|
||||
|
@ -97,8 +93,6 @@ void DatagramProcessor::processDatagrams() {
|
|||
// add this packet to our list of octree packets and process them on the octree data processing
|
||||
application->_octreeProcessor.queueReceivedPacket(matchedNode, incomingPacket);
|
||||
}
|
||||
application->_bandwidthRecorder.octreeChannel->input.updateValue(incomingPacket.size());
|
||||
application->_bandwidthRecorder.totalChannel->input.updateValue(incomingPacket.size());
|
||||
break;
|
||||
}
|
||||
case PacketTypeMetavoxelData:
|
||||
|
@ -113,15 +107,10 @@ void DatagramProcessor::processDatagrams() {
|
|||
|
||||
if (avatarMixer) {
|
||||
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||
avatarMixer->recordBytesReceived(incomingPacket.size());
|
||||
|
||||
QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram",
|
||||
Q_ARG(const QByteArray&, incomingPacket),
|
||||
Q_ARG(const QWeakPointer<Node>&, avatarMixer));
|
||||
}
|
||||
|
||||
application->_bandwidthRecorder.avatarsChannel->input.updateValue(incomingPacket.size());
|
||||
application->_bandwidthRecorder.totalChannel->input.updateValue(incomingPacket.size());
|
||||
break;
|
||||
}
|
||||
case PacketTypeDomainConnectionDenied: {
|
||||
|
|
|
@ -899,8 +899,6 @@ int MetavoxelSystemClient::parseData(const QByteArray& packet) {
|
|||
} else {
|
||||
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
|
||||
}
|
||||
Application::getInstance()->getBandwidthRecorder()->metavoxelsChannel->input.updateValue(packet.size());
|
||||
Application::getInstance()->getBandwidthRecorder()->totalChannel->input.updateValue(packet.size());
|
||||
}
|
||||
return packet.size();
|
||||
}
|
||||
|
@ -1016,8 +1014,6 @@ void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
|
|||
} else {
|
||||
DependencyManager::get<NodeList>()->writeDatagram(data, _node);
|
||||
}
|
||||
Application::getInstance()->getBandwidthRecorder()->metavoxelsChannel->output.updateValue(data.size());
|
||||
Application::getInstance()->getBandwidthRecorder()->totalChannel->output.updateValue(data.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -904,6 +904,7 @@ void ApplicationOverlay::renderAudioMeter() {
|
|||
void ApplicationOverlay::renderStatsAndLogs() {
|
||||
|
||||
Application* application = Application::getInstance();
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor();
|
||||
|
@ -919,10 +920,10 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
|||
int voxelPacketsToProcess = octreePacketProcessor.packetsToProcessCount();
|
||||
// Onscreen text about position, servers, etc
|
||||
Stats::getInstance()->display(WHITE_TEXT, horizontalOffset, application->getFps(),
|
||||
application->getInPacketsPerSecond(),
|
||||
application->getOutPacketsPerSecond(),
|
||||
application->getInBytesPerSecond(),
|
||||
application->getOutBytesPerSecond(),
|
||||
bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond(),
|
||||
bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond(),
|
||||
bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(),
|
||||
bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(),
|
||||
voxelPacketsToProcess);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,42 +21,54 @@
|
|||
#include <QColor>
|
||||
|
||||
|
||||
BandwidthDialog::ChannelDisplay::ChannelDisplay(BandwidthRecorder::Channel *ch, QFormLayout* form) {
|
||||
this->ch = ch;
|
||||
this->label = setupLabel(form);
|
||||
}
|
||||
BandwidthChannelDisplay::BandwidthChannelDisplay(QVector<NodeType_t> nodeTypesToFollow,
|
||||
QFormLayout* form,
|
||||
char const* const caption, char const* unitCaption,
|
||||
const float unitScale, unsigned colorRGBA) :
|
||||
_nodeTypesToFollow(nodeTypesToFollow),
|
||||
_caption(caption),
|
||||
_unitCaption(unitCaption),
|
||||
_unitScale(unitScale),
|
||||
_colorRGBA(colorRGBA)
|
||||
{
|
||||
_label = new QLabel();
|
||||
_label->setAlignment(Qt::AlignRight);
|
||||
|
||||
|
||||
QLabel* BandwidthDialog::ChannelDisplay::setupLabel(QFormLayout* form) {
|
||||
QLabel* label = new QLabel();
|
||||
|
||||
label->setAlignment(Qt::AlignRight);
|
||||
|
||||
QPalette palette = label->palette();
|
||||
unsigned rgb = ch->colorRGBA >> 8;
|
||||
QPalette palette = _label->palette();
|
||||
unsigned rgb = colorRGBA >> 8;
|
||||
rgb = ((rgb & 0xfefefeu) >> 1) + ((rgb & 0xf8f8f8) >> 3);
|
||||
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
|
||||
label->setPalette(palette);
|
||||
_label->setPalette(palette);
|
||||
|
||||
form->addRow((std::string(" ") + ch->caption + " Bandwidth In/Out:").c_str(), label);
|
||||
|
||||
return label;
|
||||
form->addRow(QString(" ") + _caption + " Bandwidth In/Out:", _label);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BandwidthDialog::ChannelDisplay::setLabelText() {
|
||||
std::string strBuf =
|
||||
std::to_string ((int) (ch->input.getValue() * ch->unitScale)) + "/" +
|
||||
std::to_string ((int) (ch->output.getValue() * ch->unitScale)) + " " + ch->unitCaption;
|
||||
label->setText(strBuf.c_str());
|
||||
void BandwidthChannelDisplay::bandwidthAverageUpdated() {
|
||||
float inTotal = 0.;
|
||||
float outTotal = 0.;
|
||||
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
|
||||
for (int i = 0; i < _nodeTypesToFollow.size(); ++i) {
|
||||
inTotal += bandwidthRecorder->getAverageInputKilobitsPerSecond(_nodeTypesToFollow.at(i));
|
||||
outTotal += bandwidthRecorder->getAverageOutputKilobitsPerSecond(_nodeTypesToFollow.at(i));
|
||||
}
|
||||
|
||||
_strBuf =
|
||||
QString("").setNum((int) (inTotal * _unitScale)) + "/" +
|
||||
QString("").setNum((int) (outTotal * _unitScale)) + " " + _unitCaption;
|
||||
}
|
||||
|
||||
|
||||
void BandwidthChannelDisplay::paint() {
|
||||
_label->setText(_strBuf);
|
||||
}
|
||||
|
||||
BandwidthDialog::BandwidthDialog(QWidget* parent, BandwidthRecorder* model) :
|
||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint),
|
||||
_model(model) {
|
||||
|
||||
BandwidthDialog::BandwidthDialog(QWidget* parent) :
|
||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) {
|
||||
|
||||
this->setWindowTitle("Bandwidth Details");
|
||||
|
||||
|
@ -64,30 +76,48 @@ BandwidthDialog::BandwidthDialog(QWidget* parent, BandwidthRecorder* model) :
|
|||
QFormLayout* form = new QFormLayout();
|
||||
this->QDialog::setLayout(form);
|
||||
|
||||
audioChannelDisplay = new ChannelDisplay(_model->audioChannel, form);
|
||||
avatarsChannelDisplay = new ChannelDisplay(_model->avatarsChannel, form);
|
||||
octreeChannelDisplay = new ChannelDisplay(_model->octreeChannel, form);
|
||||
metavoxelsChannelDisplay = new ChannelDisplay(_model->metavoxelsChannel, form);
|
||||
totalChannelDisplay = new ChannelDisplay(_model->totalChannel, form);
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
|
||||
_allChannelDisplays[0] = _audioChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::AudioMixer}, form, "Audio", "Kbps", 1.0, COLOR0);
|
||||
_allChannelDisplays[1] = _avatarsChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::Agent, NodeType::AvatarMixer}, form, "Avatars", "Kbps", 1.0, COLOR1);
|
||||
_allChannelDisplays[2] = _octreeChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::EntityServer}, form, "Octree", "Kbps", 1.0, COLOR2);
|
||||
_allChannelDisplays[3] = _octreeChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::DomainServer}, form, "Domain", "Kbps", 1.0, COLOR2);
|
||||
_allChannelDisplays[4] = _metavoxelsChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::MetavoxelServer, NodeType::EnvironmentServer}, form, "Metavoxels", "Kbps", 1.0, COLOR2);
|
||||
_allChannelDisplays[5] = _otherChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::Unassigned}, form, "Other", "Kbps", 1.0, COLOR2);
|
||||
_allChannelDisplays[6] = _totalChannelDisplay =
|
||||
new BandwidthChannelDisplay({NodeType::DomainServer, NodeType::EntityServer, NodeType::MetavoxelServer,
|
||||
NodeType::EnvironmentServer, NodeType::AudioMixer, NodeType::Agent,
|
||||
NodeType::AvatarMixer, NodeType::Unassigned},
|
||||
form, "Total", "Kbps", 1.0, COLOR2);
|
||||
|
||||
connect(averageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTimerTimeout()));
|
||||
averageUpdateTimer->start(1000);
|
||||
}
|
||||
|
||||
|
||||
BandwidthDialog::~BandwidthDialog() {
|
||||
delete audioChannelDisplay;
|
||||
delete avatarsChannelDisplay;
|
||||
delete octreeChannelDisplay;
|
||||
delete metavoxelsChannelDisplay;
|
||||
delete totalChannelDisplay;
|
||||
for (unsigned int i = 0; i < _CHANNELCOUNT; i++) {
|
||||
delete _allChannelDisplays[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BandwidthDialog::updateTimerTimeout() {
|
||||
for (unsigned int i = 0; i < _CHANNELCOUNT; i++) {
|
||||
_allChannelDisplays[i]->bandwidthAverageUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BandwidthDialog::paintEvent(QPaintEvent* event) {
|
||||
audioChannelDisplay->setLabelText();
|
||||
avatarsChannelDisplay->setLabelText();
|
||||
octreeChannelDisplay->setLabelText();
|
||||
metavoxelsChannelDisplay->setLabelText();
|
||||
totalChannelDisplay->setLabelText();
|
||||
|
||||
for (unsigned int i=0; i<_CHANNELCOUNT; i++)
|
||||
_allChannelDisplays[i]->paint();
|
||||
this->QDialog::paintEvent(event);
|
||||
this->setFixedSize(this->width(), this->height());
|
||||
}
|
||||
|
|
|
@ -15,36 +15,61 @@
|
|||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QFormLayout>
|
||||
#include <QVector>
|
||||
|
||||
#include "Node.h"
|
||||
#include "BandwidthRecorder.h"
|
||||
|
||||
|
||||
const unsigned int COLOR0 = 0x33cc99ff;
|
||||
const unsigned int COLOR1 = 0xffef40c0;
|
||||
const unsigned int COLOR2 = 0xd0d0d0a0;
|
||||
|
||||
|
||||
class BandwidthChannelDisplay : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BandwidthChannelDisplay(QVector<NodeType_t> nodeTypesToFollow,
|
||||
QFormLayout* form,
|
||||
char const* const caption, char const* unitCaption, float unitScale, unsigned colorRGBA);
|
||||
void paint();
|
||||
|
||||
private:
|
||||
QVector<NodeType_t> _nodeTypesToFollow;
|
||||
QLabel* _label;
|
||||
QString _strBuf;
|
||||
char const* const _caption;
|
||||
char const* _unitCaption;
|
||||
float const _unitScale;
|
||||
unsigned _colorRGBA;
|
||||
|
||||
|
||||
public slots:
|
||||
void bandwidthAverageUpdated();
|
||||
};
|
||||
|
||||
|
||||
class BandwidthDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Sets up the UI based on the configuration of the BandwidthRecorder
|
||||
BandwidthDialog(QWidget* parent, BandwidthRecorder* model);
|
||||
BandwidthDialog(QWidget* parent);
|
||||
~BandwidthDialog();
|
||||
|
||||
class ChannelDisplay {
|
||||
public:
|
||||
ChannelDisplay(BandwidthRecorder::Channel *ch, QFormLayout* form);
|
||||
QLabel* setupLabel(QFormLayout* form);
|
||||
void setLabelText();
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
private:
|
||||
BandwidthRecorder::Channel *ch;
|
||||
private:
|
||||
BandwidthChannelDisplay* _audioChannelDisplay;
|
||||
BandwidthChannelDisplay* _avatarsChannelDisplay;
|
||||
BandwidthChannelDisplay* _octreeChannelDisplay;
|
||||
BandwidthChannelDisplay* _domainChannelDisplay;
|
||||
BandwidthChannelDisplay* _metavoxelsChannelDisplay;
|
||||
BandwidthChannelDisplay* _otherChannelDisplay;
|
||||
BandwidthChannelDisplay* _totalChannelDisplay; // sums of all the other channels
|
||||
|
||||
QLabel* label;
|
||||
};
|
||||
static const unsigned int _CHANNELCOUNT = 7;
|
||||
BandwidthChannelDisplay* _allChannelDisplays[_CHANNELCOUNT];
|
||||
|
||||
ChannelDisplay* audioChannelDisplay;
|
||||
ChannelDisplay* avatarsChannelDisplay;
|
||||
ChannelDisplay* octreeChannelDisplay;
|
||||
ChannelDisplay* metavoxelsChannelDisplay;
|
||||
|
||||
// sums of all the other channels
|
||||
ChannelDisplay* totalChannelDisplay;
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -53,15 +78,17 @@ signals:
|
|||
public slots:
|
||||
|
||||
void reject();
|
||||
void updateTimerTimeout();
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
// Emits a 'closed' signal when this dialog is closed.
|
||||
void closeEvent(QCloseEvent*);
|
||||
|
||||
private:
|
||||
BandwidthRecorder* _model;
|
||||
QTimer* averageUpdateTimer = new QTimer(this);
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_BandwidthDialog_h
|
||||
|
|
|
@ -102,7 +102,7 @@ void DialogsManager::editAnimations() {
|
|||
|
||||
void DialogsManager::bandwidthDetails() {
|
||||
if (! _bandwidthDialog) {
|
||||
_bandwidthDialog = new BandwidthDialog(qApp->getWindow(), qApp->getBandwidthRecorder());
|
||||
_bandwidthDialog = new BandwidthDialog(qApp->getWindow());
|
||||
connect(_bandwidthDialog, SIGNAL(closed()), _bandwidthDialog, SLOT(deleteLater()));
|
||||
|
||||
if (_hmdToolsDialog) {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <PerfStat.h>
|
||||
|
||||
#include "Stats.h"
|
||||
#include "BandwidthRecorder.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
@ -201,8 +202,8 @@ void Stats::display(
|
|||
float fps,
|
||||
int inPacketsPerSecond,
|
||||
int outPacketsPerSecond,
|
||||
int inBytesPerSecond,
|
||||
int outBytesPerSecond,
|
||||
int inKbitsPerSecond,
|
||||
int outKbitsPerSecond,
|
||||
int voxelPacketsToProcess)
|
||||
{
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
|
@ -216,6 +217,8 @@ void Stats::display(
|
|||
QLocale locale(QLocale::English);
|
||||
std::stringstream octreeStats;
|
||||
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
|
||||
if (_lastHorizontalOffset != horizontalOffset) {
|
||||
resetWidth(glCanvas->width(), horizontalOffset);
|
||||
_lastHorizontalOffset = horizontalOffset;
|
||||
|
@ -316,8 +319,8 @@ void Stats::display(
|
|||
sprintf(packetsPerSecondString, "Packets In/Out: %d/%d", inPacketsPerSecond, outPacketsPerSecond);
|
||||
char averageMegabitsPerSecond[30];
|
||||
sprintf(averageMegabitsPerSecond, "Mbps In/Out: %3.2f/%3.2f",
|
||||
(float)inBytesPerSecond * 8.0f / 1000000.0f,
|
||||
(float)outBytesPerSecond * 8.0f / 1000000.0f);
|
||||
(float)inKbitsPerSecond * 1.0f / 1000.0f,
|
||||
(float)outKbitsPerSecond * 1.0f / 1000.0f);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, packetsPerSecondString, color);
|
||||
|
@ -440,8 +443,10 @@ void Stats::display(
|
|||
SharedNodePointer avatarMixer = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::AvatarMixer);
|
||||
if (avatarMixer) {
|
||||
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
||||
roundf(avatarMixer->getAverageKilobitsPerSecond()),
|
||||
roundf(avatarMixer->getAveragePacketsPerSecond()));
|
||||
roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) +
|
||||
bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)),
|
||||
roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer) +
|
||||
bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer)));
|
||||
} else {
|
||||
sprintf(avatarMixerStats, "No Avatar Mixer");
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
void checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseDragStartedY, int horizontalOffset);
|
||||
void resetWidth(int width, int horizontalOffset);
|
||||
void display(const float* color, int horizontalOffset, float fps, int inPacketsPerSecond, int outPacketsPerSecond,
|
||||
int inBytesPerSecond, int outBytesPerSecond, int voxelPacketsToProcess);
|
||||
int inKbitsPerSecond, int outKbitsPerSecond, int voxelPacketsToProcess);
|
||||
bool includeTimingRecord(const QString& name);
|
||||
|
||||
Q_INVOKABLE void setMetavoxelStats(int internal, int leaves, int sendProgress,
|
||||
|
|
195
libraries/networking/src/BandwidthRecorder.cpp
Normal file
195
libraries/networking/src/BandwidthRecorder.cpp
Normal file
|
@ -0,0 +1,195 @@
|
|||
//
|
||||
// BandwidthMeter.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Seth Alves on 2015-1-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Based on code by Tobias Schwinger
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include "BandwidthRecorder.h"
|
||||
|
||||
|
||||
BandwidthRecorder::Channel::Channel() {
|
||||
}
|
||||
|
||||
float BandwidthRecorder::Channel::getAverageInputPacketsPerSecond() {
|
||||
float delt = _input.getEventDeltaAverage();
|
||||
if (delt > 0.0f) {
|
||||
return (1.0 / delt);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::Channel::getAverageOutputPacketsPerSecond() {
|
||||
float delt = _input.getEventDeltaAverage();
|
||||
if (delt > 0.0f) {
|
||||
return (1.0 / _output.getEventDeltaAverage());
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::Channel::getAverageInputKilobitsPerSecond() {
|
||||
return (_input.getAverageSampleValuePerSecond() * (8.0f / 1000));
|
||||
}
|
||||
|
||||
float BandwidthRecorder::Channel::getAverageOutputKilobitsPerSecond() {
|
||||
return (_output.getAverageSampleValuePerSecond() * (8.0f / 1000));
|
||||
}
|
||||
|
||||
|
||||
void BandwidthRecorder::Channel::updateInputAverage(const float sample) {
|
||||
_input.updateAverage(sample);
|
||||
}
|
||||
|
||||
void BandwidthRecorder::Channel::updateOutputAverage(const float sample) {
|
||||
_output.updateAverage(sample);
|
||||
}
|
||||
|
||||
BandwidthRecorder::BandwidthRecorder() {
|
||||
for (uint i=0; i<CHANNEL_COUNT; i++)
|
||||
_channels[ i ] = NULL;
|
||||
}
|
||||
|
||||
BandwidthRecorder::~BandwidthRecorder() {
|
||||
for (uint i=0; i<CHANNEL_COUNT; i++)
|
||||
delete _channels[ i ];
|
||||
}
|
||||
|
||||
void BandwidthRecorder::updateInboundData(const quint8 channelType, const int sample) {
|
||||
Q_ASSERT(channelType < CHANNEL_COUNT);
|
||||
if (! _channels[channelType]) {
|
||||
_channels[channelType] = new Channel();
|
||||
}
|
||||
_channels[channelType]->updateInputAverage(sample);
|
||||
}
|
||||
|
||||
void BandwidthRecorder::updateOutboundData(const quint8 channelType, const int sample) {
|
||||
Q_ASSERT(channelType < CHANNEL_COUNT);
|
||||
if (! _channels[channelType]) {
|
||||
_channels[channelType] = new Channel();
|
||||
}
|
||||
_channels[channelType]->updateOutputAverage(sample);
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getAverageInputPacketsPerSecond(const quint8 channelType) {
|
||||
Q_ASSERT(channelType < CHANNEL_COUNT);
|
||||
if (! _channels[channelType]) {
|
||||
return 0.0f;
|
||||
}
|
||||
return _channels[channelType]->getAverageInputPacketsPerSecond();
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getAverageOutputPacketsPerSecond(const quint8 channelType) {
|
||||
Q_ASSERT(channelType < CHANNEL_COUNT);
|
||||
if (! _channels[channelType]) {
|
||||
return 0.0f;
|
||||
}
|
||||
return _channels[channelType]->getAverageOutputPacketsPerSecond();
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getAverageInputKilobitsPerSecond(const quint8 channelType) {
|
||||
Q_ASSERT(channelType < CHANNEL_COUNT);
|
||||
if (! _channels[channelType]) {
|
||||
return 0.0f;
|
||||
}
|
||||
return _channels[channelType]->getAverageInputKilobitsPerSecond();
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getAverageOutputKilobitsPerSecond(const quint8 channelType) {
|
||||
Q_ASSERT(channelType < CHANNEL_COUNT);
|
||||
if (! _channels[channelType]) {
|
||||
return 0.0f;
|
||||
}
|
||||
return _channels[channelType]->getAverageOutputKilobitsPerSecond();
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getTotalAverageInputPacketsPerSecond() {
|
||||
float result = 0.0f;
|
||||
for (uint i=0; i<CHANNEL_COUNT; i++) {
|
||||
if (_channels[i]) {
|
||||
result += _channels[i]->getAverageInputPacketsPerSecond();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getTotalAverageOutputPacketsPerSecond() {
|
||||
float result = 0.0f;
|
||||
for (uint i=0; i<CHANNEL_COUNT; i++) {
|
||||
if (_channels[i]) {
|
||||
result += _channels[i]->getAverageOutputPacketsPerSecond();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getTotalAverageInputKilobitsPerSecond(){
|
||||
float result = 0.0f;
|
||||
for (uint i=0; i<CHANNEL_COUNT; i++) {
|
||||
if (_channels[i]) {
|
||||
result += _channels[i]->getAverageInputKilobitsPerSecond();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getTotalAverageOutputKilobitsPerSecond(){
|
||||
float result = 0.0f;
|
||||
for (uint i=0; i<CHANNEL_COUNT; i++) {
|
||||
if (_channels[i]) {
|
||||
result += _channels[i]->getAverageOutputKilobitsPerSecond();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getCachedTotalAverageInputPacketsPerSecond() {
|
||||
static qint64 lastCalculated = 0;
|
||||
static float cachedValue = 0.0f;
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
if (now - lastCalculated > 1000.0f) {
|
||||
lastCalculated = now;
|
||||
cachedValue = getTotalAverageInputPacketsPerSecond();
|
||||
}
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getCachedTotalAverageOutputPacketsPerSecond() {
|
||||
static qint64 lastCalculated = 0;
|
||||
static float cachedValue = 0.0f;
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
if (now - lastCalculated > 1000.0f) {
|
||||
lastCalculated = now;
|
||||
cachedValue = getTotalAverageOutputPacketsPerSecond();
|
||||
}
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getCachedTotalAverageInputKilobitsPerSecond() {
|
||||
static qint64 lastCalculated = 0;
|
||||
static float cachedValue = 0.0f;
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
if (now - lastCalculated > 1000.0f) {
|
||||
lastCalculated = now;
|
||||
cachedValue = getTotalAverageInputKilobitsPerSecond();
|
||||
}
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
float BandwidthRecorder::getCachedTotalAverageOutputKilobitsPerSecond() {
|
||||
static qint64 lastCalculated = 0;
|
||||
static float cachedValue = 0.0f;
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
if (now - lastCalculated > 1000.0f) {
|
||||
lastCalculated = now;
|
||||
cachedValue = getTotalAverageOutputKilobitsPerSecond();
|
||||
}
|
||||
return cachedValue;
|
||||
}
|
77
libraries/networking/src/BandwidthRecorder.h
Normal file
77
libraries/networking/src/BandwidthRecorder.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// BandwidthRecorder.h
|
||||
//
|
||||
// Created by Seth Alves on 2015-1-30
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Based on code by Tobias Schwinger
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#ifndef hifi_BandwidthRecorder_h
|
||||
#define hifi_BandwidthRecorder_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QElapsedTimer>
|
||||
#include <QTimer>
|
||||
#include "DependencyManager.h"
|
||||
#include "Node.h"
|
||||
#include "SimpleMovingAverage.h"
|
||||
|
||||
|
||||
class BandwidthRecorder : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
BandwidthRecorder();
|
||||
~BandwidthRecorder();
|
||||
|
||||
// keep track of data rate in two directions as well as units and style to use during display
|
||||
class Channel {
|
||||
public:
|
||||
Channel();
|
||||
float getAverageInputPacketsPerSecond();
|
||||
float getAverageOutputPacketsPerSecond();
|
||||
float getAverageInputKilobitsPerSecond();
|
||||
float getAverageOutputKilobitsPerSecond();
|
||||
|
||||
void updateInputAverage(const float sample);
|
||||
void updateOutputAverage(const float sample);
|
||||
|
||||
private:
|
||||
SimpleMovingAverage _input = SimpleMovingAverage();
|
||||
SimpleMovingAverage _output = SimpleMovingAverage();
|
||||
};
|
||||
|
||||
float getAverageInputPacketsPerSecond(const quint8 channelType);
|
||||
float getAverageOutputPacketsPerSecond(const quint8 channelType);
|
||||
float getAverageInputKilobitsPerSecond(const quint8 channelType);
|
||||
float getAverageOutputKilobitsPerSecond(const quint8 channelType);
|
||||
|
||||
float getTotalAverageInputPacketsPerSecond();
|
||||
float getTotalAverageOutputPacketsPerSecond();
|
||||
float getTotalAverageInputKilobitsPerSecond();
|
||||
float getTotalAverageOutputKilobitsPerSecond();
|
||||
|
||||
float getCachedTotalAverageInputPacketsPerSecond();
|
||||
float getCachedTotalAverageOutputPacketsPerSecond();
|
||||
float getCachedTotalAverageInputKilobitsPerSecond();
|
||||
float getCachedTotalAverageOutputKilobitsPerSecond();
|
||||
|
||||
|
||||
private:
|
||||
// one for each possible Node type
|
||||
static const unsigned int CHANNEL_COUNT = 256;
|
||||
Channel* _channels[CHANNEL_COUNT];
|
||||
|
||||
|
||||
public slots:
|
||||
void updateInboundData(const quint8 channelType, const int bytes);
|
||||
void updateOutboundData(const quint8 channelType, const int bytes);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -47,8 +47,6 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
|
|||
_localSockAddr(),
|
||||
_publicSockAddr(),
|
||||
_stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT),
|
||||
_numCollectedPackets(0),
|
||||
_numCollectedBytes(0),
|
||||
_packetStatTimer()
|
||||
{
|
||||
static bool firstCall = true;
|
||||
|
@ -208,6 +206,21 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// qint64 LimitedNodeList::readDatagram(char* data, qint64 maxSize, QHostAddress* address = 0, quint16 * port = 0) {
|
||||
|
||||
qint64 LimitedNodeList::readDatagram(QByteArray& incomingPacket, QHostAddress* address = 0, quint16 * port = 0) {
|
||||
qint64 result = getNodeSocket().readDatagram(incomingPacket.data(), incomingPacket.size(), address, port);
|
||||
|
||||
SharedNodePointer sendingNode = sendingNodeForPacket(incomingPacket);
|
||||
if (sendingNode) {
|
||||
emit dataReceived(sendingNode->getType(), incomingPacket.size());
|
||||
} else {
|
||||
emit dataReceived(NodeType::Unassigned, incomingPacket.size());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr,
|
||||
const QUuid& connectionSecret) {
|
||||
QByteArray datagramCopy = datagram;
|
||||
|
@ -217,6 +230,7 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSock
|
|||
replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret);
|
||||
}
|
||||
|
||||
// XXX can BandwidthRecorder be used for this?
|
||||
// stat collection for packets
|
||||
++_numCollectedPackets;
|
||||
_numCollectedBytes += datagram.size();
|
||||
|
@ -231,10 +245,11 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSock
|
|||
return bytesWritten;
|
||||
}
|
||||
|
||||
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode,
|
||||
const HifiSockAddr& overridenSockAddr) {
|
||||
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram,
|
||||
const SharedNodePointer& destinationNode,
|
||||
const HifiSockAddr& overridenSockAddr) {
|
||||
if (destinationNode) {
|
||||
// if we don't have an ovveriden address, assume they want to send to the node's active socket
|
||||
// if we don't have an overridden address, assume they want to send to the node's active socket
|
||||
const HifiSockAddr* destinationSockAddr = &overridenSockAddr;
|
||||
if (overridenSockAddr.isNull()) {
|
||||
if (destinationNode->getActiveSocket()) {
|
||||
|
@ -245,6 +260,8 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const SharedNo
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
emit dataSent(destinationNode->getType(), datagram.size());
|
||||
|
||||
return writeDatagram(datagram, *destinationSockAddr, destinationNode->getConnectionSecret());
|
||||
}
|
||||
|
@ -303,7 +320,6 @@ int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& match
|
|||
QMutexLocker locker(&matchingNode->getMutex());
|
||||
|
||||
matchingNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||
matchingNode->recordBytesReceived(packet.size());
|
||||
|
||||
if (!matchingNode->getLinkedData() && linkedDataCreateCallback) {
|
||||
linkedDataCreateCallback(matchingNode.data());
|
||||
|
|
|
@ -82,6 +82,8 @@ public:
|
|||
QUdpSocket& getDTLSSocket();
|
||||
|
||||
bool packetVersionAndHashMatch(const QByteArray& packet);
|
||||
|
||||
qint64 readDatagram(QByteArray& incomingPacket, QHostAddress* address, quint16 * port);
|
||||
|
||||
qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode,
|
||||
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
||||
|
@ -180,6 +182,9 @@ signals:
|
|||
|
||||
void localSockAddrChanged(const HifiSockAddr& localSockAddr);
|
||||
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
||||
|
||||
void dataSent(const quint8 channel_type, const int bytes);
|
||||
void dataReceived(const quint8 channel_type, const int bytes);
|
||||
|
||||
protected:
|
||||
LimitedNodeList(unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0);
|
||||
|
@ -201,8 +206,11 @@ protected:
|
|||
HifiSockAddr _localSockAddr;
|
||||
HifiSockAddr _publicSockAddr;
|
||||
HifiSockAddr _stunSockAddr;
|
||||
|
||||
// XXX can BandwidthRecorder be used for this?
|
||||
int _numCollectedPackets;
|
||||
int _numCollectedBytes;
|
||||
|
||||
QElapsedTimer _packetStatTimer;
|
||||
|
||||
template<typename IteratorLambda>
|
||||
|
|
|
@ -47,7 +47,6 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
|||
_activeSocket(NULL),
|
||||
_symmetricSocket(),
|
||||
_connectionSecret(),
|
||||
_bytesReceivedMovingAverage(NULL),
|
||||
_linkedData(NULL),
|
||||
_isAlive(true),
|
||||
_pingMs(-1), // "Uninitialized"
|
||||
|
@ -60,31 +59,6 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
|||
|
||||
Node::~Node() {
|
||||
delete _linkedData;
|
||||
delete _bytesReceivedMovingAverage;
|
||||
}
|
||||
|
||||
void Node::recordBytesReceived(int bytesReceived) {
|
||||
if (!_bytesReceivedMovingAverage) {
|
||||
_bytesReceivedMovingAverage = new SimpleMovingAverage(100);
|
||||
}
|
||||
|
||||
_bytesReceivedMovingAverage->updateAverage((float) bytesReceived);
|
||||
}
|
||||
|
||||
float Node::getAveragePacketsPerSecond() {
|
||||
if (_bytesReceivedMovingAverage) {
|
||||
return (1 / _bytesReceivedMovingAverage->getEventDeltaAverage());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float Node::getAverageKilobitsPerSecond() {
|
||||
if (_bytesReceivedMovingAverage) {
|
||||
return (_bytesReceivedMovingAverage->getAverageSampleValuePerSecond() * (8.0f / 1000));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::updateClockSkewUsec(int clockSkewSample) {
|
||||
|
|
|
@ -63,10 +63,6 @@ public:
|
|||
bool isAlive() const { return _isAlive; }
|
||||
void setAlive(bool isAlive) { _isAlive = isAlive; }
|
||||
|
||||
void recordBytesReceived(int bytesReceived);
|
||||
float getAverageKilobitsPerSecond();
|
||||
float getAveragePacketsPerSecond();
|
||||
|
||||
int getPingMs() const { return _pingMs; }
|
||||
void setPingMs(int pingMs) { _pingMs = pingMs; }
|
||||
|
||||
|
@ -99,7 +95,6 @@ private:
|
|||
HifiSockAddr _symmetricSocket;
|
||||
|
||||
QUuid _connectionSecret;
|
||||
SimpleMovingAverage* _bytesReceivedMovingAverage;
|
||||
NodeData* _linkedData;
|
||||
bool _isAlive;
|
||||
int _pingMs;
|
||||
|
|
|
@ -83,6 +83,7 @@ void ThreadedAssignment::addPacketStatsAndSendStatsPacket(QJsonObject &statsObje
|
|||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
float packetsPerSecond, bytesPerSecond;
|
||||
// XXX can BandwidthRecorder be used for this?
|
||||
nodeList->getPacketStats(packetsPerSecond, bytesPerSecond);
|
||||
nodeList->resetPacketStats();
|
||||
|
||||
|
|
14
tools/refresh-tags.sh
Executable file
14
tools/refresh-tags.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm -f TAGS
|
||||
|
||||
find . -name *.h -print | while read I
|
||||
do
|
||||
etags --append "$I"
|
||||
done
|
||||
|
||||
|
||||
find . -name *.cpp -print | grep -v 'moc_' | while read I
|
||||
do
|
||||
etags --append "$I"
|
||||
done
|
Loading…
Reference in a new issue