26#include <unordered_map>
35#include "MusxInstance.h"
37#include "BaseClasses.h"
41#include "ShapeDesigner.h"
42#include "SmartShape.h"
45#ifndef DOXYGEN_SHOULD_IGNORE_THIS
49template<
class>
class PoolAccessor;
59template <
typename Pool,
typename T>
63template <
typename Pool,
typename T>
75template <
typename ObjectBaseType>
79 std::shared_ptr<const T> bindWithPartId(std::shared_ptr<const T> obj,
Cmper requestedPartId)
const
81 if constexpr (std::is_base_of_v<OthersBase, T> || std::is_base_of_v<DetailsBase, T>) {
82 if (obj && obj->getRequestedPartId() != requestedPartId) {
83 return PartContextCloner::copyWithPartId(obj, requestedPartId);
104 std::optional<Cmper> c1 = std::nullopt,
105 std::optional<Cmper> c2 = std::nullopt,
131 std::string result = std::string(
nodeId) +
" part " + std::to_string(
partId);
134 result +=
" cmpers [" + std::to_string(
cmper1.value()) +
", " + std::to_string(
cmper2.value()) +
"]";
136 result +=
" cmper " + std::to_string(
cmper1.value());
140 result +=
" inci " + std::to_string(
inci.value());
157 if (key.
inci.has_value()) {
159 noInciKey.
inci = std::nullopt;
160 auto currentIncis = getArray<ObjectBaseType>(noInciKey, key.
partId);
161 if (key.
inci.value() !=
int(currentIncis.size())) {
162 MUSX_INTEGRITY_ERROR(
"Node " + std::string(key.
nodeId) +
" has inci " + std::to_string(key.
inci.value()) +
" that is out of sequence.");
165 auto shareModeIt = m_shareMode.find(key.
nodeId);
166 auto [poolIt, emplaced] = m_pool.emplace(std::move(key),
object);
168 MUSX_INTEGRITY_ERROR(
"Attempted to add same key more than once: " + poolIt->first.description());
170 if (shareModeIt == m_shareMode.end()) {
171 m_shareMode.emplace(poolIt->first.nodeId, object->getShareMode());
172 }
else if (object->getShareMode() != shareModeIt->second && object->getShareMode() !=
Base::ShareMode::All) {
174 m_shareMode[poolIt->first.nodeId] =
object->getShareMode();
176 MUSX_INTEGRITY_ERROR(
"Share mode for added " + std::string(poolIt->first.nodeId) +
" object [" + std::to_string(
int(object->getShareMode()))
177 +
"] does not match previous [" + std::to_string(
int(shareModeIt->second)) +
"]");
195 template <
typename T>
200 auto rangeStart = m_pool.lower_bound(key);
201 auto rangeEnd = m_pool.upper_bound(
205 key.
cmper1.value_or((std::numeric_limits<Cmper>::max)()),
206 key.
cmper2.value_or((std::numeric_limits<Cmper>::max)()),
207 key.
inci.value_or((std::numeric_limits<Inci>::max)())
211 for (
auto it = rangeStart; it != rangeEnd; ++it) {
212 auto typedPtr = bindWithPartId<T>(std::dynamic_pointer_cast<T>(it->second), requestedPartId);
214 result.push_back(typedPtr);
231 template <
typename T>
236 auto it = m_shareMode.find(key.
nodeId);
239 if (it != m_shareMode.end()) {
240 forShareMode = it->second;
243 if constexpr (std::is_base_of_v<OthersBase, T>) {
244 if (!key.
cmper1.has_value()) {
245 throw std::invalid_argument(
"Array searches on partially shared Others must supply a cmper.");
247 }
else if constexpr (std::is_base_of_v<DetailsBase, T>) {
248 if (!key.
cmper1.has_value() || !key.
cmper2.has_value()) {
249 throw std::invalid_argument(
"Array searches on partially shared Details must supply both cmpers.");
254 auto keyResult = getArray<T>(key, key.
partId);
260 return getArray<T>(scoreKey, key.
partId);
274 template <
typename T>
277 auto it = m_pool.find(key);
278 if (it == m_pool.end()) {
281 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
299 template <
typename T>
302 if (
auto partVersion = getSource<T>(key)) {
310 auto it = m_shareMode.find(key.
nodeId);
317 return getSource<T>(scoreKey);
333 template <
typename T>
336 return bindWithPartId<T>(getEffectiveSourceForPart<T>(key), key.
partId);
344 : m_document(document), m_shareMode(knownShareModes) {}
348 std::unordered_map<std::string_view, dom::Base::ShareMode> m_shareMode;
350 std::map<ObjectKey, ObjectPtr> m_pool;
367 void add(std::string_view nodeName,
const std::shared_ptr<OptionsBase>& instance)
369 const Base* basePtr = instance.get();
371 MUSX_INTEGRITY_ERROR(
"Options node " + std::string(nodeName) +
" hase non-score part id [" + std::to_string(basePtr->
getSourcePartId()) +
"]");
377 template <
typename T>
380 static_assert(is_pool_type_v<OptionsPool, T>,
"Type T is not registered in OptionsPool");
385 template <
typename T>
388 static_assert(is_pool_type_v<OptionsPool, T>,
"Type T is not registered in OptionsPool");
427 void add(std::string_view nodeName,
const std::shared_ptr<OthersBase>& instance)
428 { m_pool.
add({nodeName, instance->getSourcePartId(), instance->getCmper(), std::nullopt, instance->getInci()}, instance); }
431 template <
typename T>
434 static_assert(is_pool_type_v<OthersPool, T>,
"Type T is not registered in OthersPool");
439 template <
typename T>
442 static_assert(is_pool_type_v<OthersPool, T>,
"Type T is not registered in OthersPool");
443 return m_pool.
getEffectiveForPart<T>({ T::XmlNodeName, partId, cmper, std::nullopt, inci });
470 void add(std::string_view nodeName,
const std::shared_ptr<DetailsBase>& instance)
471 { m_pool.
add({nodeName, instance->getSourcePartId(), instance->getCmper1(), instance->getCmper2(), instance->getInci()}, instance); }
474 template <
typename T,
typename = std::enable_if_t<is_pool_type_v<DetailsPool, T>>>
476 {
return m_pool.template getArrayForPart<T>({ T::XmlNodeName, partId }); }
479 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
482 static_assert(is_pool_type_v<DetailsPool, T>,
"Type T is not registered in DetailsPool");
483 return m_pool.template getArrayForPart<T>({ T::XmlNodeName, partId, cmper1, cmper2 });
487 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
490 static_assert(is_pool_type_v<DetailsPool, T>,
"Type T is not registered in DetailsPool");
491 return m_pool.template getArrayForPart<T>({ T::XmlNodeName, partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff) });
495 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
498 static_assert(is_pool_type_v<DetailsPool, T>,
"Type T is not registered in DetailsPool");
503 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
506 static_assert(is_pool_type_v<DetailsPool, T>,
"Type T is not registered in DetailsPool");
516 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<NoteDetailsBase, T>,
int> = 0>
519 static_assert(is_pool_type_v<DetailsPool, T>,
"Type T is not registered in DetailsPool");
520 auto details = getArray<T>(
524 for (
const auto& detail : details) {
525 if (detail->getNoteId() == noteInfo->getNoteId()) {
546 auto [it, emplaced] = m_pool.emplace(entryNumber, instance);
548 MUSX_INTEGRITY_ERROR(
"Entry number " + std::to_string(entryNumber) +
" added twice.");
555 const auto it = m_pool.find(entryNumber);
556 if (it == m_pool.end()) {
564 std::unordered_map<EntryNumber, std::shared_ptr<Entry>> m_pool;
573 friend class bench::PoolAccessor<
TextsPool>;
580 void add(std::string_view nodeName,
const std::shared_ptr<TextsBase>& instance)
582 const Base* basePtr = instance.get();
584 MUSX_INTEGRITY_ERROR(
"Texts node " + std::string(nodeName) +
" hase non-score part id [" + std::to_string(basePtr->
getSourcePartId()) +
"]");
586 m_pool.
add({ nodeName, basePtr->
getSourcePartId(), instance->getTextNumber() }, instance);
590 template <
typename T>
593 static_assert(is_pool_type_v<TextsPool, T>,
"Type T is not registered in TextsPool");
598 template <
typename T>
601 static_assert(is_pool_type_v<TextsPool, T>,
"Type T is not registered in TextsPool");
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:456
MusxInstanceList< T > getArray(Cmper partId) const
version of ObjectPool::getArray for getting all of them
Definition ObjectPool.h:475
MusxInstance< T > getForNote(const NoteInfoPtr ¬eInfo, const std::optional< Cmper > &forPartId=std::nullopt)
Returns the detail for a particular note.
Definition ObjectPool.h:517
DetailsPool(const DocumentWeakPtr &document)
Constructor.
Definition ObjectPool.h:462
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:504
MusxInstanceList< T > getArray(Cmper partId, EntryNumber entnum) const
EntryDetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:488
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:496
void add(std::string_view nodeName, const std::shared_ptr< DetailsBase > &instance)
DetailsPool version of ObjectPool::add.
Definition ObjectPool.h:470
MusxInstanceList< T > getArray(Cmper partId, Cmper cmper1, std::optional< Cmper > cmper2=std::nullopt) const
DetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:480
std::shared_ptr< const EntryFrame > getFrame() const
Returns the frame.
Definition Entries.h:421
Entry pool.
Definition ObjectPool.h:538
EntryPool(const DocumentWeakPtr &document)
Constructor function.
Definition ObjectPool.h:541
void add(EntryNumber entryNumber, const std::shared_ptr< Entry > &instance)
Add an entry to the EntryPool. (Used by the factory.)
Definition ObjectPool.h:544
MusxInstance< Entry > get(EntryNumber entryNumber) const
Get an entry from the EntryPool.
Definition ObjectPool.h:553
Provides optional per-type extension methods for MusxInstanceList.
Definition MusxInstance.h:96
Wraps an EntryInfo instance and a note index.
Definition Entries.h:861
EntryInfoPtr getEntryInfo() const
Gets the entry info for this note.
Definition Entries.h:896
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:343
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:275
MusxInstanceList< T > getArrayForPart(const ObjectKey &key) const
Retrieves a vector of objects of a specific type from the pool.
Definition ObjectPool.h:232
MusxInstanceList< T > getArray(const ObjectKey &key, Cmper requestedPartId) const
Retrieves a vector of objects of a specific type from the pool.
Definition ObjectPool.h:196
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:300
void add(ObjectKey key, ObjectPtr object)
Adds an ObjectBaseType object to the pool.
Definition ObjectPool.h:155
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:334
std::shared_ptr< ObjectBaseType > ObjectPtr
shared pointer to ObjectBaseType
Definition ObjectPool.h:91
A pool that manages collections of OptionsBase objects that have no Cmper value.
Definition ObjectPool.h:358
void add(std::string_view nodeName, const std::shared_ptr< OptionsBase > &instance)
Scalar version of ObjectPool::add.
Definition ObjectPool.h:367
MusxInstance< T > get() const
Get a single item out of the pool.
Definition ObjectPool.h:386
MusxInstanceList< T > getArray() const
Scalar version of ObjectPool::getArray.
Definition ObjectPool.h:378
OptionsPool(const DocumentWeakPtr &document)
Constructor function.
Definition ObjectPool.h:364
A pool that manages collections of OthersBase objects.
Definition ObjectPool.h:400
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:440
void add(std::string_view nodeName, const std::shared_ptr< OthersBase > &instance)
OthersPool version of ObjectPool::add.
Definition ObjectPool.h:427
OthersPool(const DocumentWeakPtr &document)
Constructor.
Definition ObjectPool.h:412
MusxInstanceList< T > getArray(Cmper partId, std::optional< Cmper > cmper=std::nullopt) const
OthersPool version of ObjectPool::getArray.
Definition ObjectPool.h:432
Text pool.
Definition ObjectPool.h:571
MusxInstanceList< T > getArray(std::optional< Cmper > cmper=std::nullopt) const
Texts version of ObjectPool::getArray.
Definition ObjectPool.h:591
TextsPool(const DocumentWeakPtr &document)
Constructor fundtion.
Definition ObjectPool.h:577
MusxInstance< T > get(Cmper cmper) const
Get a single item out of the pool.
Definition ObjectPool.h:599
void add(std::string_view nodeName, const std::shared_ptr< TextsBase > &instance)
Texts version of ObjectPool::add.
Definition ObjectPool.h:580
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition SmartShape.h:619
static constexpr std::string_view XmlNodeName
XML node name for this type.
Definition Details.h:1597
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Details.h:1672
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:371
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1508
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1490
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1656
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1882
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1937
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:793
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Staff.h:575
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2444
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2473
Represents the definition of a Finale staff.
Definition Staff.h:48
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Staff.h:425
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2498
std::shared_ptr< OthersPool > OthersPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:447
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:35
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:534
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
std::shared_ptr< TextsPool > TextsPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:606
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:393
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:567
object model for musx file (enigmaxml)
Definition BaseClasses.h:36
key type for storing in pool
Definition ObjectPool.h:93
std::optional< Cmper > cmper2
optional cmper2 for Details.
Definition ObjectPool.h:97
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:102
std::optional< Cmper > cmper1
optional cmper1 for Others, Texts, Details.
Definition ObjectPool.h:96
Cmper partId
the part this item is associated with (or 0 for score).
Definition ObjectPool.h:95
bool operator<(const ObjectKey &other) const
comparison operator for std::map
Definition ObjectPool.h:111
std::string_view nodeId
the identifier for this node. usually the XML node name.
Definition ObjectPool.h:94
std::optional< int > inci
optional inci for multi-inci classes
Definition ObjectPool.h:99
std::string description() const
provides a description of the key for diagnostic purposes
Definition ObjectPool.h:129
Type trait to determine if a class in a given pool.
Definition ObjectPool.h:60