UpdateHints.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * UpdateHints.h
  3. * -------------
  4. * Purpose: Hint type and abstraction class for passing around hints between module views.
  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 "openmpt/base/FlagSet.hpp"
  12. #include "../soundlib/Snd_defs.h"
  13. OPENMPT_NAMESPACE_BEGIN
  14. // Mutually exclusive hint categories
  15. enum HintCategory
  16. {
  17. HINTCAT_GLOBAL = 0, // Not a real category, since all other categories can be combined with this
  18. HINTCAT_GENERAL = 0,
  19. HINTCAT_PATTERNS = 1,
  20. HINTCAT_SAMPLES = 2,
  21. HINTCAT_INSTRUMENTS = 3,
  22. HINTCAT_SEQUENCE = 4,
  23. HINTCAT_PLUGINS = 5,
  24. HINTCAT_COMMENTS = 6,
  25. NUM_HINTCATS
  26. };
  27. enum HintType
  28. {
  29. // Hints that can be combined with any other hints (no parameter)
  30. HINT_NONE = 0x00, // No specific hint
  31. HINT_MODTYPE = 0x01, // Module type has changed. Generally this will force most things to update.
  32. HINT_MPTOPTIONS = 0x02, // Some OpenMPT options (e.g. colours) have changed which might require stuff to be redrawn.
  33. HINT_UNDO = 0x04, // Undo state information has changed
  34. HINT_ALLGLOBAL = HINT_MODTYPE | HINT_MPTOPTIONS | HINT_UNDO,
  35. // From here: Mutually exclusive hint categories
  36. // General module setting hints (GeneralHint)
  37. HINT_MODGENERAL = 0x10, // General global module settings have changed
  38. HINT_MODCHANNELS = 0x20, // Module channel settings have changed (e.g. channel volume). Parameter: Channel ID
  39. HINT_TUNINGS = 0x40, // Tuning collection was updated
  40. // Pattern-specific hints (PatternHint)
  41. HINT_PATTERNDATA = 0x10, // Pattern data has changed. Parameter: Pattern ID (0 = all patterns)
  42. HINT_PATTERNROW = 0x20, // A row of the currently edited pattern has changed. Parameter: Row number
  43. HINT_PATNAMES = 0x40, // Pattern names have changed. Parameter: Pattern ID (0 = all patterns)
  44. // Sample-specific hints (SampleHint)
  45. HINT_SAMPLEINFO = 0x10, // Sample properties have changed. Parameter: Sample ID (0 = all samples)
  46. HINT_SAMPLEDATA = 0x20, // Sample waveform has changed. Parameter: Sample ID (0 = all samples)
  47. HINT_SMPNAMES = 0x40, // Sample name has changed. Parameter: Sample ID (0 = all samples)
  48. // Instrument-specific hints (InstrumentHint)
  49. HINT_INSTRUMENT = 0x10, // Instrument properties have changed. Parameter: Instrument ID (0 = all instruments)
  50. HINT_ENVELOPE = 0x20, // An instrument envelope has changed. Parameter: Instrument ID (0 = all instruments)
  51. HINT_INSNAMES = 0x40, // Instrument name has changed. Parameter: Instrument ID (0 = all instruments)
  52. // Sequence-specific hints (SequenceHint)
  53. HINT_MODSEQUENCE = 0x10, // The pattern sequence has changed.
  54. HINT_SEQNAMES = 0x20, // Sequence names have changed. Parameter: Sequence ID (0 = all sequences)
  55. HINT_RESTARTPOS = 0x40, // Restart position has changed. Parameter: Sequence ID (0 = all sequences)
  56. // Plugin-specific hints (PluginHint)
  57. HINT_MIXPLUGINS = 0x10, // Plugin properties have changed. Parameter: Plugin ID (0 = all plugins, 1 = first plugin)
  58. HINT_PLUGINNAMES = 0x20, // Plugin names have changed. Parameter: Plugin ID (0 = all plugins, 1 = first plugin)
  59. HINT_PLUGINPARAM = 0x40, // Plugin parameter has changed. Parameter: Plugin ID (0 = all plugins, 1 = first plugin)
  60. // Comment text hints (CommentHint)
  61. HINT_MODCOMMENTS = 0x10, // Module comment text has changed
  62. };
  63. DECLARE_FLAGSET(HintType)
  64. struct UpdateHint
  65. {
  66. protected:
  67. using store_t = uint32;
  68. union
  69. {
  70. struct
  71. {
  72. store_t type : 7; // All HintType flags must fit into this.
  73. store_t category : 3; // All HintCategory types must fit into this.
  74. store_t item : 22;
  75. };
  76. store_t rawData;
  77. };
  78. UpdateHint(HintCategory category_, store_t item_ = 0) : type(HINT_NONE), category(category_), item(item_)
  79. {
  80. static_assert(sizeof(UpdateHint) == sizeof(store_t), "Internal UpdateHint size inconsistency");
  81. static_assert(sizeof(UpdateHint) <= sizeof(LPARAM), "Update hints are currently tunnelled through LPARAMs in MFC");
  82. MPT_ASSERT(static_cast<HintCategory>(category) == category_);
  83. MPT_ASSERT(UpdateHint::item == item);
  84. }
  85. template<typename T>
  86. MPT_FORCEINLINE T GetData() const { return static_cast<T>(item); }
  87. public:
  88. UpdateHint() : type(HINT_NONE), category(HINTCAT_GLOBAL), item(0) { }
  89. template<typename T>
  90. MPT_FORCEINLINE UpdateHint &SetData(T i) { item = i; MPT_ASSERT(item == i); return *this; }
  91. MPT_FORCEINLINE HintCategory GetCategory() const { return static_cast<HintCategory>(category); }
  92. MPT_FORCEINLINE FlagSet<HintType> GetType() const { return FlagSet<HintType>(static_cast<FlagSet<HintType>::store_type>(type)); }
  93. // CModDoc hint tunnelling
  94. static MPT_FORCEINLINE UpdateHint FromLPARAM(LPARAM rawData) { UpdateHint hint; hint.rawData = static_cast<store_t>(rawData); return hint; }
  95. MPT_FORCEINLINE LPARAM AsLPARAM() const { return rawData; }
  96. // Discard any hints that don't belong to class T.
  97. template<typename T>
  98. MPT_FORCEINLINE T ToType() const
  99. {
  100. T hint = static_cast<const T &>(*this);
  101. if(T::classCategory != static_cast<HintCategory>(category))
  102. {
  103. hint.type &= HINT_ALLGLOBAL;
  104. hint.item = 0;
  105. }
  106. return hint;
  107. }
  108. // Set global hint flags
  109. MPT_FORCEINLINE UpdateHint &ModType() { type |= HINT_MODTYPE; return *this; }
  110. MPT_FORCEINLINE UpdateHint &MPTOptions() { type |= HINT_MPTOPTIONS; return *this; }
  111. MPT_FORCEINLINE UpdateHint &Undo() { type |= HINT_UNDO; return *this; }
  112. };
  113. struct GeneralHint : public UpdateHint
  114. {
  115. static constexpr HintCategory classCategory = HINTCAT_GENERAL;
  116. GeneralHint() : UpdateHint(classCategory, 0) { }
  117. GeneralHint(CHANNELINDEX channel) : UpdateHint(classCategory, 1 + channel) { }
  118. MPT_FORCEINLINE GeneralHint &General() { type |= HINT_MODGENERAL; return *this; }
  119. MPT_FORCEINLINE GeneralHint &Channels() { type |= HINT_MODCHANNELS; return *this; }
  120. MPT_FORCEINLINE GeneralHint &Tunings() { type |= HINT_TUNINGS; return *this; }
  121. MPT_FORCEINLINE CHANNELINDEX GetChannel() const { return item ? static_cast<CHANNELINDEX>(item - 1) : CHANNELINDEX_INVALID; }
  122. };
  123. struct PatternHint : public UpdateHint
  124. {
  125. static constexpr HintCategory classCategory = HINTCAT_PATTERNS;
  126. PatternHint(PATTERNINDEX item = 0) : UpdateHint(classCategory, item) { }
  127. MPT_FORCEINLINE PatternHint &Data() { type |= HINT_PATTERNDATA; return *this; }
  128. MPT_FORCEINLINE PatternHint &Names() { type |= HINT_PATNAMES; return *this; }
  129. PATTERNINDEX GetPattern() const { return GetData<PATTERNINDEX>(); }
  130. };
  131. struct RowHint : public UpdateHint
  132. {
  133. static constexpr HintCategory classCategory = HINTCAT_PATTERNS;
  134. RowHint(ROWINDEX item = 0) : UpdateHint(classCategory, item) { type = HINT_PATTERNROW; }
  135. MPT_FORCEINLINE ROWINDEX GetRow() const { return GetData<ROWINDEX>(); }
  136. };
  137. struct SampleHint : public UpdateHint
  138. {
  139. static constexpr HintCategory classCategory = HINTCAT_SAMPLES;
  140. SampleHint(SAMPLEINDEX item = 0) : UpdateHint(classCategory, item) { }
  141. MPT_FORCEINLINE SampleHint &Info() { type |= HINT_SAMPLEINFO; return *this; }
  142. MPT_FORCEINLINE SampleHint &Data() { type |= HINT_SAMPLEDATA; return *this; }
  143. MPT_FORCEINLINE SampleHint &Names() { type |= HINT_SMPNAMES; return *this; }
  144. MPT_FORCEINLINE SAMPLEINDEX GetSample() const { return GetData<SAMPLEINDEX>(); }
  145. };
  146. struct InstrumentHint : public UpdateHint
  147. {
  148. static constexpr HintCategory classCategory = HINTCAT_INSTRUMENTS;
  149. InstrumentHint(INSTRUMENTINDEX item = 0) : UpdateHint(classCategory, item) { }
  150. MPT_FORCEINLINE InstrumentHint &Info() { type |= HINT_INSTRUMENT; return *this; }
  151. MPT_FORCEINLINE InstrumentHint &Envelope() { type |= HINT_ENVELOPE; return *this; }
  152. MPT_FORCEINLINE InstrumentHint &Names() { type |= HINT_INSNAMES; return *this; }
  153. MPT_FORCEINLINE INSTRUMENTINDEX GetInstrument() const { return GetData<INSTRUMENTINDEX>(); }
  154. };
  155. struct SequenceHint : public UpdateHint
  156. {
  157. static constexpr HintCategory classCategory = HINTCAT_SEQUENCE;
  158. SequenceHint(SEQUENCEINDEX item = 0) : UpdateHint(classCategory, item) { }
  159. MPT_FORCEINLINE SequenceHint &Data() { type |= HINT_MODSEQUENCE; return *this; }
  160. MPT_FORCEINLINE SequenceHint &Names() { type |= HINT_SEQNAMES; return *this; }
  161. MPT_FORCEINLINE SequenceHint &RestartPos() { type |= HINT_RESTARTPOS; return *this; }
  162. MPT_FORCEINLINE SEQUENCEINDEX GetSequence() const { return GetData<SEQUENCEINDEX>(); }
  163. };
  164. struct PluginHint : public UpdateHint
  165. {
  166. static constexpr HintCategory classCategory = HINTCAT_PLUGINS;
  167. PluginHint(PLUGINDEX item = 0) : UpdateHint(classCategory, item) { }
  168. MPT_FORCEINLINE PluginHint &Info() { type |= HINT_MIXPLUGINS; return *this; }
  169. MPT_FORCEINLINE PluginHint &Names() { type |= HINT_PLUGINNAMES; return *this; }
  170. MPT_FORCEINLINE PluginHint &Parameter() { type |= HINT_PLUGINPARAM; return *this; }
  171. MPT_FORCEINLINE PLUGINDEX GetPlugin() const { return GetData<PLUGINDEX>(); }
  172. };
  173. struct CommentHint : public UpdateHint
  174. {
  175. static constexpr HintCategory classCategory = HINTCAT_COMMENTS;
  176. CommentHint() : UpdateHint(classCategory) { type = HINT_MODCOMMENTS; }
  177. };
  178. OPENMPT_NAMESPACE_END