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,
106 if (key.
inci.has_value()) {
108 noInciKey.
inci = std::nullopt;
109 auto currentIncis = getArray<ObjectBaseType>(noInciKey);
110 if (key.
inci.value() !=
int(currentIncis.size())) {
111 MUSX_INTEGRITY_ERROR(
"Node " + key.
nodeId +
" has inci " + std::to_string(key.
inci.value()) +
" that is out of sequence.");
114 m_pool.emplace(key,
object);
115 auto it = m_shareMode.find(key.
nodeId);
116 if (it == m_shareMode.end()) {
117 m_shareMode.emplace(key.
nodeId, object->getShareMode());
118 }
else if (object->getShareMode() != it->second && object->getShareMode() !=
Base::ShareMode::All) {
120 m_shareMode[key.
nodeId] =
object->getShareMode();
122 MUSX_INTEGRITY_ERROR(
"Share mode for added " + key.
nodeId +
" object [" + std::to_string(
int(object->getShareMode()))
123 +
"] does not match previous [" + std::to_string(
int(it->second)) +
"]");
140 template <
typename T>
143 std::vector<std::shared_ptr<T>> result;
145 auto rangeStart = m_pool.lower_bound(key);
146 auto rangeEnd = m_pool.upper_bound(
150 key.
cmper1.value_or((std::numeric_limits<Cmper>::max)()),
151 key.
cmper2.value_or((std::numeric_limits<Cmper>::max)()),
152 key.
inci.value_or((std::numeric_limits<Inci>::max)())
156 for (
auto it = rangeStart; it != rangeEnd; ++it) {
157 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
159 result.push_back(typedPtr);
176 template <
typename T>
181 auto it = m_shareMode.find(key.
nodeId);
184 if (it != m_shareMode.end()) {
185 forShareMode = it->second;
188 if constexpr (std::is_base_of_v<OthersBase, T>) {
189 if (!key.
cmper1.has_value()) {
190 throw std::invalid_argument(
"Array searches on partially shared Others must supply a cmper.");
192 }
else if constexpr (std::is_base_of_v<DetailsBase, T>) {
193 if (!key.
cmper1.has_value() || !key.
cmper2.has_value()) {
194 throw std::invalid_argument(
"Array searches on partially shared Details must supply both cmpers.");
199 auto keyResult = getArray<T>(key);
205 return getArray<T>(scoreKey);
219 template <
typename T>
222 auto it = m_pool.find(key);
223 if (it == m_pool.end()) {
226 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
241 template <
typename T>
244 if (
auto partVersion = get<T>(key)) {
253 return get<T>(scoreKey);
260 ObjectPool(
const std::unordered_map<std::string, dom::Base::ShareMode>& knownShareModes = {})
261 : m_shareMode(knownShareModes) {}
264 std::map<ObjectKey, ObjectPtr> m_pool;
265 std::unordered_map<std::string, dom::Base::ShareMode> m_shareMode;
276 void add(
const std::string& nodeName,
const std::shared_ptr<OptionsBase>& instance)
278 if (instance->getPartId()) {
279 MUSX_INTEGRITY_ERROR(
"Options node " + nodeName +
" hase non-zero part id [" + std::to_string(instance->getPartId()) +
"]");
285 template <
typename T>
288 return ObjectPool::getArray<T>({ std::string(T::XmlNodeName),
SCORE_PARTID });
292 template <
typename T>
293 std::shared_ptr<T>
get()
const
295 return ObjectPool::get<T>({ std::string(T::XmlNodeName),
SCORE_PARTID });
324 void add(
const std::string& nodeName,
const std::shared_ptr<OthersBase>& instance)
325 {
ObjectPool::add({nodeName, instance->getPartId(), instance->getCmper(), std::nullopt, instance->getInci()}, instance); }
328 template <
typename T>
329 std::vector<std::shared_ptr<T>>
getArray(
Cmper partId, std::optional<Cmper> cmper = std::nullopt)
const
330 {
return ObjectPool::getArrayForPart<T>({ std::string(T::XmlNodeName), partId, cmper }); }
333 template <
typename T>
334 std::shared_ptr<T>
get(
Cmper partId,
Cmper cmper, std::optional<Inci> inci = std::nullopt)
const
335 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId, cmper, std::nullopt, inci}); }
358 void add(
const std::string& nodeName,
const std::shared_ptr<DetailsBase>& instance)
359 {
ObjectPool::add({nodeName, instance->getPartId(), instance->getCmper1(), instance->getCmper2(), instance->getInci()}, instance); }
362 template <
typename T>
364 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId }); }
367 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
368 std::vector<std::shared_ptr<T>>
getArray(
Cmper partId,
Cmper cmper1, std::optional<Cmper> cmper2 = std::nullopt)
const
369 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId, cmper1, cmper2 }); }
372 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
374 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff) }); }
377 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
378 std::shared_ptr<T>
get(
Cmper partId,
Cmper cmper1,
Cmper cmper2, std::optional<Inci> inci = std::nullopt)
const
379 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId, cmper1, cmper2, inci}); }
382 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
384 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff), inci}); }
392 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<NoteDetailsBase, T>,
int> = 0>
395 auto details = getArray<T>(
399 for (
const auto& detail : details) {
400 if (detail->getNoteId() == noteInfo->getNoteId()) {
418 auto [it, emplaced] = m_pool.emplace(entryNumber, instance);
420 MUSX_INTEGRITY_ERROR(
"Entry number " + std::to_string(entryNumber) +
" added twice.");
427 const auto it = m_pool.find(entryNumber);
428 if (it == m_pool.end()) {
435 std::unordered_map<EntryNumber, std::shared_ptr<Entry>> m_pool;
445 void add(
const std::string& nodeName,
const std::shared_ptr<TextsBase>& instance)
447 if (instance->getPartId()) {
448 MUSX_INTEGRITY_ERROR(
"Texts node " + nodeName +
" hase non-zero part id [" + std::to_string(instance->getPartId()) +
"]");
450 ObjectPool::add({ nodeName, instance->getPartId(), instance->getTextNumber() }, instance);
454 template <
typename T>
455 std::vector<std::shared_ptr<T>>
getArray(std::optional<Cmper> cmper = std::nullopt)
const
456 {
return ObjectPool::getArray<T>({ std::string(T::XmlNodeName),
SCORE_PARTID, cmper }); }
459 template <
typename T>
461 {
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:347
void add(const std::string &nodeName, const std::shared_ptr< DetailsBase > &instance)
DetailsPool version of ObjectPool::add.
Definition ObjectPool.h:358
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:368
std::vector< std::shared_ptr< T > > getArray(Cmper partId) const
version of ObjectPool::getArray for getting all of them
Definition ObjectPool.h:363
DetailsPool()
Constructor.
Definition ObjectPool.h:350
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:378
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:393
std::vector< std::shared_ptr< T > > getArray(Cmper partId, EntryNumber entnum) const
EntryDetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:373
std::shared_ptr< T > get(Cmper partId, EntryNumber entnum, std::optional< Inci > inci=std::nullopt) const
EntryDetailsPool version of ObjectPool::get.
Definition ObjectPool.h:383
std::shared_ptr< const EntryFrame > getFrame() const
Returns the frame.
Definition Entries.h:300
Entry pool.
Definition ObjectPool.h:413
void add(EntryNumber entryNumber, const std::shared_ptr< Entry > &instance)
Add an entry to the EntryPool. (Used by the factory.)
Definition ObjectPool.h:416
std::shared_ptr< Entry > get(EntryNumber entryNumber) const
Get an entry from the EntryPool.
Definition ObjectPool.h:425
Wraps an EntryInfo instance and a note index.
Definition Entries.h:670
EntryInfoPtr getEntryInfo() const
Gets the entry info for this note.
Definition Entries.h:705
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:242
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:220
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:141
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:177
ObjectPool(const std::unordered_map< std::string, dom::Base::ShareMode > &knownShareModes={})
Constructs the object pool.
Definition ObjectPool.h:260
void add(const ObjectKey &key, ObjectPtr object)
Adds an OthersBase object to the pool.
Definition ObjectPool.h:104
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:273
std::shared_ptr< T > get() const
Scalar version of ObjectPool::get.
Definition ObjectPool.h:293
void add(const std::string &nodeName, const std::shared_ptr< OptionsBase > &instance)
Scalar version of ObjectPool::add.
Definition ObjectPool.h:276
std::vector< std::shared_ptr< T > > getArray() const
Scalar version of ObjectPool::getArray.
Definition ObjectPool.h:286
A pool that manages collections of OthersBase objects.
Definition ObjectPool.h:306
OthersPool()
Constructor.
Definition ObjectPool.h:309
void add(const std::string &nodeName, const std::shared_ptr< OthersBase > &instance)
OthersPool version of ObjectPool::add.
Definition ObjectPool.h:324
std::vector< std::shared_ptr< T > > getArray(Cmper partId, std::optional< Cmper > cmper=std::nullopt) const
OthersPool version of ObjectPool::getArray.
Definition ObjectPool.h:329
std::shared_ptr< T > get(Cmper partId, Cmper cmper, std::optional< Inci > inci=std::nullopt) const
OthersPool version of ObjectPool::get.
Definition ObjectPool.h:334
Text pool.
Definition ObjectPool.h:442
std::vector< std::shared_ptr< T > > getArray(std::optional< Cmper > cmper=std::nullopt) const
Texts version of ObjectPool::getArray.
Definition ObjectPool.h:455
std::shared_ptr< T > get(Cmper cmper) const
Texts version of ObjectPool::get.
Definition ObjectPool.h:460
void add(const std::string &nodeName, const std::shared_ptr< TextsBase > &instance)
Texts version of ObjectPool::add.
Definition ObjectPool.h:445
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition SmartShape.h:417
static constexpr std::string_view XmlNodeName
XML node name for this type.
Definition Details.h:1259
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Details.h:1315
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:360
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:646
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1302
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1350
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1284
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1437
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:1582
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2389
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2483
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Others.h:2506
std::shared_ptr< OthersPool > OthersPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:338
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:409
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
std::shared_ptr< TextsPool > TextsPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:464
std::shared_ptr< OptionsPool > OptionsPoolPtr
Shared OptionsPool pointer.
Definition ObjectPool.h:299
int32_t EntryNumber
Entry identifier.
Definition Fundamentals.h:68
std::shared_ptr< EntryPool > EntryPoolPtr
Shared EntryPool pointer.
Definition ObjectPool.h:438
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 nodeId
the identifier for this node. usually the XML node name.
Definition ObjectPool.h:61