Use QML WorkerScript for loading and updating models
This commit is contained in:
parent
376b3225f6
commit
d8fd1ff3dd
6 changed files with 126 additions and 33 deletions
|
@ -62,6 +62,10 @@ ListModel {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var worker: ModelWorkerScript {
|
||||||
|
id: modelWorker
|
||||||
|
}
|
||||||
|
|
||||||
function forEachEpisode(callback) {
|
function forEachEpisode(callback) {
|
||||||
// Go from bottom up (= chronological order)
|
// Go from bottom up (= chronological order)
|
||||||
for (var i=count-1; i>=0; i--) {
|
for (var i=count-1; i>=0; i--) {
|
||||||
|
@ -122,11 +126,12 @@ ListModel {
|
||||||
|
|
||||||
ready = false;
|
ready = false;
|
||||||
py.call('main.load_episodes', [podcast_id, query], function (episodes) {
|
py.call('main.load_episodes', [podcast_id, query], function (episodes) {
|
||||||
Util.updateModelFrom(episodeListModel, episodes);
|
modelWorker.updateModelFrom(episodeListModel, episodes, function () {
|
||||||
episodeListModel.ready = true;
|
episodeListModel.ready = true;
|
||||||
if (callback !== undefined) {
|
if (callback !== undefined) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@ Connections {
|
||||||
target: py
|
target: py
|
||||||
|
|
||||||
onDownloadProgress: {
|
onDownloadProgress: {
|
||||||
Util.updateModelWith(episodeListModel, 'id', episode_id,
|
episodeListModel.worker.updateModelWith(episodeListModel, 'id', episode_id,
|
||||||
{'progress': progress});
|
{'progress': progress});
|
||||||
}
|
}
|
||||||
onPlaybackProgress: {
|
onPlaybackProgress: {
|
||||||
Util.updateModelWith(episodeListModel, 'id', episode_id,
|
episodeListModel.worker.updateModelWith(episodeListModel, 'id', episode_id,
|
||||||
{'playbackProgress': progress});
|
{'playbackProgress': progress});
|
||||||
}
|
}
|
||||||
onUpdatedEpisode: {
|
onUpdatedEpisode: {
|
||||||
|
|
|
@ -25,9 +25,13 @@ import 'util.js' as Util
|
||||||
ListModel {
|
ListModel {
|
||||||
id: podcastListModel
|
id: podcastListModel
|
||||||
|
|
||||||
|
property var worker: ModelWorkerScript {
|
||||||
|
id: modelWorker
|
||||||
|
}
|
||||||
|
|
||||||
function reload() {
|
function reload() {
|
||||||
py.call('main.load_podcasts', [], function (podcasts) {
|
py.call('main.load_podcasts', [], function (podcasts) {
|
||||||
Util.updateModelFrom(podcastListModel, podcasts);
|
modelWorker.updateModelFrom(podcastListModel, podcasts);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
67
common/ModelWorkerScript.qml
Normal file
67
common/ModelWorkerScript.qml
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* gPodder QML UI Reference Implementation
|
||||||
|
* Copyright (c) 2015, Thomas Perl <m@thp.io>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
|
||||||
|
WorkerScript {
|
||||||
|
source: 'modelworker.js'
|
||||||
|
|
||||||
|
property int callbacks_seq: 1
|
||||||
|
property var callbacks: ({})
|
||||||
|
|
||||||
|
function refCallback(callback) {
|
||||||
|
var id = callbacks_seq++;
|
||||||
|
callbacks[id] = callback;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unrefCallback(callback) {
|
||||||
|
var result = callbacks[callback];
|
||||||
|
delete callbacks[callback];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateModelFrom(model, data, callback) {
|
||||||
|
sendMessage({
|
||||||
|
action: 'updateModelFrom',
|
||||||
|
model: model,
|
||||||
|
data: data,
|
||||||
|
callback: refCallback(callback),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateModelWith(model, key, value, update, callback) {
|
||||||
|
sendMessage({
|
||||||
|
action: 'updateModelWith',
|
||||||
|
model: model,
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
update: update,
|
||||||
|
callback: refCallback(callback),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage: {
|
||||||
|
if (messageObject.callback !== undefined) {
|
||||||
|
unrefCallback(messageObject.callback)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
common/modelworker.js
Normal file
42
common/modelworker.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
function updateModelFrom(model, data) {
|
||||||
|
// TODO: This is very naive at the moment, we should do proper remove(),
|
||||||
|
// move(), set() and insert() calls, so that the UI can animate changes.
|
||||||
|
for (var i=0; i<data.length; i++) {
|
||||||
|
if (model.count < i) {
|
||||||
|
model.append(data[i]);
|
||||||
|
} else {
|
||||||
|
model.set(i, data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (model.count > data.length) {
|
||||||
|
model.remove(model.count-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateModelWith(model, key, value, update) {
|
||||||
|
for (var row=0; row<model.count; row++) {
|
||||||
|
var current = model.get(row);
|
||||||
|
if (current[key] == value) {
|
||||||
|
for (var key in update) {
|
||||||
|
model.setProperty(row, key, update[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkerScript.onMessage = function (msg) {
|
||||||
|
if (msg.action === 'updateModelFrom') {
|
||||||
|
updateModelFrom(msg.model, msg.data);
|
||||||
|
WorkerScript.sendMessage({callback: msg.callback});
|
||||||
|
} else if (msg.action === 'updateModelWith') {
|
||||||
|
updateModelWith(msg.model, msg.key, msg.value, msg.update);
|
||||||
|
WorkerScript.sendMessage({callback: msg.callback});
|
||||||
|
} else {
|
||||||
|
console.log('Unknown action: ' + msg.action);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,31 +18,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function updateModelFrom(model, data) {
|
|
||||||
for (var i=0; i<data.length; i++) {
|
|
||||||
if (model.count < i) {
|
|
||||||
model.append(data[i]);
|
|
||||||
} else {
|
|
||||||
model.set(i, data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (model.count > data.length) {
|
|
||||||
model.remove(model.count-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateModelWith(model, key, value, update) {
|
|
||||||
for (var row=0; row<model.count; row++) {
|
|
||||||
var current = model.get(row);
|
|
||||||
if (current[key] == value) {
|
|
||||||
for (var key in update) {
|
|
||||||
model.setProperty(row, key, update[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDuration(duration) {
|
function formatDuration(duration) {
|
||||||
if (duration !== 0 && !duration) {
|
if (duration !== 0 && !duration) {
|
||||||
return ''
|
return ''
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue