Change ScriptableResource signal to state

This commit is contained in:
Zach Pomerantz 2016-04-27 17:12:03 -07:00
parent de8145ec71
commit 0c78d5bdd1
3 changed files with 63 additions and 23 deletions

View file

@ -121,7 +121,17 @@ QSharedPointer<Resource> ResourceCacheSharedItems::getHighestPendingRequest() {
ScriptableResource::ScriptableResource(const QUrl& url) :
QObject(nullptr),
_url(url) {}
_url(url) {
// Expose enum State to JS/QML via properties
QObject* state = new QObject(this);
state->setObjectName("ResourceState");
setProperty("State", QVariant::fromValue(state));
auto metaEnum = QMetaEnum::fromType<State>();
for (int i = 0; i < metaEnum.keyCount(); ++i) {
state->setProperty(metaEnum.key(i), metaEnum.value(i));
}
}
void ScriptableResource::release() {
disconnectHelper();
@ -135,22 +145,30 @@ void ScriptableResource::updateMemoryCost(const QObject* engine) {
}
}
void ScriptableResource::loadingChanged() {
emit stateChanged(LOADING);
}
void ScriptableResource::loadedChanged() {
emit stateChanged(LOADED);
}
void ScriptableResource::finished(bool success) {
disconnectHelper();
_isLoaded = true;
_isFailed = !success;
if (_isFailed) {
emit failedChanged(_isFailed);
}
emit loadedChanged(_isLoaded);
emit stateChanged(success ? FINISHED : FAILED);
}
void ScriptableResource::disconnectHelper() {
if (_progressConnection) {
disconnect(_progressConnection);
}
if (_loadingConnection) {
disconnect(_loadingConnection);
}
if (_loadedConnection) {
disconnect(_loadedConnection);
}
if (_finishedConnection) {
disconnect(_finishedConnection);
}
@ -180,6 +198,12 @@ ScriptableResource* ResourceCache::prefetch(const QUrl& url, void* extra) {
result->_progressConnection = connect(
resource.data(), &Resource::onProgress,
result, &ScriptableResource::progressChanged);
result->_loadingConnection = connect(
resource.data(), &Resource::loading,
result, &ScriptableResource::loadingChanged);
result->_loadedConnection = connect(
resource.data(), &Resource::loaded,
result, &ScriptableResource::loadedChanged);
result->_finishedConnection = connect(
resource.data(), &Resource::finished,
result, &ScriptableResource::finished);
@ -644,6 +668,7 @@ void Resource::makeRequest() {
}
qCDebug(networking).noquote() << "Starting request for:" << _url.toDisplayString();
emit loading();
connect(_request, &ResourceRequest::progress, this, &Resource::onProgress);
connect(this, &Resource::onProgress, this, &Resource::handleDownloadProgress);

View file

@ -82,28 +82,36 @@ private:
class ScriptableResource : public QObject {
Q_OBJECT
Q_PROPERTY(QUrl url READ getUrl)
Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
Q_PROPERTY(bool failed READ isFailed NOTIFY failedChanged)
Q_PROPERTY(int state READ getState NOTIFY stateChanged)
public:
enum State {
QUEUED,
LOADING,
LOADED,
FINISHED,
FAILED,
};
Q_ENUM(State)
ScriptableResource(const QUrl& url);
virtual ~ScriptableResource() = default;
Q_INVOKABLE void release();
const QUrl& getUrl() const { return _url; }
bool isLoaded() const { return _isLoaded; }
bool isFailed() const { return _isFailed; }
int getState() const { return (int)_state; }
// Connects to a SLOT(updateMemoryCost(qint64) on the given engine
// Connects to a SLOT(updateMemoryCost(qint64)) on the given engine
void updateMemoryCost(const QObject* engine);
signals:
void progressChanged(uint64_t bytesReceived, uint64_t bytesTotal);
void loadedChanged(bool loaded); // analogous to &Resource::finished
void failedChanged(bool failed);
void stateChanged(int state);
private slots:
void loadingChanged();
void loadedChanged();
void finished(bool success);
private:
@ -115,11 +123,12 @@ private:
QSharedPointer<Resource> _resource;
QMetaObject::Connection _progressConnection;
QMetaObject::Connection _loadingConnection;
QMetaObject::Connection _loadedConnection;
QMetaObject::Connection _finishedConnection;
QUrl _url;
bool _isLoaded{ false };
bool _isFailed{ false };
State _state{ QUEUED };
};
Q_DECLARE_METATYPE(ScriptableResource*);
@ -287,6 +296,9 @@ public:
const QUrl& getURL() const { return _url; }
signals:
/// Fired when the resource begins downloading.
void loading();
/// Fired when the resource has been downloaded.
/// This can be used instead of downloadFinished to access data before it is processed.
void loaded(const QByteArray request);

View file

@ -22,11 +22,12 @@ function getFrame(callback) {
if (model.loaded) {
makeFrame(true);
} else {
model.loadedChanged.connect(makeFrame);
model.stateChanged.connect(makeFrame);
}
function makeFrame(success) {
if (!success) { throw "Failed to load frame"; }
function makeFrame(state) {
if (state == 4) { throw "Failed to load frame"; }
if (state != 3) { return; }
var pictureFrameProperties = {
name: 'scriptableResourceTest Picture Frame',
@ -68,9 +69,11 @@ function prefetch(callback) {
frames.push(texture);
if (!texture.loaded) {
numLoading++;
texture.loadedChanged.connect(function() {
--numLoading;
if (!numLoading) { callback(frames); }
texture.stateChanged.connect(function(state) {
if (state == 3 || state == 4) {
--numLoading;
if (!numLoading) { callback(frames); }
}
});
}
}