Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "measure.h"
24 : #include "measurebase.h"
25 : #include "rangelock.h"
26 :
27 : #include "log.h"
28 :
29 : namespace mu::engraving {
30 984 : bool RangeLock::contains(const MeasureBase* mb) const
31 : {
32 984 : return m_startMB->isBeforeOrEqual(mb) && mb->isBeforeOrEqual(m_endMB);
33 : }
34 :
35 114 : void RangeLocks::add(const RangeLock* lock)
36 : {
37 114 : m_rangeLocks.emplace(lock->startMB(), lock);
38 :
39 : #ifndef NDEBUG
40 114 : sanityCheck();
41 : #endif
42 114 : }
43 :
44 50 : void RangeLocks::remove(const RangeLock* lock)
45 : {
46 50 : m_rangeLocks.erase(lock->startMB());
47 :
48 : #ifndef NDEBUG
49 50 : sanityCheck();
50 : #endif
51 50 : }
52 :
53 69961 : const RangeLock* RangeLocks::lockStartingAt(const MeasureBase* mb) const
54 : {
55 69961 : auto iter = m_rangeLocks.find(mb);
56 69961 : return iter != m_rangeLocks.end() ? iter->second : nullptr;
57 : }
58 :
59 88976 : const RangeLock* RangeLocks::lockContaining(const MeasureBase* mb) const
60 : {
61 88976 : if (m_rangeLocks.empty()) {
62 87992 : return nullptr;
63 : }
64 :
65 984 : auto iter = m_rangeLocks.lower_bound(mb);
66 984 : if (iter != m_rangeLocks.begin()
67 984 : && (iter == m_rangeLocks.end() || mb->isBefore(iter->second->startMB()))) {
68 622 : --iter;
69 : }
70 :
71 984 : const RangeLock* lock = iter->second;
72 :
73 984 : return lock->contains(mb) ? lock : nullptr;
74 : }
75 :
76 342 : std::vector<const RangeLock*> RangeLocks::locksContainedInRange(const MeasureBase* start, const MeasureBase* end) const
77 : {
78 342 : std::vector<const RangeLock*> result;
79 :
80 367 : for (auto& pair : m_rangeLocks) {
81 29 : const RangeLock* lock = pair.second;
82 29 : if (start->isBeforeOrEqual(lock->startMB()) && lock->endMB()->isBeforeOrEqual(end)) {
83 20 : result.push_back(lock);
84 : }
85 29 : if (lock->startMB()->isAfter(end)) {
86 4 : break;
87 : }
88 : }
89 :
90 342 : return result;
91 0 : }
92 :
93 7107 : std::vector<const RangeLock*> RangeLocks::allLocks() const
94 : {
95 7107 : return muse::values(m_rangeLocks);
96 : }
97 :
98 : #ifndef NDEBUG
99 164 : void RangeLocks::sanityCheck()
100 : {
101 586 : for (auto iter = m_rangeLocks.begin(); iter != m_rangeLocks.end();) {
102 577 : auto curIter = iter;
103 577 : auto nextIter = ++iter;
104 577 : if (nextIter == m_rangeLocks.end()) {
105 155 : break;
106 : }
107 :
108 422 : const MeasureBase* curMB = curIter->first;
109 422 : const RangeLock* curLock = curIter->second;
110 :
111 422 : DO_ASSERT(curLock->startMB() == curMB);
112 :
113 422 : const MeasureBase* nextMB = nextIter->first;
114 422 : const RangeLock* nextLock = nextIter->second;
115 :
116 422 : DO_ASSERT(nextLock->startMB() == nextMB);
117 422 : DO_ASSERT(curMB->isBefore(nextMB));
118 422 : DO_ASSERT(curLock->endMB()->isBefore(nextLock->startMB()));
119 : }
120 164 : }
121 :
122 0 : void RangeLocks::dump() const
123 : {
124 0 : for (auto& pair : m_rangeLocks) {
125 0 : const RangeLock* sl = pair.second;
126 0 : const Measure* startMeasure = sl->startMB()->isMeasure() ? toMeasure(sl->startMB()) : sl->startMB()->prevMeasure();
127 0 : const Measure* endMeasure = sl->endMB()->isMeasure() ? toMeasure(sl->endMB()) : sl->endMB()->prevMeasure();
128 0 : LOGD() << "RangeLock --- Start measure: " << (startMeasure ? startMeasure->measureNumber() : -1)
129 0 : << ", End Measure: " << (endMeasure ? endMeasure->measureNumber() : -1);
130 : }
131 0 : }
132 :
133 : #endif
134 : } // namespace mu::engraving
|