Mercurial > hg > svcore
comparison data/model/SparseModel.h @ 1212:f80773b5ec96 piper
More cautious locking on sparse model modification
author | Chris Cannam |
---|---|
date | Mon, 17 Oct 2016 14:28:43 +0100 |
parents | 815f82508f96 |
children | 771a17925576 |
comparison
equal
deleted
inserted
replaced
1211:5a1198083d9a | 1212:f80773b5ec96 |
---|---|
727 SparseModel<PointType>::setResolution(int resolution) | 727 SparseModel<PointType>::setResolution(int resolution) |
728 { | 728 { |
729 { | 729 { |
730 QMutexLocker locker(&m_mutex); | 730 QMutexLocker locker(&m_mutex); |
731 m_resolution = resolution; | 731 m_resolution = resolution; |
732 } | 732 m_rows.clear(); |
733 m_rows.clear(); | 733 } |
734 emit modelChanged(); | 734 emit modelChanged(); |
735 } | 735 } |
736 | 736 |
737 template <typename PointType> | 737 template <typename PointType> |
738 void | 738 void |
740 { | 740 { |
741 { | 741 { |
742 QMutexLocker locker(&m_mutex); | 742 QMutexLocker locker(&m_mutex); |
743 m_points.clear(); | 743 m_points.clear(); |
744 m_pointCount = 0; | 744 m_pointCount = 0; |
745 } | 745 m_rows.clear(); |
746 m_rows.clear(); | 746 } |
747 emit modelChanged(); | 747 emit modelChanged(); |
748 } | 748 } |
749 | 749 |
750 template <typename PointType> | 750 template <typename PointType> |
751 void | 751 void |
752 SparseModel<PointType>::addPoint(const PointType &point) | 752 SparseModel<PointType>::addPoint(const PointType &point) |
753 { | 753 { |
754 { | 754 QMutexLocker locker(&m_mutex); |
755 QMutexLocker locker(&m_mutex); | 755 |
756 m_points.insert(point); | 756 m_points.insert(point); |
757 m_pointCount++; | 757 m_pointCount++; |
758 if (point.getLabel() != "") m_hasTextLabels = true; | 758 if (point.getLabel() != "") m_hasTextLabels = true; |
759 } | |
760 | 759 |
761 // Even though this model is nominally sparse, there may still be | 760 // Even though this model is nominally sparse, there may still be |
762 // too many signals going on here (especially as they'll probably | 761 // too many signals going on here (especially as they'll probably |
763 // be queued from one thread to another), which is why we need the | 762 // be queued from one thread to another), which is why we need the |
764 // notifyOnAdd as an option rather than a necessity (the | 763 // notifyOnAdd as an option rather than a necessity (the |
781 | 780 |
782 template <typename PointType> | 781 template <typename PointType> |
783 bool | 782 bool |
784 SparseModel<PointType>::containsPoint(const PointType &point) | 783 SparseModel<PointType>::containsPoint(const PointType &point) |
785 { | 784 { |
786 { | 785 QMutexLocker locker(&m_mutex); |
787 QMutexLocker locker(&m_mutex); | 786 |
788 | 787 PointListIterator i = m_points.lower_bound(point); |
789 PointListIterator i = m_points.lower_bound(point); | 788 typename PointType::Comparator comparator; |
790 typename PointType::Comparator comparator; | 789 while (i != m_points.end()) { |
791 while (i != m_points.end()) { | 790 if (i->frame > point.frame) break; |
792 if (i->frame > point.frame) break; | 791 if (!comparator(*i, point) && !comparator(point, *i)) { |
793 if (!comparator(*i, point) && !comparator(point, *i)) { | 792 return true; |
794 return true; | 793 } |
794 ++i; | |
795 } | |
796 | |
797 return false; | |
798 } | |
799 | |
800 template <typename PointType> | |
801 void | |
802 SparseModel<PointType>::deletePoint(const PointType &point) | |
803 { | |
804 QMutexLocker locker(&m_mutex); | |
805 | |
806 PointListIterator i = m_points.lower_bound(point); | |
807 typename PointType::Comparator comparator; | |
808 while (i != m_points.end()) { | |
809 if (i->frame > point.frame) break; | |
810 if (!comparator(*i, point) && !comparator(point, *i)) { | |
811 m_points.erase(i); | |
812 m_pointCount--; | |
813 break; | |
795 } | 814 } |
796 ++i; | 815 ++i; |
797 } | 816 } |
798 } | 817 |
799 | |
800 return false; | |
801 } | |
802 | |
803 template <typename PointType> | |
804 void | |
805 SparseModel<PointType>::deletePoint(const PointType &point) | |
806 { | |
807 { | |
808 QMutexLocker locker(&m_mutex); | |
809 | |
810 PointListIterator i = m_points.lower_bound(point); | |
811 typename PointType::Comparator comparator; | |
812 while (i != m_points.end()) { | |
813 if (i->frame > point.frame) break; | |
814 if (!comparator(*i, point) && !comparator(point, *i)) { | |
815 m_points.erase(i); | |
816 m_pointCount--; | |
817 break; | |
818 } | |
819 ++i; | |
820 } | |
821 } | |
822 // std::cout << "SparseOneDimensionalModel: emit modelChanged(" | 818 // std::cout << "SparseOneDimensionalModel: emit modelChanged(" |
823 // << point.frame << ")" << std::endl; | 819 // << point.frame << ")" << std::endl; |
824 m_rows.clear(); //!!! inefficient | 820 m_rows.clear(); //!!! inefficient |
825 emit modelChangedWithin(point.frame, point.frame + m_resolution); | 821 emit modelChangedWithin(point.frame, point.frame + m_resolution); |
826 } | 822 } |
828 template <typename PointType> | 824 template <typename PointType> |
829 void | 825 void |
830 SparseModel<PointType>::setCompletion(int completion, bool update) | 826 SparseModel<PointType>::setCompletion(int completion, bool update) |
831 { | 827 { |
832 // std::cerr << "SparseModel::setCompletion(" << completion << ")" << std::endl; | 828 // std::cerr << "SparseModel::setCompletion(" << completion << ")" << std::endl; |
829 | |
830 QMutexLocker locker(&m_mutex); | |
833 | 831 |
834 if (m_completion != completion) { | 832 if (m_completion != completion) { |
835 m_completion = completion; | 833 m_completion = completion; |
836 | 834 |
837 if (completion == 100) { | 835 if (completion == 100) { |