Mercurial > hg > svcore
changeset 1731:601851995f4b by-id
Introduce Model to ById
author | Chris Cannam |
---|---|
date | Fri, 21 Jun 2019 13:37:00 +0100 |
parents | abd8b9673028 |
children | 87b4c596c0ef |
files | base/ById.cpp base/ById.h data/model/Model.cpp data/model/Model.h data/model/WritableWaveFileModel.cpp files.pri |
diffstat | 6 files changed, 74 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/base/ById.cpp Thu Jun 20 14:57:39 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - Centre for Digital Music, Queen Mary, University of London. - - 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. See the file - COPYING included with this distribution for more information. -*/ - -#include "ById.h" - -#include <QMutex> - -#include <climits> - -int -WithId::getNextId() -{ - static int nextId = 0; - static QMutex mutex; - QMutexLocker locker(&mutex); - int i = nextId; - if (nextId == INT_MAX) { - nextId = INT_MIN; - } - ++nextId; - return i; -}
--- a/base/ById.h Thu Jun 20 14:57:39 2019 +0100 +++ b/base/ById.h Fri Jun 21 13:37:00 2019 +0100 @@ -17,31 +17,77 @@ #include <memory> #include <map> +#include <typeinfo> +#include <iostream> +#include <climits> #include <QMutex> +#include <QString> -typedef int Id; +template <typename T> +struct SvId { + int id; + bool operator<(const SvId &other) const { return id < other.id; } + + QString toString() const { + return QString("%1").arg(id); + } +}; + +template <typename T> class WithId { public: + typedef SvId<T> Id; + WithId() : m_id(getNextId()) { } + /** + * Return an id for this object. The id is a unique identifier for + * this object among all objects that implement WithId within this + * single run of the application. + */ Id getId() const { - return m_id; + Id id; + id.id = m_id; + return id; } private: - Id m_id; - static int getNextId(); + int m_id; + + static int getNextId() { + static int nextId = 0; + static QMutex mutex; + QMutexLocker locker(&mutex); + int i = nextId; + if (nextId == INT_MAX) { + nextId = INT_MIN; + } + ++nextId; + return i; + } }; -template <typename Item> +template <typename Item, typename Id> class ById { public: + ~ById() { + QMutexLocker locker(&m_mutex); + for (const auto &p: m_items) { + if (p.second && p.second.use_count() > 0) { + std::cerr << "WARNING: ById map destroyed with use count of " + << p.second.use_count() << " for item with type " + << typeid(*p.second.get()).name() + << " and id " << p.first.id << std::endl; + } + } + } + void add(std::shared_ptr<Item> item) { QMutexLocker locker(&m_mutex); m_items[item->getId()] = item; @@ -72,34 +118,36 @@ mutable QMutex m_mutex; std::map<Id, std::shared_ptr<Item>> m_items; }; -/* -class Imagined : public WithId { -}; -class ImaginedById +template <typename Item, typename Id> +class StaticById { public: - static void add(std::shared_ptr<Imagined> imagined) { - m_byId.add(imagined); + static void add(std::shared_ptr<Item> imagined) { + byId().add(imagined); } static void release(Id id) { - m_byId.release(id); + byId().release(id); } - static std::shared_ptr<Imagined> get(Id id) { - return m_byId.get(id); + static std::shared_ptr<Item> get(Id id) { + return byId().get(id); } template <typename Derived> static std::shared_ptr<Derived> getAs(Id id) { - return m_byId.getAs<Derived>(id); + return std::dynamic_pointer_cast<Derived>(get(id)); } private: - static ById<Imagined> m_byId; + static + ById<Item, Id> &byId() { + static ById<Item, Id> b; + return b; + } }; -*/ + #endif
--- a/data/model/Model.cpp Thu Jun 20 14:57:39 2019 +0100 +++ b/data/model/Model.cpp Fri Jun 21 13:37:00 2019 +0100 @@ -40,20 +40,6 @@ } } -int -Model::getNextId() -{ - static int nextId = 0; - static QMutex mutex; - QMutexLocker locker(&mutex); - int i = nextId; - if (nextId == INT_MAX) { - nextId = INT_MIN; - } - ++nextId; - return i; -} - void Model::setSourceModel(Model *model) {
--- a/data/model/Model.h Thu Jun 20 14:57:39 2019 +0100 +++ b/data/model/Model.h Fri Jun 21 13:37:00 2019 +0100 @@ -19,6 +19,7 @@ #include <vector> #include <QObject> +#include "base/ById.h" #include "base/XmlExportable.h" #include "base/Playable.h" #include "base/BaseTypes.h" @@ -27,14 +28,12 @@ class ZoomConstraint; class AlignmentModel; -typedef int ModelId; - /** * Model is the base class for all data models that represent any sort * of data on a time scale based on an audio frame rate. */ - class Model : public QObject, + public WithId<Model>, public XmlExportable, public Playable { @@ -132,13 +131,6 @@ virtual bool isSparse() const { return false; } /** - * Return an id for this model. The id is guaranteed to be a - * unique identifier for this model among all models that may ever - * exist within this single run of the application. - */ - ModelId getId() const { return m_id; } - - /** * Mark the model as abandoning. This means that the application * no longer needs it, so it can stop doing any background * calculations it may be involved in. Note that as far as the @@ -339,7 +331,6 @@ protected: Model() : - m_id(getNextId()), m_sourceModel(0), m_alignment(0), m_abandoning(false), @@ -350,15 +341,15 @@ Model(const Model &); Model &operator=(const Model &); - const ModelId m_id; Model *m_sourceModel; AlignmentModel *m_alignment; QString m_typeUri; bool m_abandoning; bool m_aboutToDelete; sv_frame_t m_extendTo; - - int getNextId(); }; +typedef Model::Id ModelId; +typedef StaticById<Model, ModelId> ModelById; + #endif
--- a/data/model/WritableWaveFileModel.cpp Thu Jun 20 14:57:39 2019 +0100 +++ b/data/model/WritableWaveFileModel.cpp Fri Jun 21 13:37:00 2019 +0100 @@ -96,7 +96,8 @@ // so the filename only needs to be unique within that - // model ID should be ok QDir dir(TempDirectory::getInstance()->getPath()); - path = dir.filePath(QString("written_%1.wav").arg(getId())); + path = dir.filePath(QString("written_%1.wav") + .arg(getId().toString())); } catch (const DirectoryCreationFailed &f) { SVCERR << "WritableWaveFileModel: Failed to create temporary directory" << endl; return; @@ -126,7 +127,8 @@ // Temp dir is exclusive to this run of the application, so // the filename only needs to be unique within that QDir dir(TempDirectory::getInstance()->getPath()); - m_temporaryPath = dir.filePath(QString("prenorm_%1.wav").arg(getId())); + m_temporaryPath = dir.filePath(QString("prenorm_%1.wav") + .arg(getId().toString())); m_temporaryWriter = new WavFileWriter (m_temporaryPath, m_sampleRate, m_channels,