mirror of
https://github.com/overte-org/overte.git
synced 2025-08-18 18:36:34 +02:00
Add AssetRequest
This commit is contained in:
parent
cf20701275
commit
260404f1fb
2 changed files with 158 additions and 0 deletions
78
libraries/networking/src/AssetRequest.cpp
Normal file
78
libraries/networking/src/AssetRequest.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// AssetRequest.cpp
|
||||
//
|
||||
// Created by Ryan Huffman on 2015/07/24
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "AssetRequest.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "AssetClient.h"
|
||||
#include "NodeList.h"
|
||||
|
||||
|
||||
AssetRequest::AssetRequest(QObject* parent, QString hash) :
|
||||
QObject(parent),
|
||||
_hash(hash)
|
||||
{
|
||||
}
|
||||
|
||||
void AssetRequest::start() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "start", Qt::AutoConnection);
|
||||
//(&AssetRequest::start)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_state == NOT_STARTED) {
|
||||
_state = WAITING_FOR_INFO;
|
||||
|
||||
auto assetClient = DependencyManager::get<AssetClient>();
|
||||
assetClient->getAssetInfo(_hash, [this](bool success, AssetInfo info) {
|
||||
_info = info;
|
||||
_data.resize(info.size);
|
||||
const DataOffset CHUNK_SIZE = 1024;
|
||||
|
||||
qDebug() << "Got size of " << _hash << " : " << info.size << " bytes";
|
||||
|
||||
// Round up
|
||||
int numChunks = (info.size + CHUNK_SIZE - 1) / CHUNK_SIZE;
|
||||
auto assetClient = DependencyManager::get<AssetClient>();
|
||||
for (int i = 0; i < numChunks; ++i) {
|
||||
++_numPendingRequests;
|
||||
auto start = i * CHUNK_SIZE;
|
||||
auto end = std::min((i + 1) * CHUNK_SIZE, info.size);
|
||||
assetClient->getAsset(_hash, start, end, [this, start, end](bool success, QByteArray data) {
|
||||
Q_ASSERT(data.size() == (end - start));
|
||||
|
||||
if (success) {
|
||||
_result = Success;
|
||||
memcpy((_data.data() + start), data.constData(), end - start);
|
||||
_totalReceived += data.size();
|
||||
emit progress(_totalReceived, _info.size);
|
||||
} else {
|
||||
_result = Error;
|
||||
qDebug() << "Got error retrieving asset";
|
||||
}
|
||||
|
||||
--_numPendingRequests;
|
||||
if (_numPendingRequests == 0) {
|
||||
_state = FINISHED;
|
||||
emit finished(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const QByteArray& AssetRequest::getData() {
|
||||
return _data;
|
||||
}
|
80
libraries/networking/src/AssetRequest.h
Normal file
80
libraries/networking/src/AssetRequest.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// AssetRequest.h
|
||||
//
|
||||
// Created by Ryan Huffman on 2015/07/24
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// 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_AssetRequest_h
|
||||
#define hifi_AssetRequest_h
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include "AssetClient.h"
|
||||
|
||||
#include "AssetUtils.h"
|
||||
|
||||
// You should be able to get an asset from any thread, and handle the responses in a safe way
|
||||
// on your own thread. Everything should happen on AssetClient's thread, the caller should
|
||||
// receive events by connecting to signals on an object that lives on AssetClient's threads.
|
||||
|
||||
// Receives parts of an asset and puts them together
|
||||
// Emits signals:
|
||||
// Progress
|
||||
// Completion, success or error
|
||||
// On finished, the AssetClient is effectively immutable and can be read from
|
||||
// any thread safely
|
||||
//
|
||||
// Will often make multiple requests to the AssetClient to get data
|
||||
class AssetRequest : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum State {
|
||||
NOT_STARTED = 0,
|
||||
WAITING_FOR_INFO,
|
||||
WAITING_FOR_DATA,
|
||||
FINISHED
|
||||
};
|
||||
|
||||
enum Result {
|
||||
Success = 0,
|
||||
Timeout,
|
||||
NotFound,
|
||||
Error,
|
||||
};
|
||||
|
||||
AssetRequest(QObject* parent, QString hash);
|
||||
|
||||
Q_INVOKABLE void start();
|
||||
//AssetRequest* requestAsset(QString hash);
|
||||
// Create AssetRequest
|
||||
// Start request for hash
|
||||
// Store messageID -> AssetRequest
|
||||
// When complete:
|
||||
// Update AssetRequest
|
||||
// AssetRequest emits signal
|
||||
|
||||
void receiveData(DataOffset start, DataOffset end, QByteArray data);
|
||||
const QByteArray& getData();
|
||||
|
||||
signals:
|
||||
void finished(AssetRequest*);
|
||||
void progress(uint64_t totalReceived, uint64_t total);
|
||||
|
||||
private:
|
||||
State _state = NOT_STARTED;
|
||||
Result _result;
|
||||
AssetInfo _info;
|
||||
uint64_t _totalReceived { 0 };
|
||||
QString _hash;
|
||||
QByteArray _data;
|
||||
int _numPendingRequests { 0 };
|
||||
// Timeout
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue