File: datastorage.cpp

package info (click to toggle)
qt6-declarative 6.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 308,920 kB
  • sloc: cpp: 775,911; javascript: 514,247; xml: 10,855; python: 2,806; ansic: 2,253; java: 810; sh: 262; makefile: 41; php: 27
file content (84 lines) | stat: -rw-r--r-- 2,688 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

#include "datastorage.h"
#include "queueworker.h"

DataStorage::DataStorage() : QObject{ nullptr }
{
    /* Generate a list of IDs to use locally.
     * DataStorage will use indexes for accessing the remote data.
     */
    m_idList.reserve(RemoteMedia::count());
    for (int id = 1; id <= RemoteMedia::count(); ++id) {
        m_idList.append(id);
    }
    m_worker = new QueueWorker;
    connect(&m_workerThread, &QThread::finished, m_worker, &QObject::deleteLater);
    m_worker->moveToThread(&m_workerThread);
    connect(m_worker, &QueueWorker::dataFetched, this, &DataStorage::dataReceived);
    connect(m_worker, &QueueWorker::processing, this, &DataStorage::fetchStarted);
    connect(m_worker, &QueueWorker::dropped, this, &DataStorage::fetchAborted);
    connect(this, &DataStorage::dataFetchNeeded, m_worker, &QueueWorker::fetchData);
    m_workerThread.start();
}

DataStorage::~DataStorage()
{
    /* Clean the worker object by stopping it and then ending the thread */
    m_worker->abort();
    m_worker = nullptr;
    m_workerThread.quit();
    m_workerThread.wait();
}

QList<int> DataStorage::idList()
{
    return m_idList;
}

MediaElement DataStorage::item(int id) const
{
    if (id < 1)
        return MediaElement{};
    //! [Send signal if no data]
    if (!m_items.contains(id)) {
        m_items.insert(id, MediaElement{});
        emit dataFetchNeeded(m_idList.indexOf(id));
    }
    return m_items.value(id);
    //! [Send signal if no data]
}

std::optional<int> DataStorage::currentlyFetchedId() const
{
    return m_currentlyFetchedId;
}

void DataStorage::fetchStarted(int index)
{
    const auto idBeingFetched = m_idList.at(index);
    m_currentlyFetchedId = idBeingFetched;
    emit dataUpdated(idBeingFetched);
}

void DataStorage::fetchAborted(int index)
{
    /* The data will never be fetched. Remove the empty item (so storge will send a signal to thread
     * if needed). Then send dataUpdated signal. If the item is still visible, view will re-request
     * its data and item will be requeued to thread. If item is no longer in visible area, view will
     * ignore the dataChanged signal and storage will not receive any calls.
     */
    const auto idAborted = m_idList.at(index);
    m_items.remove(idAborted);
    if (m_currentlyFetchedId == idAborted)
        m_currentlyFetchedId = std::nullopt;
    emit dataUpdated(idAborted);
}

void DataStorage::dataReceived(int index, MediaElement element)
{
    const auto idUpdated = m_idList.at(index);
    m_items.insert(idUpdated, element);
    emit dataUpdated(idUpdated);
}