patternContainer.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * PatternContainer.h
  3. * ------------------
  4. * Purpose: Container class for managing patterns.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #pragma once
  10. #include "openmpt/all/BuildSettings.hpp"
  11. #include "pattern.h"
  12. #include <algorithm>
  13. OPENMPT_NAMESPACE_BEGIN
  14. class CSoundFile;
  15. class CPatternContainer
  16. {
  17. public:
  18. CPattern& operator[](const int pat) { return m_Patterns[pat]; }
  19. const CPattern& operator[](const int pat) const { return m_Patterns[pat]; }
  20. public:
  21. CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) { }
  22. // Empty and initialize all patterns.
  23. void ClearPatterns();
  24. // Delete all patterns.
  25. void DestroyPatterns();
  26. // Insert (default)pattern to given position. If pattern already exists at that position,
  27. // ignoring request. Returns true on success, false otherwise.
  28. bool Insert(const PATTERNINDEX index, const ROWINDEX rows);
  29. // Insert pattern to position with the lowest index, and return that index, PATTERNINDEX_INVALID on failure.
  30. // If respectQtyLimits is true, inserting patterns will fail if the resulting pattern index would exceed the current format's pattern quantity limits.
  31. PATTERNINDEX InsertAny(const ROWINDEX rows, bool respectQtyLimits = false);
  32. // Duplicate an existing pattern. Returns new pattern index on success, or PATTERNINDEX_INVALID on failure.
  33. // If respectQtyLimits is true, inserting patterns will fail if the resulting pattern index would exceed the current format's pattern quantity limits.
  34. PATTERNINDEX Duplicate(PATTERNINDEX from, bool respectQtyLimits = false);
  35. //Remove pattern from given position. Currently it actually makes the pattern
  36. //'invisible' - the pattern data is cleared but the actual pattern object won't get removed.
  37. void Remove(const PATTERNINDEX index);
  38. // Applies function object for modcommands in patterns in given range.
  39. // Return: Copy of the function object.
  40. template <class Func>
  41. Func ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func);
  42. template <class Func>
  43. Func ForEachModCommand(Func func) { return ForEachModCommand(0, Size() - 1, func); }
  44. std::vector<CPattern>::iterator begin() { return m_Patterns.begin(); }
  45. std::vector<CPattern>::const_iterator begin() const { return m_Patterns.begin(); }
  46. std::vector<CPattern>::const_iterator cbegin() const { return m_Patterns.cbegin(); }
  47. std::vector<CPattern>::iterator end() { return m_Patterns.end(); }
  48. std::vector<CPattern>::const_iterator end() const { return m_Patterns.end(); }
  49. std::vector<CPattern>::const_iterator cend() const { return m_Patterns.cend(); }
  50. PATTERNINDEX Size() const { return static_cast<PATTERNINDEX>(m_Patterns.size()); }
  51. CSoundFile& GetSoundFile() { return m_rSndFile; }
  52. const CSoundFile& GetSoundFile() const { return m_rSndFile; }
  53. // Return true if pattern can be accessed with operator[](iPat), false otherwise.
  54. bool IsValidIndex(const PATTERNINDEX iPat) const { return (iPat < Size()); }
  55. // Return true if IsValidIndex() is true and the corresponding pattern has allocated modcommand array, false otherwise.
  56. bool IsValidPat(const PATTERNINDEX iPat) const { return IsValidIndex(iPat) && m_Patterns[iPat].IsValid(); }
  57. // Returns true if the pattern is empty, i.e. there are no notes/effects in this pattern
  58. bool IsPatternEmpty(const PATTERNINDEX nPat) const;
  59. void ResizeArray(const PATTERNINDEX newSize);
  60. void OnModTypeChanged(const MODTYPE oldtype);
  61. // Returns index of last valid pattern + 1, zero if no such pattern exists.
  62. PATTERNINDEX GetNumPatterns() const;
  63. // Returns index of highest pattern with pattern named + 1.
  64. PATTERNINDEX GetNumNamedPatterns() const;
  65. private:
  66. std::vector<CPattern> m_Patterns;
  67. CSoundFile &m_rSndFile;
  68. };
  69. template <class Func>
  70. Func CPatternContainer::ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func)
  71. {
  72. if (nStartPat > nLastPat || nLastPat >= Size())
  73. return func;
  74. for (PATTERNINDEX nPat = nStartPat; nPat <= nLastPat; nPat++) if (m_Patterns[nPat].IsValid())
  75. std::for_each(m_Patterns[nPat].begin(), m_Patterns[nPat].end(), func);
  76. return func;
  77. }
  78. const char FileIdPatterns[] = "mptPc";
  79. void ReadModPatterns(std::istream& iStrm, CPatternContainer& patc, const size_t nSize = 0);
  80. void WriteModPatterns(std::ostream& oStrm, const CPatternContainer& patc);
  81. OPENMPT_NAMESPACE_END