Files
cinema-ticket-management-sy…/core/services/model_manager.h
T
2026-07-12 14:34:52 +04:00

114 lines
3.1 KiB
C++

#ifndef MODEL_MANAGER_H
#define MODEL_MANAGER_H
#include <QMap>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QString>
// The model manager inherits the QObject class to delete child objects
class ModelManager : public QObject {
Q_OBJECT
private:
QMap<QString, QSqlTableModel *> models_;
QSqlDatabase database_;
public:
// Get the singleton instance
static ModelManager &instance();
QStringList registeredModelTableNames() const;
QStringList registeredModelTableNames(QString databaseTableName) const;
// Get a model
QSqlTableModel *getModel(const QString &modelTableName) const;
// Get a model with a specific type
template <typename T> T *getModelAs(const QString &modelTableName) const;
// Configure filters
void resetFilter(const QString &modelTableName);
void setMultiColumnFilter(const QString &modelTableName,
const QString &filter);
private:
// Register a model
template <typename T>
bool registerModel(const QString &modelTableName, const QSqlDatabase &db);
// Initialize all models
void initialize();
// Initialize a specific model
template <typename T> void initializeIfExists(T *model);
// Private constructor for singleton pattern
ModelManager();
// Private destructor
~ModelManager();
// Disable copy constructor and assignment operator
ModelManager(const ModelManager &) = delete;
ModelManager &operator=(const ModelManager &) = delete;
};
// NOTE: Implementation of template methods
template <typename T> void ModelManager::initializeIfExists(T *model) {
if constexpr (std::is_invocable_v<decltype(&T::initialize), T *>) {
model->initialize();
} else {
qDebug() << "Method initialize() is not available, skipping...";
}
}
template <typename T>
T *ModelManager::getModelAs(const QString &modelTableName) const {
auto *model = dynamic_cast<T *>(getModel(modelTableName));
if (!model) {
qFatal() << "Failed to downcast model for" << modelTableName
<< "(typeid name):" << typeid(T).name();
return nullptr;
}
qInfo() << "Successfully downcast model for" << modelTableName;
return model;
}
template <typename T>
bool ModelManager::registerModel(const QString &modelTableName,
const QSqlDatabase &db) {
static_assert(std::is_base_of_v<QSqlTableModel, T>,
"Registered model must be derived from QSqlTableModel");
static_assert(
std::is_constructible<T, QObject *, const QSqlDatabase &>::value,
"Model class must have a constructor accepting QObject* and const "
"QSqlDatabase&");
qInfo() << "Registering model:" << modelTableName;
if (models_.contains(modelTableName)) {
qInfo() << "Model" << modelTableName << "is already registered";
return true;
}
T *model = new T(this, db); // Qt will delete the model
model->setObjectName(modelTableName);
initializeIfExists(model);
models_.insert(modelTableName, model);
qInfo() << "Model" << modelTableName
<< "with database table name:" << model->tableName()
<< "was registered successfully";
return true;
}
#endif // MODEL_MANAGER_H