1 #pragma once
2 
3 #include <QObject>
4 #include <QMap>
5 #include <QList>
6 
7 #include "engine/channelhandle.h"
8 #include "util/class.h"
9 #include "effects/effectchain.h"
10 
11 class ControlObject;
12 class ControlPushButton;
13 class ControlEncoder;
14 class EffectChainSlot;
15 
16 class EffectChainSlot : public QObject {
17     Q_OBJECT
18   public:
19     EffectChainSlot(EffectRack* pRack,
20                     const QString& group,
21                     const unsigned int iChainNumber);
22     virtual ~EffectChainSlot();
23 
24     // Get the ID of the loaded EffectChain
25     QString id() const;
26 
27     unsigned int numSlots() const;
28     EffectSlotPointer addEffectSlot(const QString& group);
29     EffectSlotPointer getEffectSlot(unsigned int slotNumber);
30 
31     void loadEffectChainToSlot(EffectChainPointer pEffectChain);
32     void updateRoutingSwitches();
33     EffectChainPointer getEffectChain() const;
34     EffectChainPointer getOrCreateEffectChain(EffectsManager* pEffectsManager);
35 
36     void registerInputChannel(const ChannelHandleAndGroup& handle_group);
37 
38     double getSuperParameter() const;
39     void setSuperParameter(double value, bool force = false);
40     void setSuperParameterDefaultValue(double value);
41 
42     // Unload the loaded EffectChain.
43     void clear();
44 
45     unsigned int getChainSlotNumber() const;
46 
getGroup()47     const QString& getGroup() const {
48         return m_group;
49     }
50 
51     QDomElement toXml(QDomDocument* doc) const;
52     void loadChainSlotFromXml(const QDomElement& effectChainElement);
53 
54   signals:
55     // Indicates that the effect pEffect has been loaded into slotNumber of
56     // EffectChainSlot chainNumber. pEffect may be an invalid pointer, which
57     // indicates that a previously loaded effect was removed from the slot.
58     void effectLoaded(EffectPointer pEffect, unsigned int chainNumber,
59                       unsigned int slotNumber);
60 
61     // Indicates that the given EffectChain was loaded into this
62     // EffectChainSlot
63     void effectChainLoaded(EffectChainPointer pEffectChain);
64 
65     // Signal that whoever is in charge of this EffectChainSlot should load the
66     // next EffectChain into it.
67     void nextChain(unsigned int iChainSlotNumber,
68                    EffectChainPointer pEffectChain);
69 
70     // Signal that whoever is in charge of this EffectChainSlot should load the
71     // previous EffectChain into it.
72     void prevChain(unsigned int iChainSlotNumber,
73                    EffectChainPointer pEffectChain);
74 
75     // Signal that whoever is in charge of this EffectChainSlot should clear
76     // this EffectChain (by removing the chain from this EffectChainSlot).
77     void clearChain(unsigned int iChainNumber, EffectChainPointer pEffectChain);
78 
79     // Signal that whoever is in charge of this EffectChainSlot should load the
80     // next Effect into the specified EffectSlot.
81     void nextEffect(unsigned int iChainSlotNumber,
82                     unsigned int iEffectSlotNumber,
83                     EffectPointer pEffect);
84 
85     // Signal that whoever is in charge of this EffectChainSlot should load the
86     // previous Effect into the specified EffectSlot.
87     void prevEffect(unsigned int iChainSlotNumber,
88                     unsigned int iEffectSlotNumber,
89                     EffectPointer pEffect);
90 
91     // Signal that indicates that the EffectChainSlot has been updated.
92     void updated();
93 
94 
95   private slots:
96     void slotChainEffectChanged(unsigned int effectSlotNumber, bool shouldEmit);
97     void slotChainNameChanged(const QString& name);
98     void slotChainEnabledChanged(bool enabled);
99     void slotChainMixChanged(double mix);
100     void slotChainMixModeChanged(EffectChainMixMode mixMode);
101     void slotChainChannelStatusChanged(const QString& group, bool enabled);
102 
103     void slotEffectLoaded(EffectPointer pEffect, unsigned int slotNumber);
104     // Clears the effect in the given position in the loaded EffectChain.
105     void slotClearEffect(unsigned int iEffectSlotNumber);
106 
107     void slotControlClear(double v);
108     void slotControlChainEnabled(double v);
109     void slotControlChainMix(double v);
110     void slotControlChainSuperParameter(double v, bool force);
111     void slotControlChainMixMode(double v);
112     void slotControlChainSelector(double v);
113     void slotControlChainNextPreset(double v);
114     void slotControlChainPrevPreset(double v);
115     void slotChannelStatusChanged(const QString& group);
116 
117   private:
debugString()118     QString debugString() const {
119         return QString("EffectChainSlot(%1)").arg(m_group);
120     }
121 
122     const unsigned int m_iChainSlotNumber;
123     const QString m_group;
124     EffectRack* m_pEffectRack;
125 
126     EffectChainPointer m_pEffectChain;
127 
128     ControlPushButton* m_pControlClear;
129     ControlObject* m_pControlNumEffects;
130     ControlObject* m_pControlNumEffectSlots;
131     ControlObject* m_pControlChainLoaded;
132     ControlPushButton* m_pControlChainEnabled;
133     ControlObject* m_pControlChainMix;
134     ControlObject* m_pControlChainSuperParameter;
135     ControlPushButton* m_pControlChainMixMode;
136     ControlEncoder* m_pControlChainSelector;
137     ControlPushButton* m_pControlChainNextPreset;
138     ControlPushButton* m_pControlChainPrevPreset;
139 
140     /**
141       These COs do not affect how the effects are processed;
142       they are defined here for skins and controller mappings to communicate
143       with each other. They cannot be defined in skins because they must be present
144       when both skins and mappings are loaded, otherwise the skin will
145       create a new CO with the same ConfigKey but actually be interacting with a different
146       object than the mapping.
147     **/
148     ControlPushButton* m_pControlChainShowFocus;
149     ControlPushButton* m_pControlChainHasControllerFocus;
150     ControlPushButton* m_pControlChainShowParameters;
151     ControlPushButton* m_pControlChainFocusedEffect;
152 
153     struct ChannelInfo {
154         // Takes ownership of pEnabled.
ChannelInfoChannelInfo155         ChannelInfo(const ChannelHandleAndGroup& handle_group, ControlObject* pEnabled)
156                 : handle_group(handle_group),
157                   pEnabled(pEnabled) {
158 
159         }
~ChannelInfoChannelInfo160         ~ChannelInfo() {
161             delete pEnabled;
162         }
163         ChannelHandleAndGroup handle_group;
164         ControlObject* pEnabled;
165     };
166     QMap<QString, ChannelInfo*> m_channelInfoByName;
167 
168     QList<EffectSlotPointer> m_slots;
169 
170     DISALLOW_COPY_AND_ASSIGN(EffectChainSlot);
171 };
172