# HG changeset patch # User Chris Cannam # Date 1561120620 -3600 # Node ID 601851995f4b1dcb1ebbc8e26e47866fddef10d9 # Parent abd8b9673028e9397d2bc78b57e7f29e601853c6 Introduce Model to ById diff -r abd8b9673028 -r 601851995f4b base/ById.cpp --- 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 - -#include - -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; -} diff -r abd8b9673028 -r 601851995f4b base/ById.h --- 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 #include +#include +#include +#include #include +#include -typedef int Id; +template +struct SvId { + int id; + bool operator<(const SvId &other) const { return id < other.id; } + + QString toString() const { + return QString("%1").arg(id); + } +}; + +template class WithId { public: + typedef SvId 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 +template 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) { QMutexLocker locker(&m_mutex); m_items[item->getId()] = item; @@ -72,34 +118,36 @@ mutable QMutex m_mutex; std::map> m_items; }; -/* -class Imagined : public WithId { -}; -class ImaginedById +template +class StaticById { public: - static void add(std::shared_ptr imagined) { - m_byId.add(imagined); + static void add(std::shared_ptr imagined) { + byId().add(imagined); } static void release(Id id) { - m_byId.release(id); + byId().release(id); } - static std::shared_ptr get(Id id) { - return m_byId.get(id); + static std::shared_ptr get(Id id) { + return byId().get(id); } template static std::shared_ptr getAs(Id id) { - return m_byId.getAs(id); + return std::dynamic_pointer_cast(get(id)); } private: - static ById m_byId; + static + ById &byId() { + static ById b; + return b; + } }; -*/ + #endif diff -r abd8b9673028 -r 601851995f4b data/model/Model.cpp --- 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) { diff -r abd8b9673028 -r 601851995f4b data/model/Model.h --- 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 #include +#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, 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 ModelById; + #endif diff -r abd8b9673028 -r 601851995f4b data/model/WritableWaveFileModel.cpp --- 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, diff -r abd8b9673028 -r 601851995f4b files.pri --- a/files.pri Thu Jun 20 14:57:39 2019 +0100 +++ b/files.pri Fri Jun 21 13:37:00 2019 +0100 @@ -150,7 +150,6 @@ SVCORE_SOURCES = \ base/AudioLevel.cpp \ - base/ById.cpp \ base/Clipboard.cpp \ base/ColumnOp.cpp \ base/Command.cpp \