Mercurial > hg > svcore
diff data/model/SparseModel.h @ 1527:710e6250a401 zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:14 +0100 |
parents | f68911282993 |
children | c01cbe41aeb5 |
line wrap: on
line diff
--- a/data/model/SparseModel.h Mon Dec 12 15:18:52 2016 +0000 +++ b/data/model/SparseModel.h Mon Sep 17 13:51:14 2018 +0100 @@ -13,8 +13,8 @@ COPYING included with this distribution for more information. */ -#ifndef _SPARSE_MODEL_H_ -#define _SPARSE_MODEL_H_ +#ifndef SV_SPARSE_MODEL_H +#define SV_SPARSE_MODEL_H #include "Model.h" #include "TabularModel.h" @@ -43,9 +43,16 @@ class SparseModel : public Model, public TabularModel { + // If we omit the Q_OBJECT macro, lupdate complains. + + // If we include it, moc fails (can't handle template classes). + + // If we omit it, lupdate still seems to emit translatable + // messages for the tr() strings in here. So I guess we omit it. + public: SparseModel(sv_samplerate_t sampleRate, int resolution, - bool notifyOnAdd = true); + bool notifyOnAdd = true); virtual ~SparseModel() { } virtual bool isOK() const { return true; } @@ -66,12 +73,12 @@ // Extend the end of the model. If this is set to something beyond // the end of the final point in the model, then getEndFrame() // will return this value. Otherwise getEndFrame() will return the - // end of the final point. + // end of the final point. (This is used by the Tony application) virtual void extendEndFrame(sv_frame_t to) { m_extendTo = to; } - + typedef PointType Point; typedef std::multiset<PointType, - typename PointType::OrderComparator> PointList; + typename PointType::OrderComparator> PointList; typedef typename PointList::iterator PointListIterator; typedef typename PointList::const_iterator PointListConstIterator; @@ -151,6 +158,8 @@ virtual bool hasTextLabels() const { return m_hasTextLabels; } + virtual bool isSparse() const { return true; } + QString getTypeName() const { return tr("Sparse"); } virtual QString getXmlOutputType() const { return "sparse"; } @@ -168,7 +177,7 @@ DataExportOptions opts) const { return toDelimitedDataStringSubsetWithOptions (delimiter, opts, - std::min(getStartFrame(), sv_frame_t(0)), getEndFrame() + 1); + std::min(getStartFrame(), sv_frame_t(0)), getEndFrame()); } virtual QString toDelimitedDataStringSubset(QString delimiter, sv_frame_t f0, sv_frame_t f1) const { @@ -196,23 +205,23 @@ class AddPointCommand : public Command { public: - AddPointCommand(SparseModel<PointType> *model, - const PointType &point, + AddPointCommand(SparseModel<PointType> *model, + const PointType &point, QString name = "") : - m_model(model), m_point(point), m_name(name) { } + m_model(model), m_point(point), m_name(name) { } - virtual QString getName() const { + virtual QString getName() const { return (m_name == "" ? tr("Add Point") : m_name); } - virtual void execute() { m_model->addPoint(m_point); } - virtual void unexecute() { m_model->deletePoint(m_point); } + virtual void execute() { m_model->addPoint(m_point); } + virtual void unexecute() { m_model->deletePoint(m_point); } - const PointType &getPoint() const { return m_point; } + const PointType &getPoint() const { return m_point; } private: - SparseModel<PointType> *m_model; - PointType m_point; + SparseModel<PointType> *m_model; + PointType m_point; QString m_name; }; @@ -223,20 +232,20 @@ class DeletePointCommand : public Command { public: - DeletePointCommand(SparseModel<PointType> *model, - const PointType &point) : - m_model(model), m_point(point) { } + DeletePointCommand(SparseModel<PointType> *model, + const PointType &point) : + m_model(model), m_point(point) { } - virtual QString getName() const { return tr("Delete Point"); } + virtual QString getName() const { return tr("Delete Point"); } - virtual void execute() { m_model->deletePoint(m_point); } - virtual void unexecute() { m_model->addPoint(m_point); } + virtual void execute() { m_model->deletePoint(m_point); } + virtual void unexecute() { m_model->addPoint(m_point); } - const PointType &getPoint() const { return m_point; } + const PointType &getPoint() const { return m_point; } private: - SparseModel<PointType> *m_model; - PointType m_point; + SparseModel<PointType> *m_model; + PointType m_point; }; @@ -247,27 +256,27 @@ class EditCommand : public MacroCommand { public: - EditCommand(SparseModel<PointType> *model, QString commandName); + EditCommand(SparseModel<PointType> *model, QString commandName); - virtual void addPoint(const PointType &point); - virtual void deletePoint(const PointType &point); + virtual void addPoint(const PointType &point); + virtual void deletePoint(const PointType &point); - /** - * Stack an arbitrary other command in the same sequence. - */ - virtual void addCommand(Command *command) { addCommand(command, true); } + /** + * Stack an arbitrary other command in the same sequence. + */ + virtual void addCommand(Command *command) { addCommand(command, true); } - /** - * If any points have been added or deleted, return this - * command (so the caller can add it to the command history). - * Otherwise delete the command and return NULL. - */ - virtual EditCommand *finish(); + /** + * If any points have been added or deleted, return this + * command (so the caller can add it to the command history). + * Otherwise delete the command and return NULL. + */ + virtual EditCommand *finish(); protected: - virtual void addCommand(Command *command, bool executeFirst); + virtual void addCommand(Command *command, bool executeFirst); - SparseModel<PointType> *m_model; + SparseModel<PointType> *m_model; }; @@ -277,27 +286,27 @@ class RelabelCommand : public Command { public: - RelabelCommand(SparseModel<PointType> *model, - const PointType &point, - QString newLabel) : - m_model(model), m_oldPoint(point), m_newPoint(point) { - m_newPoint.label = newLabel; - } + RelabelCommand(SparseModel<PointType> *model, + const PointType &point, + QString newLabel) : + m_model(model), m_oldPoint(point), m_newPoint(point) { + m_newPoint.label = newLabel; + } - virtual QString getName() const { return tr("Re-Label Point"); } + virtual QString getName() const { return tr("Re-Label Point"); } - virtual void execute() { - m_model->deletePoint(m_oldPoint); - m_model->addPoint(m_newPoint); - std::swap(m_oldPoint, m_newPoint); - } + virtual void execute() { + m_model->deletePoint(m_oldPoint); + m_model->addPoint(m_newPoint); + std::swap(m_oldPoint, m_newPoint); + } - virtual void unexecute() { execute(); } + virtual void unexecute() { execute(); } private: - SparseModel<PointType> *m_model; - PointType m_oldPoint; - PointType m_newPoint; + SparseModel<PointType> *m_model; + PointType m_oldPoint; + PointType m_newPoint; }; /** @@ -558,7 +567,7 @@ QMutexLocker locker(&m_mutex); sv_frame_t f = 0; if (!m_points.empty()) { - f = m_points.begin()->frame; + f = m_points.begin()->frame; } return f; } @@ -570,11 +579,14 @@ QMutexLocker locker(&m_mutex); sv_frame_t f = 0; if (!m_points.empty()) { - PointListConstIterator i(m_points.end()); - f = (--i)->frame; + PointListConstIterator i(m_points.end()); + f = (--i)->frame + 1; } - if (m_extendTo > f) return m_extendTo; - else return f; + if (m_extendTo > f) { + return m_extendTo; + } else { + return f; + } } template <typename PointType> @@ -618,7 +630,7 @@ PointList rv; for (PointListConstIterator i = startItr; i != endItr; ++i) { - rv.insert(*i); + rv.insert(*i); } return rv; @@ -634,7 +646,7 @@ PointList rv; for (PointListConstIterator i = startItr; i != endItr; ++i) { - rv.insert(*i); + rv.insert(*i); } return rv; @@ -704,9 +716,9 @@ --i; sv_frame_t frame = i->frame; while (i->frame == frame) { - rv.insert(*i); - if (i == m_points.begin()) break; - --i; + rv.insert(*i); + if (i == m_points.begin()) break; + --i; } return rv; @@ -726,8 +738,8 @@ sv_frame_t frame = i->frame; while (i != m_points.end() && i->frame == frame) { - rv.insert(*i); - ++i; + rv.insert(*i); + ++i; } return rv; @@ -738,8 +750,8 @@ SparseModel<PointType>::setResolution(int resolution) { { - QMutexLocker locker(&m_mutex); - m_resolution = resolution; + QMutexLocker locker(&m_mutex); + m_resolution = resolution; m_rows.clear(); } emit modelChanged(); @@ -750,8 +762,8 @@ SparseModel<PointType>::clear() { { - QMutexLocker locker(&m_mutex); - m_points.clear(); + QMutexLocker locker(&m_mutex); + m_points.clear(); m_pointCount = 0; m_rows.clear(); } @@ -762,30 +774,35 @@ void SparseModel<PointType>::addPoint(const PointType &point) { - QMutexLocker locker(&m_mutex); + { + QMutexLocker locker(&m_mutex); - m_points.insert(point); - m_pointCount++; - if (point.getLabel() != "") m_hasTextLabels = true; + m_points.insert(point); + m_pointCount++; + if (point.getLabel() != "") m_hasTextLabels = true; - // Even though this model is nominally sparse, there may still be - // too many signals going on here (especially as they'll probably - // be queued from one thread to another), which is why we need the - // notifyOnAdd as an option rather than a necessity (the - // alternative is to notify on setCompletion). + // Even though this model is nominally sparse, there may still + // be too many signals going on here (especially as they'll + // probably be queued from one thread to another), which is + // why we need the notifyOnAdd as an option rather than a + // necessity (the alternative is to notify on setCompletion). + + if (m_notifyOnAdd) { + m_rows.clear(); //!!! inefficient + } else { + if (m_sinceLastNotifyMin == -1 || + point.frame < m_sinceLastNotifyMin) { + m_sinceLastNotifyMin = point.frame; + } + if (m_sinceLastNotifyMax == -1 || + point.frame > m_sinceLastNotifyMax) { + m_sinceLastNotifyMax = point.frame; + } + } + } if (m_notifyOnAdd) { - m_rows.clear(); //!!! inefficient - emit modelChangedWithin(point.frame, point.frame + m_resolution); - } else { - if (m_sinceLastNotifyMin == -1 || - point.frame < m_sinceLastNotifyMin) { - m_sinceLastNotifyMin = point.frame; - } - if (m_sinceLastNotifyMax == -1 || - point.frame > m_sinceLastNotifyMax) { - m_sinceLastNotifyMax = point.frame; - } + emit modelChangedWithin(point.frame, point.frame + m_resolution); } } @@ -812,23 +829,26 @@ void SparseModel<PointType>::deletePoint(const PointType &point) { - QMutexLocker locker(&m_mutex); + { + QMutexLocker locker(&m_mutex); - PointListIterator i = m_points.lower_bound(point); - typename PointType::Comparator comparator; - while (i != m_points.end()) { - if (i->frame > point.frame) break; - if (!comparator(*i, point) && !comparator(point, *i)) { - m_points.erase(i); - m_pointCount--; - break; - } - ++i; - } + PointListIterator i = m_points.lower_bound(point); + typename PointType::Comparator comparator; + while (i != m_points.end()) { + if (i->frame > point.frame) break; + if (!comparator(*i, point) && !comparator(point, *i)) { + m_points.erase(i); + m_pointCount--; + break; + } + ++i; + } // std::cout << "SparseOneDimensionalModel: emit modelChanged(" -// << point.frame << ")" << std::endl; - m_rows.clear(); //!!! inefficient +// << point.frame << ")" << std::endl; + m_rows.clear(); //!!! inefficient + } + emit modelChangedWithin(point.frame, point.frame + m_resolution); } @@ -837,36 +857,47 @@ SparseModel<PointType>::setCompletion(int completion, bool update) { // std::cerr << "SparseModel::setCompletion(" << completion << ")" << std::endl; + bool emitCompletionChanged = true; + bool emitGeneralModelChanged = false; + bool emitRegionChanged = false; - QMutexLocker locker(&m_mutex); + { + QMutexLocker locker(&m_mutex); - if (m_completion != completion) { - m_completion = completion; + if (m_completion != completion) { + m_completion = completion; - if (completion == 100) { + if (completion == 100) { - if (!m_notifyOnAdd) { - emit completionChanged(); + if (m_notifyOnAdd) { + emitCompletionChanged = false; + } + + m_notifyOnAdd = true; // henceforth + m_rows.clear(); //!!! inefficient + emitGeneralModelChanged = true; + + } else if (!m_notifyOnAdd) { + + if (update && + m_sinceLastNotifyMin >= 0 && + m_sinceLastNotifyMax >= 0) { + m_rows.clear(); //!!! inefficient + emitRegionChanged = true; + } } + } + } - m_notifyOnAdd = true; // henceforth - m_rows.clear(); //!!! inefficient - emit modelChanged(); - - } else if (!m_notifyOnAdd) { - - if (update && - m_sinceLastNotifyMin >= 0 && - m_sinceLastNotifyMax >= 0) { - m_rows.clear(); //!!! inefficient - emit modelChangedWithin(m_sinceLastNotifyMin, m_sinceLastNotifyMax); - m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1; - } else { - emit completionChanged(); - } - } else { - emit completionChanged(); - } + if (emitCompletionChanged) { + emit completionChanged(); + } + if (emitGeneralModelChanged) { + emit modelChanged(); + } + if (emitRegionChanged) { + emit modelChangedWithin(m_sinceLastNotifyMin, m_sinceLastNotifyMax); + m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1; } } @@ -882,20 +913,20 @@ QString type = getXmlOutputType(); Model::toXml - (out, + (out, indent, - QString("type=\"%1\" dimensions=\"%2\" resolution=\"%3\" notifyOnAdd=\"%4\" dataset=\"%5\" %6") + QString("type=\"%1\" dimensions=\"%2\" resolution=\"%3\" notifyOnAdd=\"%4\" dataset=\"%5\" %6") .arg(type) - .arg(PointType(0).getDimensions()) - .arg(m_resolution) - .arg(m_notifyOnAdd ? "true" : "false") - .arg(getObjectExportId(&m_points)) - .arg(extraAttributes)); + .arg(PointType(0).getDimensions()) + .arg(m_resolution) + .arg(m_notifyOnAdd ? "true" : "false") + .arg(getObjectExportId(&m_points)) + .arg(extraAttributes)); out << indent; out << QString("<dataset id=\"%1\" dimensions=\"%2\">\n") - .arg(getObjectExportId(&m_points)) - .arg(PointType(0).getDimensions()); + .arg(getObjectExportId(&m_points)) + .arg(PointType(0).getDimensions()); for (PointListConstIterator i = m_points.begin(); i != m_points.end(); ++i) { i->toXml(out, indent + " "); @@ -942,24 +973,24 @@ template <typename PointType> void SparseModel<PointType>::EditCommand::addCommand(Command *command, - bool executeFirst) + bool executeFirst) { if (executeFirst) command->execute(); if (!m_commands.empty()) { - DeletePointCommand *dpc = dynamic_cast<DeletePointCommand *>(command); - if (dpc) { - AddPointCommand *apc = dynamic_cast<AddPointCommand *> - (m_commands[m_commands.size() - 1]); - typename PointType::Comparator comparator; - if (apc) { - if (!comparator(apc->getPoint(), dpc->getPoint()) && - !comparator(dpc->getPoint(), apc->getPoint())) { - deleteCommand(apc); - return; - } - } - } + DeletePointCommand *dpc = dynamic_cast<DeletePointCommand *>(command); + if (dpc) { + AddPointCommand *apc = dynamic_cast<AddPointCommand *> + (m_commands[m_commands.size() - 1]); + typename PointType::Comparator comparator; + if (apc) { + if (!comparator(apc->getPoint(), dpc->getPoint()) && + !comparator(dpc->getPoint(), apc->getPoint())) { + deleteCommand(apc); + return; + } + } + } } MacroCommand::addCommand(command);