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) : ScriptableResource::ScriptableResource(const QUrl& url) :
QObject(nullptr), 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() { void ScriptableResource::release() {
disconnectHelper(); 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) { void ScriptableResource::finished(bool success) {
disconnectHelper(); disconnectHelper();
_isLoaded = true; emit stateChanged(success ? FINISHED : FAILED);
_isFailed = !success;
if (_isFailed) {
emit failedChanged(_isFailed);
}
emit loadedChanged(_isLoaded);
} }
void ScriptableResource::disconnectHelper() { void ScriptableResource::disconnectHelper() {
if (_progressConnection) { if (_progressConnection) {
disconnect(_progressConnection); disconnect(_progressConnection);
} }
if (_loadingConnection) {
disconnect(_loadingConnection);
}
if (_loadedConnection) {
disconnect(_loadedConnection);
}
if (_finishedConnection) { if (_finishedConnection) {
disconnect(_finishedConnection); disconnect(_finishedConnection);
} }
@ -180,6 +198,12 @@ ScriptableResource* ResourceCache::prefetch(const QUrl& url, void* extra) {
result->_progressConnection = connect( result->_progressConnection = connect(
resource.data(), &Resource::onProgress, resource.data(), &Resource::onProgress,
result, &ScriptableResource::progressChanged); 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( result->_finishedConnection = connect(
resource.data(), &Resource::finished, resource.data(), &Resource::finished,
result, &ScriptableResource::finished); result, &ScriptableResource::finished);
@ -644,6 +668,7 @@ void Resource::makeRequest() {
} }
qCDebug(networking).noquote() << "Starting request for:" << _url.toDisplayString(); qCDebug(networking).noquote() << "Starting request for:" << _url.toDisplayString();
emit loading();
connect(_request, &ResourceRequest::progress, this, &Resource::onProgress); connect(_request, &ResourceRequest::progress, this, &Resource::onProgress);
connect(this, &Resource::onProgress, this, &Resource::handleDownloadProgress); connect(this, &Resource::onProgress, this, &Resource::handleDownloadProgress);

View file

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

View file

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