26#include <unordered_map>
35#include "BaseClasses.h"
50template <
typename ObjectBaseType,
typename TopKeyElementType = std::
string>
67 std::optional<Cmper> c1 = std::nullopt,
68 std::optional<Cmper> c2 = std::nullopt,
94 if constexpr (std::is_same_v<TopKeyElementType, std::string>) {
97 return std::string(
"entry ") + std::to_string(
nodeId);
113 if (key.
inci.has_value()) {
115 noInciKey.
inci = std::nullopt;
116 auto currentIncis = getArray<ObjectBaseType>(noInciKey);
117 if (key.
inci.value() != currentIncis.size()) {
118 MUSX_INTEGRITY_ERROR(
"Node " + key.
nodeString() +
" has inci " + std::to_string(key.
inci.value()) +
" that is out of sequence.");
121 m_pool.emplace(key,
object);
122 auto it = m_shareMode.find(key.
nodeId);
123 if (it == m_shareMode.end()) {
124 m_shareMode.emplace(key.
nodeId, object->getShareMode());
125 }
else if (object->getShareMode() != it->second && object->getShareMode() !=
Base::ShareMode::All) {
127 m_shareMode[key.
nodeId] =
object->getShareMode();
129 MUSX_INTEGRITY_ERROR(
"Share mode for added " + key.
nodeString() +
" object [" + std::to_string(
int(object->getShareMode()))
130 +
"] does not match previous [" + std::to_string(
int(it->second)) +
"]");
147 template <
typename T>
150 std::vector<std::shared_ptr<T>> result;
152 auto rangeStart = m_pool.lower_bound(key);
153 auto rangeEnd = m_pool.upper_bound(
157 key.
cmper1.value_or((std::numeric_limits<Cmper>::max)()),
158 key.
cmper2.value_or((std::numeric_limits<Cmper>::max)()),
159 key.
inci.value_or((std::numeric_limits<Inci>::max)())
163 for (
auto it = rangeStart; it != rangeEnd; ++it) {
164 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
166 result.push_back(typedPtr);
183 template <
typename T>
188 auto it = m_shareMode.find(key.
nodeId);
191 if (it != m_shareMode.end()) {
192 forShareMode = it->second;
195 if constexpr (std::is_base_of_v<OthersBase, T>) {
196 if (!key.
cmper1.has_value()) {
197 throw std::invalid_argument(
"Array searches on partially shared Others must supply a cmper.");
199 }
else if constexpr (std::is_base_of_v<DetailsBase, T>) {
200 if (!key.
cmper1.has_value() || !key.
cmper2.has_value()) {
201 throw std::invalid_argument(
"Array searches on partially shared Details must supply both cmpers.");
206 auto keyResult = getArray<T>(key);
212 return getArray<T>(scoreKey);
226 template <
typename T>
229 auto it = m_pool.find(key);
230 if (it == m_pool.end()) {
233 auto typedPtr = std::dynamic_pointer_cast<T>(it->second);
248 template <
typename T>
251 if (
auto partVersion = get<T>(key)) {
260 return get<T>(scoreKey);
268 std::map<ObjectKey, ObjectPtr> m_pool;
269 std::unordered_map<TopKeyElementType, dom::Base::ShareMode> m_shareMode;
280 void add(
const std::string& nodeName,
const std::shared_ptr<OptionsBase>& instance)
282 if (instance->getPartId()) {
283 MUSX_INTEGRITY_ERROR(
"Options node " + nodeName +
" hase non-zero part id [" + std::to_string(instance->getPartId()) +
"]");
289 template <
typename T>
292 return ObjectPool::getArray<T>({ std::string(T::XmlNodeName),
SCORE_PARTID });
296 template <
typename T>
297 std::shared_ptr<T>
get()
const
299 return ObjectPool::get<T>({ std::string(T::XmlNodeName),
SCORE_PARTID });
313 void add(
const std::string& nodeName,
const std::shared_ptr<OthersBase>& instance)
314 {
ObjectPool::add({nodeName, instance->getPartId(), instance->getCmper(), std::nullopt, instance->getInci()}, instance); }
317 template <
typename T>
318 std::vector<std::shared_ptr<T>>
getArray(
Cmper partId, std::optional<Cmper> cmper = std::nullopt)
const
319 {
return ObjectPool::getArrayForPart<T>({ std::string(T::XmlNodeName), partId, cmper }); }
322 template <
typename T>
323 std::shared_ptr<T>
get(
Cmper partId,
Cmper cmper, std::optional<Inci> inci = std::nullopt)
const
324 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId, cmper, std::nullopt, inci}); }
339 void add(
const std::string& nodeName,
const std::shared_ptr<DetailsBase>& instance)
340 {
ObjectPool::add({nodeName, instance->getPartId(), instance->getCmper1(), instance->getCmper2(), instance->getInci()}, instance); }
343 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
344 std::vector<std::shared_ptr<T>>
getArray(
Cmper partId,
Cmper cmper1, std::optional<Cmper> cmper2 = std::nullopt)
const
345 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId, cmper1, cmper2 }); }
348 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
350 {
return ObjectPool::template getArrayForPart<T>({ std::string(T::XmlNodeName), partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff) }); }
353 template <
typename T,
typename std::enable_if_t<!std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
354 std::shared_ptr<T>
get(
Cmper partId,
Cmper cmper1,
Cmper cmper2, std::optional<Inci> inci = std::nullopt)
const
355 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId, cmper1, cmper2, inci}); }
358 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<EntryDetailsBase, T>,
int> = 0>
360 {
return ObjectPool::getEffectiveForPart<T>({std::string(T::XmlNodeName), partId,
Cmper(entnum >> 16),
Cmper(entnum & 0xffff), inci}); }
363 template <
typename T,
typename std::enable_if_t<std::is_base_of_v<NoteDetailsBase, T>,
int> = 0>
367 auto details = getArray<T>(entry->getPartId(), entry->getEntryNumber());
368 for (
const auto& detail : details) {
369 if (detail->getNoteId() == noteInfo->getNoteId()) {
389 template <
typename T>
391 {
return ObjectPool::get<T>({ entryNumber,
SCORE_PARTID }); }
401 void add(
const std::string& nodeName,
const std::shared_ptr<TextsBase>& instance)
403 if (instance->getPartId()) {
404 MUSX_INTEGRITY_ERROR(
"Texts node " + nodeName +
" hase non-zero part id [" + std::to_string(instance->getPartId()) +
"]");
406 ObjectPool::add({ nodeName, instance->getPartId(), instance->getTextNumber() }, instance);
410 template <
typename T>
411 std::vector<std::shared_ptr<T>>
getArray(std::optional<Cmper> cmper = std::nullopt)
const
412 {
return ObjectPool::getArray<T>({ std::string(T::XmlNodeName),
SCORE_PARTID, cmper }); }
415 template <
typename T>
417 {
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:72
A pool that manages collections of DetailsBase objects, organized by XML node names and Cmper values.
Definition ObjectPool.h:336
void add(const std::string &nodeName, const std::shared_ptr< DetailsBase > &instance)
DetailsPool version of ObjectPool::add.
Definition ObjectPool.h:339
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:344
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:354
std::shared_ptr< T > getForNote(const NoteInfoPtr noteInfo)
Returns the detail for a particular note.
Definition ObjectPool.h:364
std::vector< std::shared_ptr< T > > getArray(Cmper partId, EntryNumber entnum) const
EntryDetailsPool version of ObjectPool::getArray.
Definition ObjectPool.h:349
std::shared_ptr< T > get(Cmper partId, EntryNumber entnum, std::optional< Inci > inci=std::nullopt) const
EntryDetailsPool version of ObjectPool::get.
Definition ObjectPool.h:359
Entry pool.
Definition ObjectPool.h:382
void add(EntryNumber entryNumber, const std::shared_ptr< Entry > &instance)
EntryPool version of ObjectPool::add.
Definition ObjectPool.h:385
std::shared_ptr< T > get(EntryNumber entryNumber) const
EntryPool version of ObjectPool::get.
Definition ObjectPool.h:390
Wraps an EntryInfo instance and a note index.
Definition Entries.h:535
EntryInfoPtr getEntryInfo() const
Gets the entry info for this note.
Definition Entries.h:565
A pool that manages collections of OthersBase objects, organized by XML node names and Cmper values.
Definition ObjectPool.h:52
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:249
std::shared_ptr< ObjectBaseType > ObjectPtr
shared pointer to ObjectBaseType
Definition ObjectPool.h:55
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:148
virtual ~ObjectPool()=default
virtual destructor
void add(const ObjectKey &key, ObjectPtr object)
Adds an OthersBase object to the pool.
Definition ObjectPool.h:111
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:184
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:227
A pool that manages collections of OptionsBase objects that have no Cmper value.
Definition ObjectPool.h:277
std::shared_ptr< T > get() const
Scalar version of ObjectPool::get.
Definition ObjectPool.h:297
void add(const std::string &nodeName, const std::shared_ptr< OptionsBase > &instance)
Scalar version of ObjectPool::add.
Definition ObjectPool.h:280
std::vector< std::shared_ptr< T > > getArray() const
Scalar version of ObjectPool::getArray.
Definition ObjectPool.h:290
A pool that manages collections of OthersBase objects.
Definition ObjectPool.h:310
void add(const std::string &nodeName, const std::shared_ptr< OthersBase > &instance)
OthersPool version of ObjectPool::add.
Definition ObjectPool.h:313
std::vector< std::shared_ptr< T > > getArray(Cmper partId, std::optional< Cmper > cmper=std::nullopt) const
OthersPool version of ObjectPool::getArray.
Definition ObjectPool.h:318
std::shared_ptr< T > get(Cmper partId, Cmper cmper, std::optional< Inci > inci=std::nullopt) const
OthersPool version of ObjectPool::get.
Definition ObjectPool.h:323
Text pool.
Definition ObjectPool.h:398
std::vector< std::shared_ptr< T > > getArray(std::optional< Cmper > cmper=std::nullopt) const
Texts version of ObjectPool::getArray.
Definition ObjectPool.h:411
std::shared_ptr< T > get(Cmper cmper) const
Texts version of ObjectPool::get.
Definition ObjectPool.h:416
void add(const std::string &nodeName, const std::shared_ptr< TextsBase > &instance)
Texts version of ObjectPool::add.
Definition ObjectPool.h:401
std::shared_ptr< OthersPool > OthersPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:327
constexpr Cmper SCORE_PARTID
The part id of the score.
Definition Fundamentals.h:75
std::shared_ptr< DetailsPool > DetailsPoolPtr
Shared DetailsPool pointer.
Definition ObjectPool.h:378
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
std::shared_ptr< TextsPool > TextsPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:420
std::shared_ptr< OptionsPool > OptionsPoolPtr
Shared OptionsPool pointer.
Definition ObjectPool.h:303
int32_t EntryNumber
Entry identifier.
Definition Fundamentals.h:68
std::shared_ptr< EntryPool > EntryPoolPtr
Shared EntryPool pointer.
Definition ObjectPool.h:394
object model for musx file (enigmaxml)
Definition BaseClasses.h:32
key type for storing in pool
Definition ObjectPool.h:57
ObjectKey(const TopKeyElementType 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:65
std::string nodeString() const
Returns a string version of the nodeId for inclusion in messages.
Definition ObjectPool.h:92
std::optional< Cmper > cmper1
optional cmper1 for Others, Texts, Details.
Definition ObjectPool.h:60
Cmper partId
the part this item is associated with (or 0 for score).
Definition ObjectPool.h:59
std::optional< Inci > inci
optional inci for multi-inci classes
Definition ObjectPool.h:62
bool operator<(const ObjectKey &other) const
comparison operator for std::map
Definition ObjectPool.h:74
TopKeyElementType nodeId
the identifier for this node. usually the XML node name.
Definition ObjectPool.h:58
std::optional< Cmper > cmper2
optional cmper2 for Details.
Definition ObjectPool.h:61