215 lines
8.8 KiB
C
215 lines
8.8 KiB
C
|
/*
|
||
|
* UpdateHints.h
|
||
|
* -------------
|
||
|
* Purpose: Hint type and abstraction class for passing around hints between module views.
|
||
|
* Notes : (currently none)
|
||
|
* Authors: OpenMPT Devs
|
||
|
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "openmpt/all/BuildSettings.hpp"
|
||
|
|
||
|
#include "openmpt/base/FlagSet.hpp"
|
||
|
#include "../soundlib/Snd_defs.h"
|
||
|
|
||
|
OPENMPT_NAMESPACE_BEGIN
|
||
|
|
||
|
// Mutually exclusive hint categories
|
||
|
enum HintCategory
|
||
|
{
|
||
|
HINTCAT_GLOBAL = 0, // Not a real category, since all other categories can be combined with this
|
||
|
HINTCAT_GENERAL = 0,
|
||
|
HINTCAT_PATTERNS = 1,
|
||
|
HINTCAT_SAMPLES = 2,
|
||
|
HINTCAT_INSTRUMENTS = 3,
|
||
|
HINTCAT_SEQUENCE = 4,
|
||
|
HINTCAT_PLUGINS = 5,
|
||
|
HINTCAT_COMMENTS = 6,
|
||
|
|
||
|
NUM_HINTCATS
|
||
|
};
|
||
|
|
||
|
enum HintType
|
||
|
{
|
||
|
// Hints that can be combined with any other hints (no parameter)
|
||
|
HINT_NONE = 0x00, // No specific hint
|
||
|
HINT_MODTYPE = 0x01, // Module type has changed. Generally this will force most things to update.
|
||
|
HINT_MPTOPTIONS = 0x02, // Some OpenMPT options (e.g. colours) have changed which might require stuff to be redrawn.
|
||
|
HINT_UNDO = 0x04, // Undo state information has changed
|
||
|
|
||
|
HINT_ALLGLOBAL = HINT_MODTYPE | HINT_MPTOPTIONS | HINT_UNDO,
|
||
|
|
||
|
// From here: Mutually exclusive hint categories
|
||
|
|
||
|
// General module setting hints (GeneralHint)
|
||
|
HINT_MODGENERAL = 0x10, // General global module settings have changed
|
||
|
HINT_MODCHANNELS = 0x20, // Module channel settings have changed (e.g. channel volume). Parameter: Channel ID
|
||
|
HINT_TUNINGS = 0x40, // Tuning collection was updated
|
||
|
// Pattern-specific hints (PatternHint)
|
||
|
HINT_PATTERNDATA = 0x10, // Pattern data has changed. Parameter: Pattern ID (0 = all patterns)
|
||
|
HINT_PATTERNROW = 0x20, // A row of the currently edited pattern has changed. Parameter: Row number
|
||
|
HINT_PATNAMES = 0x40, // Pattern names have changed. Parameter: Pattern ID (0 = all patterns)
|
||
|
// Sample-specific hints (SampleHint)
|
||
|
HINT_SAMPLEINFO = 0x10, // Sample properties have changed. Parameter: Sample ID (0 = all samples)
|
||
|
HINT_SAMPLEDATA = 0x20, // Sample waveform has changed. Parameter: Sample ID (0 = all samples)
|
||
|
HINT_SMPNAMES = 0x40, // Sample name has changed. Parameter: Sample ID (0 = all samples)
|
||
|
// Instrument-specific hints (InstrumentHint)
|
||
|
HINT_INSTRUMENT = 0x10, // Instrument properties have changed. Parameter: Instrument ID (0 = all instruments)
|
||
|
HINT_ENVELOPE = 0x20, // An instrument envelope has changed. Parameter: Instrument ID (0 = all instruments)
|
||
|
HINT_INSNAMES = 0x40, // Instrument name has changed. Parameter: Instrument ID (0 = all instruments)
|
||
|
// Sequence-specific hints (SequenceHint)
|
||
|
HINT_MODSEQUENCE = 0x10, // The pattern sequence has changed.
|
||
|
HINT_SEQNAMES = 0x20, // Sequence names have changed. Parameter: Sequence ID (0 = all sequences)
|
||
|
HINT_RESTARTPOS = 0x40, // Restart position has changed. Parameter: Sequence ID (0 = all sequences)
|
||
|
// Plugin-specific hints (PluginHint)
|
||
|
HINT_MIXPLUGINS = 0x10, // Plugin properties have changed. Parameter: Plugin ID (0 = all plugins, 1 = first plugin)
|
||
|
HINT_PLUGINNAMES = 0x20, // Plugin names have changed. Parameter: Plugin ID (0 = all plugins, 1 = first plugin)
|
||
|
HINT_PLUGINPARAM = 0x40, // Plugin parameter has changed. Parameter: Plugin ID (0 = all plugins, 1 = first plugin)
|
||
|
// Comment text hints (CommentHint)
|
||
|
HINT_MODCOMMENTS = 0x10, // Module comment text has changed
|
||
|
};
|
||
|
DECLARE_FLAGSET(HintType)
|
||
|
|
||
|
struct UpdateHint
|
||
|
{
|
||
|
protected:
|
||
|
using store_t = uint32;
|
||
|
union
|
||
|
{
|
||
|
struct
|
||
|
{
|
||
|
store_t type : 7; // All HintType flags must fit into this.
|
||
|
store_t category : 3; // All HintCategory types must fit into this.
|
||
|
store_t item : 22;
|
||
|
};
|
||
|
store_t rawData;
|
||
|
};
|
||
|
|
||
|
UpdateHint(HintCategory category_, store_t item_ = 0) : type(HINT_NONE), category(category_), item(item_)
|
||
|
{
|
||
|
static_assert(sizeof(UpdateHint) == sizeof(store_t), "Internal UpdateHint size inconsistency");
|
||
|
static_assert(sizeof(UpdateHint) <= sizeof(LPARAM), "Update hints are currently tunnelled through LPARAMs in MFC");
|
||
|
MPT_ASSERT(static_cast<HintCategory>(category) == category_);
|
||
|
MPT_ASSERT(UpdateHint::item == item);
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
MPT_FORCEINLINE T GetData() const { return static_cast<T>(item); }
|
||
|
|
||
|
public:
|
||
|
UpdateHint() : type(HINT_NONE), category(HINTCAT_GLOBAL), item(0) { }
|
||
|
|
||
|
template<typename T>
|
||
|
MPT_FORCEINLINE UpdateHint &SetData(T i) { item = i; MPT_ASSERT(item == i); return *this; }
|
||
|
|
||
|
MPT_FORCEINLINE HintCategory GetCategory() const { return static_cast<HintCategory>(category); }
|
||
|
MPT_FORCEINLINE FlagSet<HintType> GetType() const { return FlagSet<HintType>(static_cast<FlagSet<HintType>::store_type>(type)); }
|
||
|
|
||
|
// CModDoc hint tunnelling
|
||
|
static MPT_FORCEINLINE UpdateHint FromLPARAM(LPARAM rawData) { UpdateHint hint; hint.rawData = static_cast<store_t>(rawData); return hint; }
|
||
|
MPT_FORCEINLINE LPARAM AsLPARAM() const { return rawData; }
|
||
|
|
||
|
// Discard any hints that don't belong to class T.
|
||
|
template<typename T>
|
||
|
MPT_FORCEINLINE T ToType() const
|
||
|
{
|
||
|
T hint = static_cast<const T &>(*this);
|
||
|
if(T::classCategory != static_cast<HintCategory>(category))
|
||
|
{
|
||
|
hint.type &= HINT_ALLGLOBAL;
|
||
|
hint.item = 0;
|
||
|
}
|
||
|
return hint;
|
||
|
}
|
||
|
|
||
|
// Set global hint flags
|
||
|
MPT_FORCEINLINE UpdateHint &ModType() { type |= HINT_MODTYPE; return *this; }
|
||
|
MPT_FORCEINLINE UpdateHint &MPTOptions() { type |= HINT_MPTOPTIONS; return *this; }
|
||
|
MPT_FORCEINLINE UpdateHint &Undo() { type |= HINT_UNDO; return *this; }
|
||
|
};
|
||
|
|
||
|
struct GeneralHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_GENERAL;
|
||
|
GeneralHint() : UpdateHint(classCategory, 0) { }
|
||
|
GeneralHint(CHANNELINDEX channel) : UpdateHint(classCategory, 1 + channel) { }
|
||
|
MPT_FORCEINLINE GeneralHint &General() { type |= HINT_MODGENERAL; return *this; }
|
||
|
MPT_FORCEINLINE GeneralHint &Channels() { type |= HINT_MODCHANNELS; return *this; }
|
||
|
MPT_FORCEINLINE GeneralHint &Tunings() { type |= HINT_TUNINGS; return *this; }
|
||
|
|
||
|
MPT_FORCEINLINE CHANNELINDEX GetChannel() const { return item ? static_cast<CHANNELINDEX>(item - 1) : CHANNELINDEX_INVALID; }
|
||
|
};
|
||
|
|
||
|
struct PatternHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_PATTERNS;
|
||
|
PatternHint(PATTERNINDEX item = 0) : UpdateHint(classCategory, item) { }
|
||
|
MPT_FORCEINLINE PatternHint &Data() { type |= HINT_PATTERNDATA; return *this; }
|
||
|
MPT_FORCEINLINE PatternHint &Names() { type |= HINT_PATNAMES; return *this; }
|
||
|
|
||
|
PATTERNINDEX GetPattern() const { return GetData<PATTERNINDEX>(); }
|
||
|
};
|
||
|
|
||
|
struct RowHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_PATTERNS;
|
||
|
RowHint(ROWINDEX item = 0) : UpdateHint(classCategory, item) { type = HINT_PATTERNROW; }
|
||
|
|
||
|
MPT_FORCEINLINE ROWINDEX GetRow() const { return GetData<ROWINDEX>(); }
|
||
|
};
|
||
|
|
||
|
struct SampleHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_SAMPLES;
|
||
|
SampleHint(SAMPLEINDEX item = 0) : UpdateHint(classCategory, item) { }
|
||
|
MPT_FORCEINLINE SampleHint &Info() { type |= HINT_SAMPLEINFO; return *this; }
|
||
|
MPT_FORCEINLINE SampleHint &Data() { type |= HINT_SAMPLEDATA; return *this; }
|
||
|
MPT_FORCEINLINE SampleHint &Names() { type |= HINT_SMPNAMES; return *this; }
|
||
|
|
||
|
MPT_FORCEINLINE SAMPLEINDEX GetSample() const { return GetData<SAMPLEINDEX>(); }
|
||
|
};
|
||
|
|
||
|
struct InstrumentHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_INSTRUMENTS;
|
||
|
InstrumentHint(INSTRUMENTINDEX item = 0) : UpdateHint(classCategory, item) { }
|
||
|
MPT_FORCEINLINE InstrumentHint &Info() { type |= HINT_INSTRUMENT; return *this; }
|
||
|
MPT_FORCEINLINE InstrumentHint &Envelope() { type |= HINT_ENVELOPE; return *this; }
|
||
|
MPT_FORCEINLINE InstrumentHint &Names() { type |= HINT_INSNAMES; return *this; }
|
||
|
|
||
|
MPT_FORCEINLINE INSTRUMENTINDEX GetInstrument() const { return GetData<INSTRUMENTINDEX>(); }
|
||
|
};
|
||
|
|
||
|
struct SequenceHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_SEQUENCE;
|
||
|
SequenceHint(SEQUENCEINDEX item = 0) : UpdateHint(classCategory, item) { }
|
||
|
MPT_FORCEINLINE SequenceHint &Data() { type |= HINT_MODSEQUENCE; return *this; }
|
||
|
MPT_FORCEINLINE SequenceHint &Names() { type |= HINT_SEQNAMES; return *this; }
|
||
|
MPT_FORCEINLINE SequenceHint &RestartPos() { type |= HINT_RESTARTPOS; return *this; }
|
||
|
|
||
|
MPT_FORCEINLINE SEQUENCEINDEX GetSequence() const { return GetData<SEQUENCEINDEX>(); }
|
||
|
};
|
||
|
|
||
|
struct PluginHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_PLUGINS;
|
||
|
PluginHint(PLUGINDEX item = 0) : UpdateHint(classCategory, item) { }
|
||
|
MPT_FORCEINLINE PluginHint &Info() { type |= HINT_MIXPLUGINS; return *this; }
|
||
|
MPT_FORCEINLINE PluginHint &Names() { type |= HINT_PLUGINNAMES; return *this; }
|
||
|
MPT_FORCEINLINE PluginHint &Parameter() { type |= HINT_PLUGINPARAM; return *this; }
|
||
|
|
||
|
MPT_FORCEINLINE PLUGINDEX GetPlugin() const { return GetData<PLUGINDEX>(); }
|
||
|
};
|
||
|
|
||
|
struct CommentHint : public UpdateHint
|
||
|
{
|
||
|
static constexpr HintCategory classCategory = HINTCAT_COMMENTS;
|
||
|
CommentHint() : UpdateHint(classCategory) { type = HINT_MODCOMMENTS; }
|
||
|
};
|
||
|
|
||
|
OPENMPT_NAMESPACE_END
|