You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
5.7 KiB
220 lines
5.7 KiB
/*****************************************************************************
|
|
* Copyright (C) 2023 VLC authors and VideoLAN
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* ( at your option ) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
#ifndef BASEMODEL_P_HPP
|
|
#define BASEMODEL_P_HPP
|
|
|
|
#include <memory>
|
|
#include "listcacheloader.hpp"
|
|
#include "listcache.hpp"
|
|
#include "base_model.hpp"
|
|
|
|
class BaseModelPrivate {
|
|
Q_DECLARE_PUBLIC(BaseModel)
|
|
public:
|
|
BaseModelPrivate(BaseModel * pub)
|
|
: q_ptr(pub)
|
|
{
|
|
}
|
|
virtual ~BaseModelPrivate() = default;
|
|
virtual void validateCache() const = 0;
|
|
virtual void resetCache() = 0;
|
|
virtual void invalidateCache() = 0;
|
|
virtual bool loading() const = 0;
|
|
virtual unsigned int getCount() const = 0;
|
|
virtual unsigned int getMaximumCount() const = 0;
|
|
|
|
virtual bool initializeModel() = 0;
|
|
|
|
protected:
|
|
virtual bool cachable() const
|
|
{
|
|
return !m_qmlInitializing;
|
|
}
|
|
|
|
//accessing procted functions from BaseModel must be done here
|
|
//has friendship isn't inherited
|
|
template<typename T>
|
|
void validateCacheImpl(T* cache) const
|
|
{
|
|
Q_Q(const BaseModel);
|
|
|
|
QObject::connect(cache, &T::localSizeChanged,
|
|
q, &BaseModel::onLocalSizeChanged);
|
|
|
|
QObject::connect(cache, &T::localDataChanged,
|
|
q, &BaseModel::onCacheDataChanged);
|
|
|
|
QObject::connect(cache, &T::beginInsertRows,
|
|
q, &BaseModel::onCacheBeginInsertRows);
|
|
QObject::connect(cache, &T::endInsertRows,
|
|
q, &BaseModel::endInsertRows);
|
|
|
|
QObject::connect(cache, &T::beginRemoveRows,
|
|
q, &BaseModel::onCacheBeginRemoveRows);
|
|
QObject::connect(cache, &T::endRemoveRows,
|
|
q, &BaseModel::endRemoveRows);
|
|
|
|
QObject::connect(cache, &T::endMoveRows,
|
|
q, &BaseModel::endMoveRows);
|
|
QObject::connect(cache, &T::beginMoveRows,
|
|
q, &BaseModel::onCacheBeginMoveRows);
|
|
|
|
cache->initCount();
|
|
}
|
|
|
|
template<typename T>
|
|
void resetCacheImpl(T& cache)
|
|
{
|
|
Q_Q(BaseModel);
|
|
emit q->beginResetModel();
|
|
// 'abandon' existing cache and queue it for deletion
|
|
cache->disconnect(q);
|
|
cache->deleteLater();
|
|
cache.release();
|
|
emit q->endResetModel();
|
|
validateCache();
|
|
}
|
|
|
|
template <typename T>
|
|
void invalidateCacheImpl(T& cache)
|
|
{
|
|
Q_Q(BaseModel);
|
|
if (cache)
|
|
{
|
|
cache->invalidate();
|
|
emit q->loadingChanged();
|
|
}
|
|
else
|
|
validateCache();
|
|
}
|
|
|
|
BaseModel* q_ptr = nullptr;
|
|
|
|
QString m_searchPattern = {};
|
|
Qt::SortOrder m_sortOrder = Qt::SortOrder::AscendingOrder;
|
|
QString m_sortCriteria = {};
|
|
unsigned int m_limit = 0;
|
|
unsigned int m_offset = 0;
|
|
bool m_qmlInitializing = false;
|
|
};
|
|
|
|
template<typename T>
|
|
class BaseModelPrivateT : public BaseModelPrivate
|
|
{
|
|
public:
|
|
using BaseModelPrivate::BaseModelPrivate;
|
|
virtual ~BaseModelPrivateT() = default;
|
|
|
|
public:
|
|
void validateCache() const override;
|
|
void resetCache() override;
|
|
void invalidateCache() override;
|
|
|
|
virtual bool loading() const override;
|
|
|
|
const T* item(int signedidx) const;
|
|
|
|
virtual unsigned int getCount() const override;
|
|
virtual unsigned int getMaximumCount() const override;
|
|
|
|
virtual std::unique_ptr<ListCacheLoader<T>> createLoader() const = 0;
|
|
|
|
protected:
|
|
mutable std::unique_ptr<ListCache<T>> m_cache;
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
unsigned BaseModelPrivateT<T>::getCount() const
|
|
{
|
|
if (!m_cache)
|
|
return 0;
|
|
|
|
ssize_t queryCount = m_cache->queryCount();
|
|
if (queryCount == ListCache<T>::COUNT_UNINITIALIZED)
|
|
return 0;
|
|
|
|
return static_cast<unsigned>(queryCount);
|
|
}
|
|
|
|
template<typename T>
|
|
unsigned BaseModelPrivateT<T>::getMaximumCount() const
|
|
{
|
|
if (!m_cache)
|
|
return 0;
|
|
|
|
ssize_t maximumCount = m_cache->maximumCount();
|
|
if (maximumCount == ListCache<T>::COUNT_UNINITIALIZED)
|
|
return 0;
|
|
return static_cast<unsigned>(maximumCount);
|
|
}
|
|
|
|
template<typename T>
|
|
const T* BaseModelPrivateT<T>::item(int signedidx) const
|
|
{
|
|
if (!m_cache)
|
|
return nullptr;
|
|
|
|
ssize_t count = m_cache->queryCount();
|
|
|
|
if (count == 0 || signedidx < 0 || signedidx >= count)
|
|
return nullptr;
|
|
|
|
unsigned int idx = static_cast<unsigned int>(signedidx);
|
|
|
|
m_cache->refer(idx);
|
|
|
|
return m_cache->get(idx);
|
|
}
|
|
|
|
template<typename T>
|
|
void BaseModelPrivateT<T>::validateCache() const
|
|
{
|
|
if (m_cache)
|
|
return;
|
|
|
|
if (!cachable())
|
|
return;
|
|
|
|
auto loader = createLoader();
|
|
m_cache = std::make_unique<ListCache<T>>(std::move(loader), false, m_limit, m_offset);
|
|
validateCacheImpl(m_cache.get());
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
void BaseModelPrivateT<T>::resetCache()
|
|
{
|
|
resetCacheImpl(m_cache);
|
|
}
|
|
|
|
template<typename T>
|
|
void BaseModelPrivateT<T>::invalidateCache()
|
|
{
|
|
invalidateCacheImpl(m_cache);
|
|
}
|
|
|
|
template<typename T>
|
|
bool BaseModelPrivateT<T>::loading() const
|
|
{
|
|
bool loading = !m_cache || (m_cache->queryCount() == ListCache<T>::COUNT_UNINITIALIZED);
|
|
return loading;
|
|
}
|
|
|
|
#endif // BASEMODEL_P_HPP
|
|
|