forked from sudip-mondal-2002/Amplitron
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand_chain.h
More file actions
121 lines (105 loc) · 3.61 KB
/
Copy pathcommand_chain.h
File metadata and controls
121 lines (105 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#pragma once
#include "gui/commands/command_base.h"
#include "audio/engine/audio_engine.h"
#include "audio/effects/effect.h"
#include <cstring>
#include <algorithm>
namespace Amplitron {
/**
* @brief Command that appends an effect to the engine's signal chain.
*
* execute() adds the effect; undo() finds and removes it.
*/
class AddEffectCommand : public Command {
public:
/**
* @brief Construct an AddEffectCommand.
* @param engine Reference to the audio engine that owns the effect chain.
* @param effect Shared pointer to the effect to add.
*/
AddEffectCommand(AudioEngine& engine, std::shared_ptr<Effect> effect)
: engine_(engine), effect_(std::move(effect)) {}
/** @brief Append the effect to the engine's chain (before the amp if present). */
bool execute() override {
int amp_idx = -1;
auto& fx = engine_.effects();
for (int i = 0; i < static_cast<int>(fx.size()); ++i) {
if (std::strcmp(fx[i]->name(), "Amp Sim") == 0) {
amp_idx = i;
break;
}
}
if (amp_idx >= 0) {
engine_.insert_effect(amp_idx, effect_);
} else {
engine_.add_effect(effect_);
}
return true;
}
/** @brief Remove the previously added effect from the chain. */
void undo() override {
auto& fx = engine_.effects();
for (int i = static_cast<int>(fx.size()) - 1; i >= 0; --i) {
if (fx[i] == effect_) {
engine_.remove_effect(i);
return;
}
}
}
/** @brief Return "Add Effect". */
const char* description() const override { return "Add Effect"; }
/** @brief Accessor for the wrapped effect. */
std::shared_ptr<Effect> effect() const { return effect_; }
private:
AudioEngine& engine_;
std::shared_ptr<Effect> effect_;
};
/**
* @brief Command that removes an effect from the engine's signal chain.
*
* The constructor captures the effect pointer before removal so undo() can
* re-insert it at its original position.
*/
class RemoveEffectCommand : public Command {
public:
/**
* @brief Construct a RemoveEffectCommand.
* @param engine Reference to the audio engine.
* @param index Chain index of the effect to remove (captured at construction).
*/
RemoveEffectCommand(AudioEngine& engine, int index)
: engine_(engine), index_(index) {
auto& fx = engine_.effects();
if (index >= 0 && index < static_cast<int>(fx.size())) {
effect_ = fx[index];
}
}
/** @brief Remove the effect at the stored index. */
bool execute() override {
engine_.remove_effect(index_);
return true;
}
/** @brief Re-insert the captured effect at its original chain position. */
void undo() override {
if (effect_) {
auto& fx = engine_.effects();
int pos = std::min(index_, static_cast<int>(fx.size()));
engine_.add_effect(effect_);
int last = static_cast<int>(engine_.effects().size()) - 1;
if (last != pos) {
engine_.move_effect(last, pos);
}
}
}
/** @brief Return "Remove Effect". */
const char* description() const override { return "Remove Effect"; }
/** @brief Original chain index of the removed effect. */
int index() const { return index_; }
/** @brief Accessor for the captured effect pointer. */
std::shared_ptr<Effect> effect() const { return effect_; }
private:
AudioEngine& engine_;
int index_;
std::shared_ptr<Effect> effect_;
};
} // namespace Amplitron