mirror of
https://github.com/overte-org/overte.git
synced 2025-08-11 09:20:48 +02:00
Better monitoring of the resource loading in flights
This commit is contained in:
parent
6154611b05
commit
ee5de175eb
5 changed files with 252 additions and 88 deletions
|
@ -325,7 +325,11 @@ QVariantList ResourceCache::getResourceList() {
|
||||||
BLOCKING_INVOKE_METHOD(this, "getResourceList",
|
BLOCKING_INVOKE_METHOD(this, "getResourceList",
|
||||||
Q_RETURN_ARG(QVariantList, list));
|
Q_RETURN_ARG(QVariantList, list));
|
||||||
} else {
|
} else {
|
||||||
auto resources = _resources.uniqueKeys();
|
QList<QUrl> resources;
|
||||||
|
{
|
||||||
|
QReadLocker locker(&_resourcesLock);
|
||||||
|
resources = _resources.uniqueKeys();
|
||||||
|
}
|
||||||
list.reserve(resources.size());
|
list.reserve(resources.size());
|
||||||
for (auto& resource : resources) {
|
for (auto& resource : resources) {
|
||||||
list << resource;
|
list << resource;
|
||||||
|
@ -379,6 +383,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
|
_numLoadingResources++;
|
||||||
resource = createResource(url);
|
resource = createResource(url);
|
||||||
resource->setExtra(extra);
|
resource->setExtra(extra);
|
||||||
resource->setExtraHash(extraHash);
|
resource->setExtraHash(extraHash);
|
||||||
|
@ -386,6 +391,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
|
||||||
resource->setCache(this);
|
resource->setCache(this);
|
||||||
resource->moveToThread(qApp->thread());
|
resource->moveToThread(qApp->thread());
|
||||||
connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize);
|
connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize);
|
||||||
|
connect(resource.data(), &Resource::finished, this, &ResourceCache::decreaseNumLoading);
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&_resourcesLock);
|
QWriteLocker locker(&_resourcesLock);
|
||||||
_resources[url].insert(extraHash, resource);
|
_resources[url].insert(extraHash, resource);
|
||||||
|
@ -513,6 +519,11 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) {
|
||||||
emit dirty();
|
emit dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceCache::decreaseNumLoading() {
|
||||||
|
_numLoadingResources--;
|
||||||
|
emit dirty();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QSharedPointer<Resource>> ResourceCache::getLoadingRequests() {
|
QList<QSharedPointer<Resource>> ResourceCache::getLoadingRequests() {
|
||||||
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests();
|
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests();
|
||||||
}
|
}
|
||||||
|
@ -530,7 +541,7 @@ bool ResourceCache::attemptRequest(QSharedPointer<Resource> resource) {
|
||||||
|
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
if (sharedItems->appendRequest(resource)) {
|
if (sharedItems->appendRequest(resource)) {
|
||||||
resource->makeRequest();
|
resource->makeRequest();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -201,6 +201,7 @@ class ResourceCache : public QObject {
|
||||||
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
|
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
|
||||||
|
|
||||||
Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty)
|
Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty)
|
||||||
|
Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -208,10 +209,13 @@ public:
|
||||||
size_t getSizeTotalResources() const { return _totalResourcesSize; }
|
size_t getSizeTotalResources() const { return _totalResourcesSize; }
|
||||||
size_t getNumCachedResources() const { return _numUnusedResources; }
|
size_t getNumCachedResources() const { return _numUnusedResources; }
|
||||||
size_t getSizeCachedResources() const { return _unusedResourcesSize; }
|
size_t getSizeCachedResources() const { return _unusedResourcesSize; }
|
||||||
size_t getSizeCachedResources() const { return _unusedResourcesSize; }
|
size_t getNumPendingResources() const { return _numPendingResources; }
|
||||||
|
size_t getNumLoadingResources() const { return _numLoadingResources; }
|
||||||
|
|
||||||
Q_INVOKABLE QVariantList getResourceList();
|
Q_INVOKABLE QVariantList getResourceList();
|
||||||
|
|
||||||
|
Q_INVOKABLE void decreaseNumLoading();
|
||||||
|
|
||||||
static void setRequestLimit(uint32_t limit);
|
static void setRequestLimit(uint32_t limit);
|
||||||
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
|
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
|
||||||
|
|
||||||
|
@ -292,6 +296,8 @@ private:
|
||||||
|
|
||||||
std::atomic<size_t> _numTotalResources { 0 };
|
std::atomic<size_t> _numTotalResources { 0 };
|
||||||
std::atomic<qint64> _totalResourcesSize { 0 };
|
std::atomic<qint64> _totalResourcesSize { 0 };
|
||||||
|
std::atomic<size_t> _numPendingResources{ 0 };
|
||||||
|
std::atomic<size_t> _numLoadingResources{ 0 };
|
||||||
|
|
||||||
// Cached resources
|
// Cached resources
|
||||||
QMap<int, QSharedPointer<Resource>> _unusedResources;
|
QMap<int, QSharedPointer<Resource>> _unusedResources;
|
||||||
|
@ -320,6 +326,12 @@ class ScriptableResourceCache : public QObject {
|
||||||
Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty)
|
Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty)
|
||||||
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
|
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
|
||||||
|
|
||||||
|
Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty)
|
||||||
|
Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty)
|
||||||
|
|
||||||
|
Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty)
|
||||||
|
Q_PROPERTY(size_t numGlobalQueriesLoading READ getNumGlobalQueriesLoading NOTIFY dirty)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache);
|
ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache);
|
||||||
|
|
||||||
|
@ -393,6 +405,11 @@ private:
|
||||||
size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); }
|
size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); }
|
||||||
size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); }
|
size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); }
|
||||||
size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); }
|
size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); }
|
||||||
|
size_t getNumPendingResources() const { return _resourceCache->getNumPendingResources(); }
|
||||||
|
size_t getNumLoadingResources() const { return _resourceCache->getNumLoadingResources(); }
|
||||||
|
|
||||||
|
size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); }
|
||||||
|
size_t getNumGlobalQueriesLoading() const { return ResourceCache::getPendingRequestCount(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for resources.
|
/// Base class for resources.
|
||||||
|
|
139
scripts/developer/utilities/cache/cash.qml
vendored
139
scripts/developer/utilities/cache/cash.qml
vendored
|
@ -34,6 +34,99 @@ Rectangle {
|
||||||
id: column
|
id: column
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
Prop.PropFolderPanel {
|
||||||
|
label: "Resource Queries Inspector"
|
||||||
|
isUnfold: true
|
||||||
|
panelFrameData: Component {
|
||||||
|
Column {
|
||||||
|
PlotPerf {
|
||||||
|
title: "Global Queries"
|
||||||
|
height: 80
|
||||||
|
valueScale: 1
|
||||||
|
valueUnit: ""
|
||||||
|
plots: [
|
||||||
|
{
|
||||||
|
object: ModelCache,
|
||||||
|
prop: "numGlobalQueriesPending",
|
||||||
|
label: "Pending",
|
||||||
|
color: "#1AC567"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: ModelCache,
|
||||||
|
prop: "numGlobalQueriesLoading",
|
||||||
|
label: "Loading",
|
||||||
|
color: "#FEC567"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: ModelCache,
|
||||||
|
prop: "numLoading",
|
||||||
|
label: "Model Loading",
|
||||||
|
color: "#C5FE67"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropFolderPanel {
|
||||||
|
label: "Cache Inspectors"
|
||||||
|
isUnfold: true
|
||||||
|
panelFrameData: Component {
|
||||||
|
Column {
|
||||||
|
Prop.PropButton {
|
||||||
|
text: "Model"
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: "openModelCacheInspector"});
|
||||||
|
}
|
||||||
|
width:column.width
|
||||||
|
}
|
||||||
|
Prop.PropButton {
|
||||||
|
text: "Material"
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: "openMaterialCacheInspector"});
|
||||||
|
}
|
||||||
|
width:column.width
|
||||||
|
}
|
||||||
|
Prop.PropButton {
|
||||||
|
text: "Texture"
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: "openTextureCacheInspector"});
|
||||||
|
}
|
||||||
|
width:column.width
|
||||||
|
}
|
||||||
|
Prop.PropButton {
|
||||||
|
text: "Animation"
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: "openAnimationCacheInspector"});
|
||||||
|
}
|
||||||
|
width:column.width
|
||||||
|
}
|
||||||
|
Prop.PropButton {
|
||||||
|
text: "Sound"
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: "openSoundCacheInspector"});
|
||||||
|
}
|
||||||
|
width:column.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropScalar {
|
||||||
|
label: "Texture Loading"
|
||||||
|
object: TextureCache
|
||||||
|
property: "numLoading"
|
||||||
|
integral: true
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
Prop.PropScalar {
|
||||||
|
label: "Model Loading"
|
||||||
|
object: ModelCache
|
||||||
|
property: "numLoading"
|
||||||
|
integral: true
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Prop.PropFolderPanel {
|
Prop.PropFolderPanel {
|
||||||
label: "Stats"
|
label: "Stats"
|
||||||
isUnfold: true
|
isUnfold: true
|
||||||
|
@ -81,51 +174,7 @@ Rectangle {
|
||||||
color: "#FFB4EF"
|
color: "#FFB4EF"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}}
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
Prop.PropFolderPanel {
|
|
||||||
label: "Cache Inspectors"
|
|
||||||
isUnfold: true
|
|
||||||
panelFrameData: Component {
|
|
||||||
Column {
|
|
||||||
Prop.PropButton {
|
|
||||||
text: "Model"
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: "openModelCacheInspector"});
|
|
||||||
}
|
|
||||||
width:column.width
|
|
||||||
}
|
|
||||||
Prop.PropButton {
|
|
||||||
text: "Material"
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: "openMaterialCacheInspector"});
|
|
||||||
}
|
|
||||||
width:column.width
|
|
||||||
}
|
|
||||||
Prop.PropButton {
|
|
||||||
text: "Texture"
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: "openTextureCacheInspector"});
|
|
||||||
}
|
|
||||||
width:column.width
|
|
||||||
}
|
|
||||||
Prop.PropButton {
|
|
||||||
text: "Animation"
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: "openAnimationCacheInspector"});
|
|
||||||
}
|
|
||||||
width:column.width
|
|
||||||
}
|
|
||||||
Prop.PropButton {
|
|
||||||
text: "Sound"
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: "openSoundCacheInspector"});
|
|
||||||
}
|
|
||||||
width:column.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
import QtQuick 2.7
|
import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.5
|
import QtQuick.Controls 2.5
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
@ -36,18 +36,39 @@ Item {
|
||||||
if (cache !== undefined) {
|
if (cache !== undefined) {
|
||||||
theList = cache.getResourceList();
|
theList = cache.getResourceList();
|
||||||
} else {
|
} else {
|
||||||
theList = [{"name": "ResourceCacheInspector.cache is undefined"}];
|
theList = ["ResourceCacheInspector.cache is undefined"];
|
||||||
}
|
}
|
||||||
return theList;
|
var theListString = new Array(theList.length)
|
||||||
|
for (var i in theList) {
|
||||||
|
theListString[i] = (theList[i].toString())
|
||||||
|
}
|
||||||
|
return theListString;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetItemListFromCache() {
|
function resetItemListFromCache() {
|
||||||
resourceItemsModel.resetItemList(fetchItemsList())
|
resetItemList(fetchItemsList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var needFreshList : false
|
||||||
|
|
||||||
function updateItemListFromCache() {
|
function updateItemListFromCache() {
|
||||||
resourceItemsModel.updateItemList(fetchItemsList())
|
needFreshList = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1000; running: true; repeat: true
|
||||||
|
onTriggered: pullFreshValues()
|
||||||
|
}
|
||||||
|
|
||||||
|
function pullFreshValues() {
|
||||||
|
if (needFreshList) {
|
||||||
|
console.log("Updating " + cacheResourceName + "cache list")
|
||||||
|
updateItemList(fetchItemsList())
|
||||||
|
needFreshList = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
|
@ -77,7 +98,7 @@ Item {
|
||||||
property: "numTotal"
|
property: "numTotal"
|
||||||
integral: true
|
integral: true
|
||||||
readOnly: true
|
readOnly: true
|
||||||
onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() }
|
onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() }
|
||||||
}
|
}
|
||||||
Prop.PropScalar {
|
Prop.PropScalar {
|
||||||
id: cachedCount
|
id: cachedCount
|
||||||
|
@ -88,7 +109,7 @@ Item {
|
||||||
property: "numCached"
|
property: "numCached"
|
||||||
integral: true
|
integral: true
|
||||||
readOnly: true
|
readOnly: true
|
||||||
onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() }
|
onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() }
|
||||||
}
|
}
|
||||||
height: totalCount.height
|
height: totalCount.height
|
||||||
}
|
}
|
||||||
|
@ -97,26 +118,81 @@ Item {
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: resourceItemsModel
|
id: resourceItemsModel
|
||||||
|
}
|
||||||
|
property var currentItemsList: new Array();
|
||||||
|
|
||||||
function packItemEntry(item) {
|
function packItemEntry(item) {
|
||||||
var some_uri = Qt.resolvedUrl(item)
|
var entry = { "name": "", "root": "", "path": "", "base": "", "url": item}
|
||||||
|
if (item.length > 0) {
|
||||||
return { "name": item, "url": some_uri}
|
var rootPos = item.search("://")
|
||||||
|
entry.root = item.substring(0, rootPos)
|
||||||
|
if (rootPos >= 0) rootPos += 3
|
||||||
|
entry.path = item.substring(rootPos, item.length)
|
||||||
|
var splitted = entry.path.split('/')
|
||||||
|
entry.name = splitted[splitted.length - 1]
|
||||||
|
entry.base = splitted[0]
|
||||||
}
|
}
|
||||||
|
return entry
|
||||||
|
}
|
||||||
|
|
||||||
function resetItemList(itemList) {
|
function resetItemList(itemList) {
|
||||||
resourceItemsModel.clear()
|
currentItemsList = []
|
||||||
for (var i in itemList) {
|
resourceItemsModel.clear()
|
||||||
resourceItemsModel.append(packItemEntry(itemList[i]))
|
for (var i in itemList) {
|
||||||
|
var item = itemList[i]
|
||||||
|
currentItemsList.push(item)
|
||||||
|
resourceItemsModel.append(packItemEntry(item))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateItemList(newItemList) {
|
||||||
|
resetItemList(newItemList)
|
||||||
|
/*
|
||||||
|
var nextListLength = (currentItemList.length < newItemList.length ? newItemList.length : currentItemList.length )
|
||||||
|
var nextList = new Array(nextListLength)
|
||||||
|
|
||||||
|
var addedList = []
|
||||||
|
var removedList = []
|
||||||
|
var movedList = []
|
||||||
|
|
||||||
|
for (var i in currentItemList) {
|
||||||
|
var item = currentItemList[i]
|
||||||
|
var foundPos = newItemList.findIndex(item)
|
||||||
|
if (foundPos == i) {
|
||||||
|
newList[i] = item
|
||||||
|
newItemList[i] = 0
|
||||||
|
} else if (foundPos == -1) {
|
||||||
|
removedList.push(i)
|
||||||
|
} else {
|
||||||
|
movedList.push([i,foundPos])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateItemList(itemList) {
|
for (var i in newItemList) {
|
||||||
resourceItemsModel.clear()
|
var item = newItemList[i]
|
||||||
for (var i in itemList) {
|
if (item != 0) {
|
||||||
resourceItemsModel.append(packItemEntry(itemList[i]))
|
var foundPos = currentItemList.findIndex(item)
|
||||||
|
if (foundPos == -1) {
|
||||||
|
addedList.push(item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (var i in itemList) {
|
||||||
|
newList[i] = itemList[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*currentItemsList.clear()
|
||||||
|
resourceItemsModel.clear()
|
||||||
|
for (var i in itemList) {
|
||||||
|
currentItemsList.append(itemList[i].toString())
|
||||||
|
resourceItemsModel.append(packItemEntry(currentItemsList[i]))
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
@ -131,24 +207,35 @@ Item {
|
||||||
size:8
|
size:8
|
||||||
}
|
}
|
||||||
Prop.PropLabel {
|
Prop.PropLabel {
|
||||||
text: JSON.stringify(model.url)
|
text: model.root
|
||||||
|
width: 30
|
||||||
}
|
}
|
||||||
/* Prop.PropLabel {
|
Prop.PropSplitter {
|
||||||
text: model.url
|
size:8
|
||||||
}*/
|
}
|
||||||
|
Prop.PropLabel {
|
||||||
|
text: model.base
|
||||||
|
width: 60
|
||||||
|
}
|
||||||
|
Prop.PropSplitter {
|
||||||
|
size:8
|
||||||
|
}
|
||||||
|
Prop.PropLabel {
|
||||||
|
text: model.name
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
ListView {
|
||||||
anchors.top: header.bottom
|
anchors.top: header.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
clip: true
|
clip: true
|
||||||
ListView {
|
|
||||||
id: listView
|
id: listView
|
||||||
model: resourceItemsModel
|
model: resourceItemsModel
|
||||||
delegate: resouceItemDelegate
|
delegate: resouceItemDelegate
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,12 +91,12 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Original.ScrollView {
|
ListView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
ListView {
|
|
||||||
id: theView
|
id: theView
|
||||||
model: jobsModel
|
model: jobsModel
|
||||||
delegate: objRecursiveDelegate
|
delegate: objRecursiveDelegate
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue