MUSX Document Model
Loading...
Searching...
No Matches
ObjectPool.h
1/*
2 * Copyright (C) 2025, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#include <string>
25#include <map>
26#include <unordered_map>
27#include <vector>
28#include <memory>
29#include <tuple>
30#include <variant>
31#include <stdexcept>
32#include <functional>
33#include <limits>
34
35#include "MusxInstance.h"
36
37#include "BaseClasses.h"
38#include "Others.h"
39#include "Details.h"
40#include "Entries.h"
41#include "ShapeDesigner.h"
42#include "SmartShape.h"
43#include "Staff.h"
44
45#ifndef DOXYGEN_SHOULD_IGNORE_THIS
46namespace bench {
49template<class> class PoolAccessor;
50}; // namespace bench
51#endif
52
53namespace musx {
54namespace dom {
55
59template <typename Pool, typename T>
60struct is_pool_type : std::false_type {}; // default: not valid
61
63template <typename Pool, typename T>
65
75template <typename ObjectBaseType>
77{
78public:
80 using ObjectPtr = std::shared_ptr<ObjectBaseType>;
82 struct ObjectKey {
83 std::string_view nodeId;
85 std::optional<Cmper> cmper1;
86 std::optional<Cmper> cmper2;
87 // Use `int` instead of `Inci` to work around GCC spurious -Wmaybe-uninitialized warning
88 std::optional<int> inci;
89
91 ObjectKey(std::string_view n,
92 Cmper p,
93 std::optional<Cmper> c1 = std::nullopt,
94 std::optional<Cmper> c2 = std::nullopt,
95 std::optional<int> i = std::nullopt) : nodeId(n), partId(p), cmper1(c1), cmper2(c2), inci(i)
96 {
97 }
98
100 bool operator<(const ObjectKey& other) const
101 {
102 if (nodeId != other.nodeId) {
103 return nodeId < other.nodeId;
104 }
105 if (partId != other.partId) {
106 return partId < other.partId;
107 }
108 if (cmper1 != other.cmper1) {
109 return cmper1 < other.cmper1;
110 }
111 if (cmper2 != other.cmper2) {
112 return cmper2 < other.cmper2;
113 }
114 return inci < other.inci;
115 }
116
118 std::string description() const
119 {
120 std::string result = std::string(nodeId) + " part " + std::to_string(partId);
121 if (cmper1) {
122 if (cmper2) {
123 result += " cmpers [" + std::to_string(cmper1.value()) + ", " + std::to_string(cmper2.value()) + "]";
124 } else {
125 result += " cmper " + std::to_string(cmper1.value());
126 }
127 }
128 if (inci) {
129 result += " inci " + std::to_string(inci.value());
130 }
131 return result;
132 }
133 };
134
135private:
136 template <typename T>
137 std::shared_ptr<const T> bindWithPartId(std::shared_ptr<const T> obj, Cmper requestedPartId) const
138 {
139 if constexpr (std::is_base_of_v<OthersBase, T> || std::is_base_of_v<DetailsBase, T>) {
140 if (obj && obj->getRequestedPartId() != requestedPartId) {
141 return PartContextCloner::copyWithPartId(obj, requestedPartId);
142 }
143 }
144 return obj;
145 }
146
147 inline static ObjectKey makeEndKey(const ObjectKey& key)
148 {
149 return ObjectKey{
150 key.nodeId,
151 key.partId,
152 key.cmper1.value_or((std::numeric_limits<Cmper>::max)()),
153 key.cmper2.value_or((std::numeric_limits<Cmper>::max)()),
154 key.inci.value_or((std::numeric_limits<Inci>::max)())
155 };
156 }
157
158 template <typename T>
159 inline static MusxInstance<T> checkedStaticCast([[maybe_unused]]const ObjectKey& key, const ObjectPtr& p)
160 {
161 static_assert(std::is_base_of_v<ObjectBaseType, T>, "T must derive from ObjectBaseType");
162 if constexpr (!std::is_same_v<T, ObjectBaseType>) {
163 assert(T::XmlNodeName == key.nodeId && "nodeId/type mismatch: pool invariant violated");
164 }
165 #ifndef NDEBUG
166 // Optional paranoia while refactoring:
167 //assert(std::dynamic_pointer_cast<T>(p));
168 #endif
169 return std::static_pointer_cast<T>(p);
170 }
171
172 inline static bool logicalLess(const ObjectKey& a, const ObjectKey& b)
173 {
174 return std::tie(a.cmper1, a.cmper2, a.inci) < std::tie(b.cmper1, b.cmper2, b.inci);
175 }
176
177 inline static bool logicalEq(const ObjectKey& a, const ObjectKey& b)
178 {
179 return a.cmper1 == b.cmper1 && a.cmper2 == b.cmper2 && a.inci == b.inci;
180 }
181
182public:
184 virtual ~ObjectPool() = default;
185
192 void add(ObjectKey key, ObjectPtr object)
193 {
194 if (key.inci.has_value()) {
195 ObjectKey noInciKey = key;
196 noInciKey.inci = std::nullopt;
197 auto currentIncis = getArray<ObjectBaseType>(noInciKey, key.partId);
198 if (key.inci.value() != int(currentIncis.size())) {
199 MUSX_INTEGRITY_ERROR("Node " + std::string(key.nodeId) + " has inci " + std::to_string(key.inci.value()) + " that is out of sequence.");
200 }
201 }
202 auto shareModeIt = m_shareMode.find(key.nodeId);
203 auto [poolIt, emplaced] = m_pool.emplace(std::move(key), object);
204 if (!emplaced) {
205 MUSX_INTEGRITY_ERROR("Attempted to add same key more than once: " + poolIt->first.description());
206 }
207 if (shareModeIt == m_shareMode.end()) {
208 m_shareMode.emplace(poolIt->first.nodeId, object->getShareMode());
209 } else if (object->getShareMode() != shareModeIt->second && object->getShareMode() != Base::ShareMode::All) {
210 if (shareModeIt->second == Base::ShareMode::All) {
211 m_shareMode[poolIt->first.nodeId] = object->getShareMode();
212 } else {
213 MUSX_INTEGRITY_ERROR("Share mode for added " + std::string(poolIt->first.nodeId) + " object [" + std::to_string(int(object->getShareMode()))
214 + "] does not match previous [" + std::to_string(int(shareModeIt->second)) + "]");
215 }
216 }
217 }
218
232 template <typename T>
233 MusxInstanceList<T> getArray(const ObjectKey& key, Cmper requestedPartId) const
234 {
235 MusxInstanceList<T> result(m_document, requestedPartId);
236
237 auto rangeStart = m_pool.lower_bound(key);
238 auto rangeEnd = m_pool.upper_bound(makeEndKey(key));
239
240 for (auto it = rangeStart; it != rangeEnd; ++it) {
241 auto typedPtr = bindWithPartId<T>(checkedStaticCast<T>(key, it->second), requestedPartId);
242 result.push_back(typedPtr);
243 }
244 return result;
245 }
246
259 template <typename T>
261 {
263 if (key.partId != SCORE_PARTID) {
264 auto it = m_shareMode.find(key.nodeId);
265 // If the nodeId is not found in m_shareMode, it means the document contains no instances,
266 // and every path will return an empty vector. We can safely ignore this case.
267 if (it != m_shareMode.end()) {
268 forShareMode = it->second;
269 }
270 }
271
272 if (key.partId == SCORE_PARTID || forShareMode == Base::ShareMode::None) {
273 return getArray<T>(key, key.partId);
274 }
275 ObjectKey scoreKey(key);
276 scoreKey.partId = SCORE_PARTID;
277 if (forShareMode == Base::ShareMode::All) {
278 return getArray<T>(scoreKey, key.partId);
279 }
280
281 const auto partStart = m_pool.lower_bound(key);
282 const auto partEnd = m_pool.upper_bound(makeEndKey(key));
283
284 const auto scoreStart = m_pool.lower_bound(scoreKey);
285 const auto scoreEnd = m_pool.upper_bound(makeEndKey(scoreKey));
286
287 auto partIt = partStart;
288 auto scoreIt = scoreStart;
289
290 MusxInstanceList<T> result(m_document, key.partId);
291 auto pushInstance = [&](const auto& it) {
292 auto typed = bindWithPartId<T>(checkedStaticCast<T>(key, it->second), key.partId);
293 result.push_back(typed);
294 };
295 while (partIt != partEnd || scoreIt != scoreEnd) {
296 if (scoreIt == scoreEnd) {
297 pushInstance(partIt++);
298 continue;
299 }
300 if (partIt == partEnd) {
301 pushInstance(scoreIt++); // bind score record to requested part
302 continue;
303 }
304 const ObjectKey& pk = partIt->first;
305 const ObjectKey& sk = scoreIt->first;
306 if (logicalEq(pk, sk)) {
307 pushInstance(partIt++); // prefer part instance
308 scoreIt++;
309 } else if (logicalLess(pk, sk)) {
310 pushInstance(partIt++);
311 } else {
312 pushInstance(scoreIt++); // score fallback
313 }
314 }
315 return result;
316 }
317
329 template <typename T>
331 {
332 auto it = m_pool.find(key);
333 if (it == m_pool.end()) {
334 return nullptr;
335 }
336 return checkedStaticCast<T>(key, it->second);
337 }
338
352 template <typename T>
354 {
355 if (auto partVersion = getSource<T>(key)) {
356 return partVersion;
357 }
358 if (key.partId == SCORE_PARTID) {
359 // if this is already the score version, there is nothing to return.
360 return nullptr;
361 } else {
362 // if this is for a part, do not search score for unshared types.
363 auto it = m_shareMode.find(key.nodeId);
364 if (it != m_shareMode.end() && it->second == Base::ShareMode::None) {
365 return nullptr;
366 }
367 }
368 ObjectKey scoreKey(key);
369 scoreKey.partId = SCORE_PARTID;
370 return getSource<T>(scoreKey);
371 }
372
386 template <typename T>
388 {
389 return bindWithPartId<T>(getEffectiveSourceForPart<T>(key), key.partId);
390 }
391
396 ObjectPool(const DocumentWeakPtr& document, const std::unordered_map<std::string_view, dom::Base::ShareMode>& knownShareModes = {})
397 : m_document(document), m_shareMode(knownShareModes) {}
398
399private:
400 DocumentWeakPtr m_document;
401 std::unordered_map<std::string_view, dom::Base::ShareMode> m_shareMode;
402
403 std::map<ObjectKey, ObjectPtr> m_pool;
404};
405
411{
413 friend class bench::PoolAccessor<OptionsPool>;
414
415public:
417 OptionsPool(const DocumentWeakPtr& document) : m_pool(document) {}
418
420 void add(std::string_view nodeName, const std::shared_ptr<OptionsBase>& instance)
421 {
422 const Base* basePtr = instance.get();
423 if (basePtr->getSourcePartId() != SCORE_PARTID) {
424 MUSX_INTEGRITY_ERROR("Options node " + std::string(nodeName) + " hase non-score part id [" + std::to_string(basePtr->getSourcePartId()) + "]");
425 }
426 m_pool.add({ nodeName, basePtr->getSourcePartId() }, instance);
427 }
428
430 template <typename T>
432 {
433 static_assert(is_pool_type_v<OptionsPool, T>, "Type T is not registered in OptionsPool");
434 return m_pool.getArray<T>({ T::XmlNodeName, SCORE_PARTID }, SCORE_PARTID);
435 }
436
438 template <typename T>
440 {
441 static_assert(is_pool_type_v<OptionsPool, T>, "Type T is not registered in OptionsPool");
442 return m_pool.getSource<T>({ T::XmlNodeName, SCORE_PARTID });
443 }
444};
446using OptionsPoolPtr = std::shared_ptr<OptionsPool>;
447
453{
455 friend class bench::PoolAccessor<OthersPool>;
456 friend MusxInstance<others::StaffComposite> others::StaffComposite::createCurrent(const DocumentPtr& document, Cmper partId, StaffCmper staffId, MeasCmper measId, Edu eduPosition);
457
458 MusxInstance<others::Staff> getRawStaff(Cmper partId, StaffCmper staffId)
459 {
460 return m_pool.getEffectiveSourceForPart<others::Staff>({ std::string(others::Staff::XmlNodeName), partId, staffId, std::nullopt, std::nullopt });
461 }
462
463public:
478
480 void add(std::string_view nodeName, const std::shared_ptr<OthersBase>& instance)
481 { m_pool.add({nodeName, instance->getSourcePartId(), instance->getCmper(), std::nullopt, instance->getInci()}, instance); }
482
484 template <typename T>
485 MusxInstanceList<T> getArray(Cmper partId, std::optional<Cmper> cmper = std::nullopt) const
486 {
487 static_assert(is_pool_type_v<OthersPool, T>, "Type T is not registered in OthersPool");
488 return m_pool.getArrayForPart<T>({ T::XmlNodeName, partId, cmper });
489 }
490
492 template <typename T>
493 MusxInstance<T> get(Cmper partId, Cmper cmper, std::optional<Inci> inci = std::nullopt) const
494 {
495 static_assert(is_pool_type_v<OthersPool, T>, "Type T is not registered in OthersPool");
496 return m_pool.getEffectiveForPart<T>({ T::XmlNodeName, partId, cmper, std::nullopt, inci });
497 }
498};
500using OthersPoolPtr = std::shared_ptr<OthersPool>;
501
509{
511 friend class bench::PoolAccessor<DetailsPool>;
512
513public:
515 DetailsPool(const DocumentWeakPtr& document) : m_pool(document, {
519 // add other known sharemode none items as they are identified.
520 }) {}
521
523 void add(std::string_view nodeName, const std::shared_ptr<DetailsBase>& instance)
524 { m_pool.add({nodeName, instance->getSourcePartId(), instance->getCmper1(), instance->getCmper2(), instance->getInci()}, instance); }
525
527 template <typename T, typename = std::enable_if_t<is_pool_type_v<DetailsPool, T>>>
529 { return m_pool.template getArrayForPart<T>({ T::XmlNodeName, partId }); }
530
532 template <typename T, typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>, int> = 0>
533 MusxInstanceList<T> getArray(Cmper partId, Cmper cmper1, std::optional<Cmper> cmper2 = std::nullopt) const
534 {
535 static_assert(is_pool_type_v<DetailsPool, T>, "Type T is not registered in DetailsPool");
536 return m_pool.template getArrayForPart<T>({ T::XmlNodeName, partId, cmper1, cmper2 });
537 }
538
540 template <typename T, typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>, int> = 0>
542 {
543 static_assert(is_pool_type_v<DetailsPool, T>, "Type T is not registered in DetailsPool");
544 return m_pool.template getArrayForPart<T>({ T::XmlNodeName, partId, Cmper(entnum >> 16), Cmper(entnum & 0xffff) });
545 }
546
548 template <typename T, typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>, int> = 0>
549 MusxInstance<T> get(Cmper partId, Cmper cmper1, Cmper cmper2, std::optional<Inci> inci = std::nullopt) const
550 {
551 static_assert(is_pool_type_v<DetailsPool, T>, "Type T is not registered in DetailsPool");
552 return m_pool.getEffectiveForPart<T>({ T::XmlNodeName, partId, cmper1, cmper2, inci });
553 }
554
556 template <typename T, typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>, int> = 0>
557 MusxInstance<T> get(Cmper partId, EntryNumber entnum, std::optional<Inci> inci = std::nullopt) const
558 {
559 static_assert(is_pool_type_v<DetailsPool, T>, "Type T is not registered in DetailsPool");
560 return m_pool.getEffectiveForPart<T>({ T::XmlNodeName, partId, Cmper(entnum >> 16), Cmper(entnum & 0xffff), inci });
561 }
562
569 template <typename T, typename std::enable_if_t<std::is_base_of_v<NoteDetailsBase, T>, int> = 0>
570 MusxInstance<T> getForNote(const NoteInfoPtr& noteInfo, const std::optional<Cmper>& forPartId = std::nullopt)
571 {
572 static_assert(is_pool_type_v<DetailsPool, T>, "Type T is not registered in DetailsPool");
573 auto details = getArray<T>(
574 forPartId.value_or(noteInfo.getEntryInfo().getFrame()->getRequestedPartId()),
575 noteInfo.getEntryInfo()->getEntry()->getEntryNumber()
576 );
577 for (const auto& detail : details) {
578 if (detail->getNoteId() == noteInfo->getNoteId()) {
579 return detail;
580 }
581 }
582 return nullptr;
583 }
584};
585
587using DetailsPoolPtr = std::shared_ptr<DetailsPool>;
588
590class EntryPool // uses different implementation than other pools for more efficient access
591{
592public:
594 EntryPool(const DocumentWeakPtr& document) : m_document(document) {}
595
597 void add(EntryNumber entryNumber, const std::shared_ptr<Entry>& instance)
598 {
599 auto [it, emplaced] = m_pool.emplace(entryNumber, instance);
600 if (!emplaced) {
601 MUSX_INTEGRITY_ERROR("Entry number " + std::to_string(entryNumber) + " added twice.");
602 }
603 }
604
607 {
608 const auto it = m_pool.find(entryNumber);
609 if (it == m_pool.end()) {
610 return nullptr;
611 }
612 return it->second;
613 }
614
615private:
616 DocumentWeakPtr m_document;
617 std::unordered_map<EntryNumber, std::shared_ptr<Entry>> m_pool;
618
619 friend class bench::PoolAccessor<EntryPool>;
620};
622using EntryPoolPtr = std::shared_ptr<EntryPool>;
623
626{
628 friend class bench::PoolAccessor<TextsPool>;
629
630public:
632 TextsPool(const DocumentWeakPtr& document) : m_pool(document) {}
633
635 void add(std::string_view nodeName, const std::shared_ptr<TextsBase>& instance)
636 {
637 const Base* basePtr = instance.get();
638 if (basePtr->getSourcePartId() != SCORE_PARTID) {
639 MUSX_INTEGRITY_ERROR("Texts node " + std::string(nodeName) + " hase non-score part id [" + std::to_string(basePtr->getSourcePartId()) + "]");
640 }
641 m_pool.add({ nodeName, basePtr->getSourcePartId(), instance->getTextNumber() }, instance);
642 }
643
645 template <typename T>
646 MusxInstanceList<T> getArray(std::optional<Cmper> cmper = std::nullopt) const
647 {
648 static_assert(is_pool_type_v<TextsPool, T>, "Type T is not registered in TextsPool");
649 return m_pool.getArray<T>({ T::XmlNodeName, SCORE_PARTID, cmper }, SCORE_PARTID);
650 }
651
653 template <typename T>
655 {
656 static_assert(is_pool_type_v<TextsPool, T>, "Type T is not registered in TextsPool");
657 return m_pool.getSource<T>({ T::XmlNodeName, SCORE_PARTID, cmper, std::nullopt, std::nullopt });
658 }
659};
661using TextsPoolPtr = std::shared_ptr<TextsPool>;
662
663} // namespace dom
664} // namespace musx
Base class to enforce polymorphism across all DOM classes.
Definition BaseClasses.h:83
Cmper getSourcePartId() const
Gets the source partId for this instance. If an instance is fully shared with the score,...
Definition BaseClasses.h:124
ShareMode
Describes how this instance is shared between part and score.
Definition BaseClasses.h:91
A pool that manages collections of DetailsBase objects, organized by XML node names and Cmper values.
Definition ObjectPool.h:509
MusxInstanceList< T > getArray(Cmper partId) const
version of ObjectPool::getArray for getting all of them
Definition ObjectPool.h:528
MusxInstance< T > getForNote(const NoteInfoPtr &noteInfo, const std::optional< Cmper > &forPartId=std::nullopt)
Returns the detail for a particular note.
Definition ObjectPool.h:570
DetailsPool(const DocumentWeakPtr &document)
Constructor.
Definition ObjectPool.h:515
MusxInstance< T > get(Cmper partId, EntryNumber entnum, std::optional< Inci > inci=std::nullopt) const
Get a single EntryDetailsBase item out of the pool.
Definition ObjectPool.h:557
MusxInstanceList< T > getArray(Cmper partId, EntryNumber entnum) const
EntryDetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:541
MusxInstance< T > get(Cmper partId, Cmper cmper1, Cmper cmper2, std::optional< Inci > inci=std::nullopt) const
Get a single DetailsBase item out of the pool (not EntryDetailsBase)
Definition ObjectPool.h:549
void add(std::string_view nodeName, const std::shared_ptr< DetailsBase > &instance)
DetailsPool version of ObjectPool::add.
Definition ObjectPool.h:523
MusxInstanceList< T > getArray(Cmper partId, Cmper cmper1, std::optional< Cmper > cmper2=std::nullopt) const
DetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:533
std::shared_ptr< const EntryFrame > getFrame() const
Returns the frame.
Definition Entries.h:606
Entry pool.
Definition ObjectPool.h:591
EntryPool(const DocumentWeakPtr &document)
Constructor function.
Definition ObjectPool.h:594
void add(EntryNumber entryNumber, const std::shared_ptr< Entry > &instance)
Add an entry to the EntryPool. (Used by the factory.)
Definition ObjectPool.h:597
MusxInstance< Entry > get(EntryNumber entryNumber) const
Get an entry from the EntryPool.
Definition ObjectPool.h:606
Provides optional per-type extension methods for MusxInstanceList.
Definition MusxInstance.h:103
Wraps an EntryInfo instance and a note index.
Definition Entries.h:1545
EntryInfoPtr getEntryInfo() const
Gets the entry info for this note.
Definition Entries.h:1585
A pool that manages collections of OthersBase objects, organized by XML node names and Cmper values.
Definition ObjectPool.h:77
ObjectPool(const DocumentWeakPtr &document, const std::unordered_map< std::string_view, dom::Base::ShareMode > &knownShareModes={})
Constructs the object pool.
Definition ObjectPool.h:396
virtual ~ObjectPool()=default
virtual destructor
MusxInstance< T > getSource(const ObjectKey &key) const
Retrieves the first (and usually only) object of a specific type from the pool.
Definition ObjectPool.h:330
MusxInstanceList< T > getArrayForPart(const ObjectKey &key) const
Retrieves a vector of objects of a specific type from the pool.
Definition ObjectPool.h:260
MusxInstanceList< T > getArray(const ObjectKey &key, Cmper requestedPartId) const
Retrieves a vector of objects of a specific type from the pool.
Definition ObjectPool.h:233
MusxInstance< T > getEffectiveSourceForPart(const ObjectKey &key) const
Retrieves the first (and usually only) object of a specific type from the pool for a part.
Definition ObjectPool.h:353
void add(ObjectKey key, ObjectPtr object)
Adds an ObjectBaseType object to the pool.
Definition ObjectPool.h:192
MusxInstance< T > getEffectiveForPart(const ObjectKey &key) const
Retrieves the first (and usually only) object of a specific type from the pool for a part.
Definition ObjectPool.h:387
std::shared_ptr< ObjectBaseType > ObjectPtr
shared pointer to ObjectBaseType
Definition ObjectPool.h:80
A pool that manages collections of OptionsBase objects that have no Cmper value.
Definition ObjectPool.h:411
void add(std::string_view nodeName, const std::shared_ptr< OptionsBase > &instance)
Scalar version of ObjectPool::add.
Definition ObjectPool.h:420
MusxInstance< T > get() const
Get a single item out of the pool.
Definition ObjectPool.h:439
MusxInstanceList< T > getArray() const
Scalar version of ObjectPool::getArray.
Definition ObjectPool.h:431
OptionsPool(const DocumentWeakPtr &document)
Constructor function.
Definition ObjectPool.h:417
A pool that manages collections of OthersBase objects.
Definition ObjectPool.h:453
MusxInstance< T > get(Cmper partId, Cmper cmper, std::optional< Inci > inci=std::nullopt) const
Get a single item out of the pool.
Definition ObjectPool.h:493
void add(std::string_view nodeName, const std::shared_ptr< OthersBase > &instance)
OthersPool version of ObjectPool::add.
Definition ObjectPool.h:480
OthersPool(const DocumentWeakPtr &document)
Constructor.
Definition ObjectPool.h:465
MusxInstanceList< T > getArray(Cmper partId, std::optional< Cmper > cmper=std::nullopt) const
OthersPool version of ObjectPool::getArray.
Definition ObjectPool.h:485
Text pool.
Definition ObjectPool.h:626
MusxInstanceList< T > getArray(std::optional< Cmper > cmper=std::nullopt) const
Texts version of ObjectPool::getArray.
Definition ObjectPool.h:646
TextsPool(const DocumentWeakPtr &document)
Constructor fundtion.
Definition ObjectPool.h:632
MusxInstance< T > get(Cmper cmper) const
Get a single item out of the pool.
Definition ObjectPool.h:654
void add(std::string_view nodeName, const std::shared_ptr< TextsBase > &instance)
Texts version of ObjectPool::add.
Definition ObjectPool.h:635
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition SmartShape.h:684
static constexpr std::string_view XmlNodeName
XML node name for this type.
Definition Details.h:1865
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Details.h:1940
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:397
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1637
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1619
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1785
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2024
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2090
static MusxInstance< StaffComposite > createCurrent(const DocumentPtr &document, Cmper partId, StaffCmper staffId, MeasCmper measId, Edu eduPosition)
Calculates the current staff at the specified metric position by applying all relevant staff styles,...
Definition Staff.cpp:1065
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Staff.h:687
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2774
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2807
Represents the definition of a Finale staff.
Definition Staff.h:52
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Staff.h:507
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2832
std::shared_ptr< OthersPool > OthersPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:500
int16_t MeasCmper
Enigma meas Cmper (may be negative when not applicable)
Definition Fundamentals.h:64
std::shared_ptr< const T > MusxInstance
Defines the type of a musx instance stored in a pool.
Definition MusxInstance.h:39
constexpr Cmper SCORE_PARTID
The part id of the score.
Definition Fundamentals.h:79
constexpr bool is_pool_type_v
Value shortcut for is_pool_type.
Definition ObjectPool.h:64
std::shared_ptr< DetailsPool > DetailsPoolPtr
Shared DetailsPool pointer.
Definition ObjectPool.h:587
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
std::shared_ptr< TextsPool > TextsPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:661
int32_t Edu
"Enigma Durational Units" value (1024 per quarter note)
Definition Fundamentals.h:61
std::shared_ptr< OptionsPool > OptionsPoolPtr
Shared OptionsPool pointer.
Definition ObjectPool.h:446
std::weak_ptr< Document > DocumentWeakPtr
Shared weak Document pointer.
Definition BaseClasses.h:57
int32_t EntryNumber
Entry identifier.
Definition Fundamentals.h:69
std::shared_ptr< Document > DocumentPtr
Shared Document pointer.
Definition BaseClasses.h:55
int16_t StaffCmper
Enigma staff (staffId) Cmper (may be negative when not applicable)
Definition Fundamentals.h:65
std::shared_ptr< EntryPool > EntryPoolPtr
Shared EntryPool pointer.
Definition ObjectPool.h:622
object model for musx file (enigmaxml)
Definition BaseClasses.h:36
key type for storing in pool
Definition ObjectPool.h:82
std::optional< Cmper > cmper2
optional cmper2 for Details.
Definition ObjectPool.h:86
ObjectKey(std::string_view n, Cmper p, std::optional< Cmper > c1=std::nullopt, std::optional< Cmper > c2=std::nullopt, std::optional< int > i=std::nullopt)
explicit constructor for optional parameters
Definition ObjectPool.h:91
std::optional< Cmper > cmper1
optional cmper1 for Others, Texts, Details.
Definition ObjectPool.h:85
Cmper partId
the part this item is associated with (or 0 for score).
Definition ObjectPool.h:84
bool operator<(const ObjectKey &other) const
comparison operator for std::map
Definition ObjectPool.h:100
std::string_view nodeId
the identifier for this node. usually the XML node name.
Definition ObjectPool.h:83
std::optional< int > inci
optional inci for multi-inci classes
Definition ObjectPool.h:88
std::string description() const
provides a description of the key for diagnostic purposes
Definition ObjectPool.h:118
Type trait to determine if a class in a given pool.
Definition ObjectPool.h:60