mirror of
https://github.com/lubosz/overte.git
synced 2025-08-29 09:26:28 +02:00
Include a simple bandwidth limit option.
This commit is contained in:
parent
9c0e3ead13
commit
311d1332f1
4 changed files with 83 additions and 4 deletions
|
@ -39,11 +39,13 @@ REGISTER_META_OBJECT(StaticModelRenderer)
|
|||
|
||||
static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
|
||||
|
||||
MetavoxelSystem::NetworkSimulation::NetworkSimulation(float dropRate, float repeatRate, int minimumDelay, int maximumDelay) :
|
||||
MetavoxelSystem::NetworkSimulation::NetworkSimulation(float dropRate, float repeatRate,
|
||||
int minimumDelay, int maximumDelay, int bandwidthLimit) :
|
||||
dropRate(dropRate),
|
||||
repeatRate(repeatRate),
|
||||
minimumDelay(minimumDelay),
|
||||
maximumDelay(maximumDelay) {
|
||||
maximumDelay(maximumDelay),
|
||||
bandwidthLimit(bandwidthLimit) {
|
||||
}
|
||||
|
||||
void MetavoxelSystem::init() {
|
||||
|
@ -695,6 +697,28 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
|||
}
|
||||
}
|
||||
|
||||
Throttle::Throttle() :
|
||||
_limit(INT_MAX),
|
||||
_total(0) {
|
||||
}
|
||||
|
||||
bool Throttle::shouldThrottle(int bytes) {
|
||||
// clear expired buckets
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
while (!_buckets.isEmpty() && _buckets.first().first >= now) {
|
||||
_total -= _buckets.takeFirst().second;
|
||||
}
|
||||
|
||||
// if possible, add the new bucket
|
||||
if (_total + bytes > _limit) {
|
||||
return true;
|
||||
}
|
||||
const int BUCKET_DURATION = 1000;
|
||||
_buckets.append(Bucket(now + BUCKET_DURATION, bytes));
|
||||
_total += bytes;
|
||||
return false;
|
||||
}
|
||||
|
||||
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) :
|
||||
MetavoxelClient(node, updater) {
|
||||
}
|
||||
|
@ -746,6 +770,12 @@ int MetavoxelSystemClient::parseData(const QByteArray& packet) {
|
|||
}
|
||||
int count = (randFloat() < simulation.repeatRate) ? 2 : 1;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (simulation.bandwidthLimit > 0) {
|
||||
_receiveThrottle.setLimit(simulation.bandwidthLimit);
|
||||
if (_receiveThrottle.shouldThrottle(packet.size())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int delay = randIntInRange(simulation.minimumDelay, simulation.maximumDelay);
|
||||
if (delay > 0) {
|
||||
ReceiveDelayer* delayer = new ReceiveDelayer(_node, packet);
|
||||
|
@ -864,6 +894,12 @@ void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
|
|||
}
|
||||
int count = (randFloat() < simulation.repeatRate) ? 2 : 1;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (simulation.bandwidthLimit > 0) {
|
||||
_sendThrottle.setLimit(simulation.bandwidthLimit);
|
||||
if (_sendThrottle.shouldThrottle(data.size())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int delay = randIntInRange(simulation.minimumDelay, simulation.maximumDelay);
|
||||
if (delay > 0) {
|
||||
SendDelayer* delayer = new SendDelayer(_node, data);
|
||||
|
|
|
@ -37,8 +37,10 @@ public:
|
|||
float repeatRate;
|
||||
int minimumDelay;
|
||||
int maximumDelay;
|
||||
int bandwidthLimit;
|
||||
|
||||
NetworkSimulation(float dropRate = 0.0f, float repeatRate = 0.0f, int minimumDelay = 0, int maximumDelay = 0);
|
||||
NetworkSimulation(float dropRate = 0.0f, float repeatRate = 0.0f, int minimumDelay = 0,
|
||||
int maximumDelay = 0, int bandwidthLimit = 0);
|
||||
};
|
||||
|
||||
virtual void init();
|
||||
|
@ -132,6 +134,28 @@ typedef QVector<BufferPoint> BufferPointVector;
|
|||
|
||||
Q_DECLARE_METATYPE(BufferPointVector)
|
||||
|
||||
/// Simple throttle for limiting bandwidth on a per-second basis.
|
||||
class Throttle {
|
||||
public:
|
||||
|
||||
Throttle();
|
||||
|
||||
/// Sets the per-second limit.
|
||||
void setLimit(int limit) { _limit = limit; }
|
||||
|
||||
/// Determines whether the message with the given size should be throttled (discarded). If not, registers the message
|
||||
/// as having been processed (i.e., contributing to later throttling).
|
||||
bool shouldThrottle(int bytes);
|
||||
|
||||
private:
|
||||
|
||||
int _limit;
|
||||
int _total;
|
||||
|
||||
typedef QPair<qint64, int> Bucket;
|
||||
QList<Bucket> _buckets;
|
||||
};
|
||||
|
||||
/// A client session associated with a single server.
|
||||
class MetavoxelSystemClient : public MetavoxelClient {
|
||||
Q_OBJECT
|
||||
|
@ -161,6 +185,9 @@ private:
|
|||
MetavoxelData _augmentedData;
|
||||
MetavoxelData _renderedAugmentedData;
|
||||
QReadWriteLock _augmentedDataLock;
|
||||
|
||||
Throttle _sendThrottle;
|
||||
Throttle _receiveThrottle;
|
||||
};
|
||||
|
||||
/// Base class for cached static buffers.
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "Application.h"
|
||||
#include "MetavoxelNetworkSimulator.h"
|
||||
|
||||
const int BYTES_PER_KILOBYTE = 1024;
|
||||
|
||||
MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() :
|
||||
QWidget(Application::getInstance()->getGLWidget(), Qt::Dialog) {
|
||||
|
||||
|
@ -58,6 +60,13 @@ MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() :
|
|||
connect(_maximumDelay, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||
|
||||
form->addRow("Bandwidth Limit:", _bandwidthLimit = new QSpinBox());
|
||||
_bandwidthLimit->setMaximum(1024 * 1024);
|
||||
_bandwidthLimit->setSuffix("KB/s");
|
||||
_bandwidthLimit->setValue(simulation.bandwidthLimit / BYTES_PER_KILOBYTE);
|
||||
connect(_bandwidthLimit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok, this);
|
||||
topLayout->addWidget(buttons);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QWidget::close);
|
||||
|
@ -66,7 +75,13 @@ MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() :
|
|||
}
|
||||
|
||||
void MetavoxelNetworkSimulator::updateMetavoxelSystem() {
|
||||
int bandwidthLimit = _bandwidthLimit->value() * BYTES_PER_KILOBYTE;
|
||||
if (bandwidthLimit > 0) {
|
||||
// make sure the limit is enough to let at least one packet through
|
||||
const int MINIMUM_BANDWIDTH_LIMIT = 2048;
|
||||
bandwidthLimit = qMax(bandwidthLimit, MINIMUM_BANDWIDTH_LIMIT);
|
||||
}
|
||||
Application::getInstance()->getMetavoxels()->setNetworkSimulation(MetavoxelSystem::NetworkSimulation(
|
||||
_dropRate->value() / 100.0, _repeatRate->value() / 100.0, qMin(_minimumDelay->value(), _maximumDelay->value()),
|
||||
qMax(_minimumDelay->value(), _maximumDelay->value())));
|
||||
qMax(_minimumDelay->value(), _maximumDelay->value()), bandwidthLimit));
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ private:
|
|||
QDoubleSpinBox* _repeatRate;
|
||||
QSpinBox* _minimumDelay;
|
||||
QSpinBox* _maximumDelay;
|
||||
QSpinBox* _bandwidthLimit;
|
||||
};
|
||||
|
||||
#endif // hifi_MetavoxelNetworkSimulator_h
|
||||
|
|
Loading…
Reference in a new issue