26#include <unordered_map>
35#include "BaseClasses.h"
39#include "SmartShape.h"
53template <
typename ObjectBaseType>
70 std::optional<Cmper> c1 = std::nullopt,
71 std::optional<Cmper> c2 = std::nullopt,
97 std::string result =
nodeId +
" part " + std::to_string(
partId);
100 result +=
" cmpers [" + std::to_string(
cmper1.value()) +
", " + std::to_string(
cmper2.value()) +
"]";
102 result +=
" cmper " + std::to_string(
cmper1.value());
106 result +=
" inci " + std::to_string(
inci.value());
123 if (key.
inci.has_value()) {
125 noInciKey.
inci = std::nullopt;
126 auto currentIncis = getArray<ObjectBaseType>(noInciKey);
127 if (key.
inci.value() !=
int(currentIncis.size())) {
128 MUSX_INTEGRITY_ERROR(
"Node " + key.
nodeId +
" has inci " + std::to_string(key.
inci.value()) +
" that is out of sequence.");
131 auto [poolIt, emplaced] = m_pool.emplace(key,
object);
133 MUSX_INTEGRITY_ERROR(
"Attempted to add same key more than once: " + key.
description());
135 auto it = m_shareMode.find(key.
nodeId);
136 if (it == m_shareMode.end()) {
137 m_shareMode.emplace(key.
nodeId, object->getShareMode());
138 }
else if (object->getShareMode() != it->second && object->getShareMode() !=
Base::ShareMode::All) {
140 m_shareMode[key.
nodeId] =
object->getShareMode();
142 MUSX_INTEGRITY_ERROR(
"Share mode for added " + key.
nodeId +
" object [" + std::to_string(
int(object->getShareMode()))
143 +
"] does not match previous [" + std::to_string(
int(it->second)) +
"]");
160 template <
typename T>
163 std::vector<std::shared_ptr<T>> result;
165 auto rangeStart = m_pool.lower_bound(key);
166 auto rangeEnd = m_pool.upper_bound(
170 key.
cmper1.value_or((std::numeric_limits<Cmper>::max)()),
171 key.
cmper2.value_or((std::numeric_limits<Cmper>::max)()),
172 key.
inci.value_or((std::numeric_limits<Inci>::max)())
176 for (
auto it = rangeStart; it != rangeEnd; ++it) {
177 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
179 result.push_back(typedPtr);
196 template <
typename T>
201 auto it = m_shareMode.find(key.
nodeId);
204 if (it != m_shareMode.end()) {
205 forShareMode = it->second;
208 if constexpr (std::is_base_of_v<OthersBase, T>) {
209 if (!key.
cmper1.has_value()) {
210 throw std::invalid_argument(
"Array searches on partially shared Others must supply a cmper.");
212 }
else if constexpr (std::is_base_of_v<DetailsBase, T>) {
213 if (!key.
cmper1.has_value() || !key.
cmper2.has_value()) {
214 throw std::invalid_argument(
"Array searches on partially shared Details must supply both cmpers.");
219 auto keyResult = getArray<T>(key);
225 return getArray<T>(scoreKey);
239 template <
typename T>
242 auto it = m_pool.find(key);
243 if (it == m_pool.end()) {
246 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
261 template <
typename T>
264 if (
auto partVersion = get<T>(key)) {
273 return get<T>(scoreKey);
280 ObjectPool(
const std::unordered_map<std::string, dom::Base::ShareMode>& knownShareModes = {})
281 : m_shareMode(knownShareModes) {}
284 std::map<ObjectKey, ObjectPtr> m_pool;
285 std::unordered_map<std::string, dom::Base::ShareMode> m_shareMode;
296 void add(
const std::string& nodeName,
const std::shared_ptr<OptionsBase>& instance)
298 if (instance->getPartId()) {
299 MUSX_INTEGRITY_ERROR(
"Options node " + nodeName +
" hase non-zero part id [" + std::to_string(instance->getPartId()) +
"]");
305 template <
typename T>
308 return ObjectPool::getArray<T>({ std::string(T::XmlNodeName),
SCORE_PARTID });
312 template <
typename T>
313 std::shared_ptr<T>
get()
const
315 return ObjectPool::get<T>({ std::string(T::XmlNodeName),
SCORE_PARTID });
344 void add(
const std::string& nodeName,
const std::shared_ptr<OthersBase>& instance)
345 {
ObjectPool::add({nodeName, instance->getPartId(), instance->getCmper(), std::nullopt, instance->getInci()}, instance); }
348 template <
typename T>
349 std::vector<std::shared_ptr<T>>
getArray(
Cmper partId, std::optional<Cmper> cmper = std::nullopt)
const
350 {
return ObjectPool::getArrayForPart<T>({ std::string(T::XmlNodeName), partId, cmper }); }
353 template <
typename T>
354 std::shared_ptr<T>
get(
Cmper partId,
Cmper cmper, std::optional<Inci> inci = std::nullopt)
const
355 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId, cmper, std::nullopt, inci}); }
378 void add(
const std::string& nodeName,
const std::shared_ptr<DetailsBase>& instance)
379 {
ObjectPool::add({nodeName, instance->getPartId(), instance->getCmper1(), instance->getCmper2(), instance->getInci()}, instance); }
382 template <
typename T>
384 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId }); }
387 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
388 std::vector<std::shared_ptr<T>>
getArray(
Cmper partId,
Cmper cmper1, std::optional<Cmper> cmper2 = std::nullopt)
const
389 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId, cmper1, cmper2 }); }
392 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
394 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff) }); }
397 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
398 std::shared_ptr<T>
get(
Cmper partId,
Cmper cmper1,
Cmper cmper2, std::optional<Inci> inci = std::nullopt)
const
399 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId, cmper1, cmper2, inci}); }
402 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
404 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff), inci}); }
412 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<NoteDetailsBase, T>,
int> = 0>
415 auto details = getArray<T>(
419 for (
const auto& detail : details) {
420 if (detail->getNoteId() == noteInfo->getNoteId()) {
438 auto [it, emplaced] = m_pool.emplace(entryNumber, instance);
440 MUSX_INTEGRITY_ERROR(
"Entry number " + std::to_string(entryNumber) +
" added twice.");
447 const auto it = m_pool.find(entryNumber);
448 if (it == m_pool.end()) {
455 std::unordered_map<EntryNumber, std::shared_ptr<Entry>> m_pool;
465 void add(
const std::string& nodeName,
const std::shared_ptr<TextsBase>& instance)
467 if (instance->getPartId()) {
468 MUSX_INTEGRITY_ERROR(
"Texts node " + nodeName +
" hase non-zero part id [" + std::to_string(instance->getPartId()) +
"]");
470 ObjectPool::add({ nodeName, instance->getPartId(), instance->getTextNumber() }, instance);
474 template <
typename T>
475 std::vector<std::shared_ptr<T>>
getArray(std::optional<Cmper> cmper = std::nullopt)
const
476 {
return ObjectPool::getArray<T>({ std::string(T::XmlNodeName),
SCORE_PARTID, cmper }); }
479 template <
typename T>
481 {
return ObjectPool::get<T>({ std::string(T::XmlNodeName),
SCORE_PARTID, cmper, std::nullopt, std::nullopt }); }
ShareMode
Describes how this instance is shared between part and score.
Definition BaseClasses.h:68
A pool that manages collections of DetailsBase objects, organized by XML node names and Cmper values.
Definition ObjectPool.h:367
void add(const std::string &nodeName, const std::shared_ptr< DetailsBase > &instance)
DetailsPool version of ObjectPool::add.
Definition ObjectPool.h:378
std::vector< std::shared_ptr< T > > getArray(Cmper partId, Cmper cmper1, std::optional< Cmper > cmper2=std::nullopt) const
DetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:388
std::vector< std::shared_ptr< T > > getArray(Cmper partId) const
version of ObjectPool::getArray for getting all of them
Definition ObjectPool.h:383
DetailsPool()
Constructor.
Definition ObjectPool.h:370
std::shared_ptr< T > get(Cmper partId, Cmper cmper1, Cmper cmper2, std::optional< Inci > inci=std::nullopt) const
DetailsPool version of ObjectPool::get.
Definition ObjectPool.h:398
std::shared_ptr< T > getForNote(const NoteInfoPtr ¬eInfo, const std::optional< Cmper > &forPartId=std::nullopt)
Returns the detail for a particular note.
Definition ObjectPool.h:413
std::vector< std::shared_ptr< T > > getArray(Cmper partId, EntryNumber entnum) const
EntryDetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:393
std::shared_ptr< T > get(Cmper partId, EntryNumber entnum, std::optional< Inci > inci=std::nullopt) const
EntryDetailsPool version of ObjectPool::get.
Definition ObjectPool.h:403
std::shared_ptr< const EntryFrame > getFrame() const
Returns the frame.
Definition Entries.h:411
Entry pool.
Definition ObjectPool.h:433
void add(EntryNumber entryNumber, const std::shared_ptr< Entry > &instance)
Add an entry to the EntryPool. (Used by the factory.)
Definition ObjectPool.h:436
std::shared_ptr< Entry > get(EntryNumber entryNumber) const
Get an entry from the EntryPool.
Definition ObjectPool.h:445
Wraps an EntryInfo instance and a note index.
Definition Entries.h:833
EntryInfoPtr getEntryInfo() const
Gets the entry info for this note.
Definition Entries.h:868
A pool that manages collections of OthersBase objects, organized by XML node names and Cmper values.
Definition ObjectPool.h:55
std::shared_ptr< 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:262
std::shared_ptr< T > get(const ObjectKey &key) const
Retrieves the first (and usually only) object of a specific type from the pool.
Definition ObjectPool.h:240
virtual ~ObjectPool()=default
virtual destructor
std::vector< std::shared_ptr< T > > getArray(const ObjectKey &key) const
Retrieves a vector of objects of a specific type from the pool.
Definition ObjectPool.h:161
std::vector< std::shared_ptr< T > > getArrayForPart(const ObjectKey &key) const
Retrieves a vector of objects of a specific type from the pool.
Definition ObjectPool.h:197
ObjectPool(const std::unordered_map< std::string, dom::Base::ShareMode > &knownShareModes={})
Constructs the object pool.
Definition ObjectPool.h:280
void add(const ObjectKey &key, ObjectPtr object)
Adds an OthersBase object to the pool.
Definition ObjectPool.h:121
std::shared_ptr< ObjectBaseType > ObjectPtr
shared pointer to ObjectBaseType
Definition ObjectPool.h:58
A pool that manages collections of OptionsBase objects that have no Cmper value.
Definition ObjectPool.h:293
std::shared_ptr< T > get() const
Scalar version of ObjectPool::get.
Definition ObjectPool.h:313
void add(const std::string &nodeName, const std::shared_ptr< OptionsBase > &instance)
Scalar version of ObjectPool::add.
Definition ObjectPool.h:296
std::vector< std::shared_ptr< T > > getArray() const
Scalar version of ObjectPool::getArray.
Definition ObjectPool.h:306
A pool that manages collections of OthersBase objects.
Definition ObjectPool.h:326
OthersPool()
Constructor.
Definition ObjectPool.h:329
void add(const std::string &nodeName, const std::shared_ptr< OthersBase > &instance)
OthersPool version of ObjectPool::add.
Definition ObjectPool.h:344
std::vector< std::shared_ptr< T > > getArray(Cmper partId, std::optional< Cmper > cmper=std::nullopt) const
OthersPool version of ObjectPool::getArray.
Definition ObjectPool.h:349
std::shared_ptr< T > get(Cmper partId, Cmper cmper, std::optional< Inci > inci=std::nullopt) const
OthersPool version of ObjectPool::get.
Definition ObjectPool.h:354
Text pool.
Definition ObjectPool.h:462
std::vector< std::shared_ptr< T > > getArray(std::optional< Cmper > cmper=std::nullopt) const
Texts version of ObjectPool::getArray.
Definition ObjectPool.h:475
std::shared_ptr< T > get(Cmper cmper) const
Texts version of ObjectPool::get.
Definition ObjectPool.h:480
void add(const std::string &nodeName, const std::shared_ptr< TextsBase > &instance)
Texts version of ObjectPool::add.
Definition ObjectPool.h:465
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition SmartShape.h:420
static constexpr std::string_view XmlNodeName
XML node name for this type.
Definition Details.h:1274
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Details.h:1345
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:361
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:649
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1342
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1414
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1324
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1501
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1646
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2489
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2586
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2609
std::shared_ptr< OthersPool > OthersPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:358
constexpr Cmper SCORE_PARTID
The part id of the score.
Definition Fundamentals.h:80
std::shared_ptr< DetailsPool > DetailsPoolPtr
Shared DetailsPool pointer.
Definition ObjectPool.h:429
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
std::shared_ptr< TextsPool > TextsPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:484
std::shared_ptr< OptionsPool > OptionsPoolPtr
Shared OptionsPool pointer.
Definition ObjectPool.h:319
int32_t EntryNumber
Entry identifier.
Definition Fundamentals.h:68
std::shared_ptr< EntryPool > EntryPoolPtr
Shared EntryPool pointer.
Definition ObjectPool.h:458
object model for musx file (enigmaxml)
Definition BaseClasses.h:32
key type for storing in pool
Definition ObjectPool.h:60
std::optional< Cmper > cmper2
optional cmper2 for Details.
Definition ObjectPool.h:64
std::optional< Cmper > cmper1
optional cmper1 for Others, Texts, Details.
Definition ObjectPool.h:63
Cmper partId
the part this item is associated with (or 0 for score).
Definition ObjectPool.h:62
ObjectKey(const std::string n, Cmper p, std::optional< Cmper > c1=std::nullopt, std::optional< Cmper > c2=std::nullopt, std::optional< Inci > i=std::nullopt)
explicit constructor for optional parameters
Definition ObjectPool.h:68
std::optional< Inci > inci
optional inci for multi-inci classes
Definition ObjectPool.h:65
bool operator<(const ObjectKey &other) const
comparison operator for std::map
Definition ObjectPool.h:77
std::string description() const
provides a description of the key for diagnostic purposes
Definition ObjectPool.h:95
std::string nodeId
the identifier for this node. usually the XML node name.
Definition ObjectPool.h:61