Fix preset dirtying and lights update on DPat
[SugarCubes.git] / _Presets.pde
1 interface PresetListener {
2 public void onPresetLoaded(Preset preset);
3 public void onPresetDirty(Preset preset);
4 public void onPresetStored(Preset preset);
5 public void onPresetUnloaded();
6 }
7
8 class PresetManager implements LXParameter.Listener {
9
10 public static final int NUM_PRESETS = 8;
11 public static final String FILENAME = "data/presets.txt";
12 public static final String DELIMITER = "\t";
13
14 private final Preset[] presets = new Preset[NUM_PRESETS];
15 private final List<PresetListener> listeners = new ArrayList<PresetListener>();
16
17 private Preset loadedPreset = null;
18 private LXPattern loadedPattern = null;
19
20 PresetManager() {
21 for (int i = 0; i < presets.length; ++i) {
22 presets[i] = new Preset(this, i);
23 }
24 String[] values = loadStrings(FILENAME);
25 if (values == null) {
26 write();
27 } else {
28 int i = 0;
29 for (String serialized : values) {
30 presets[i++].load(serialized);
31 if (i >= NUM_PRESETS) {
32 break;
33 }
34 }
35 }
36 for (Engine.Deck deck : lx.engine.getDecks()) {
37 deck.addListener(new Engine.AbstractListener() {
38 public void patternDidChange(Engine.Deck deck, LXPattern pattern) {
39 if (midiEngine.getFocusedDeck() == deck) {
40 if (pattern != loadedPattern) {
41 onPresetDirty();
42 }
43 }
44 }
45 });
46 }
47 }
48
49 public void setMidiEngine(MidiEngine midiEngine) {
50 midiEngine.addListener(new MidiEngineListener() {
51 public void onFocusedDeck(int deckIndex) {
52 loadedPreset = null;
53 for (PresetListener listener : listeners) {
54 listener.onPresetUnloaded();
55 }
56 }
57 });
58 }
59
60 public void addListener(PresetListener listener) {
61 listeners.add(listener);
62 }
63
64 public void select(int index) {
65 presets[index].select();
66 }
67
68 public void store(int index) {
69 presets[index].store(midiEngine.getFocusedPattern());
70 for (PresetListener listener : listeners) {
71 listener.onPresetStored(presets[index]);
72 }
73 select(index);
74 }
75
76 public void onPresetLoaded(Preset preset, LXPattern pattern) {
77 if (loadedPattern != pattern) {
78 if (loadedPattern != null) {
79 for (LXParameter p : loadedPattern.getParameters()) {
80 ((LXListenableParameter) p).removeListener(this);
81 }
82 }
83 }
84 for (PresetListener listener : listeners) {
85 listener.onPresetLoaded(preset);
86 }
87 loadedPreset = preset;
88 loadedPattern = pattern;
89 for (LXParameter p : loadedPattern.getParameters()) {
90 ((LXListenableParameter) p).addListener(this);
91 }
92 }
93
94 private void onPresetDirty() {
95 if (loadedPreset != null) {
96 for (PresetListener listener : listeners) {
97 listener.onPresetDirty(loadedPreset);
98 }
99 }
100 }
101
102 public void onParameterChanged(LXParameter p) {
103 onPresetDirty();
104 }
105
106 public void write() {
107 String[] lines = new String[NUM_PRESETS];
108 int i = 0;
109 for (Preset preset : presets) {
110 lines[i++] = preset.serialize();
111 }
112 saveStrings(FILENAME, lines);
113 }
114 }
115
116 class Preset {
117
118 final PresetManager manager;
119 final int index;
120
121 String className;
122 final Map<String, Float> parameters = new HashMap<String, Float>();
123
124 Preset(PresetManager manager, int index) {
125 this.manager = manager;
126 this.index = index;
127 }
128
129 public void load(String serialized) {
130 className = null;
131 parameters.clear();
132 try {
133 String[] parts = serialized.split(PresetManager.DELIMITER);
134 className = parts[0];
135 int i = 1;
136 while (i < parts.length - 1) {
137 parameters.put(parts[i], Float.parseFloat(parts[i+1]));
138 i += 2;
139 }
140 } catch (Exception x) {
141 className = null;
142 parameters.clear();
143 }
144 }
145
146 public String serialize() {
147 if (className == null) {
148 return "null";
149 }
150 String val = className + PresetManager.DELIMITER;
151 for (String pKey : parameters.keySet()) {
152 val += pKey + PresetManager.DELIMITER + parameters.get(pKey) + PresetManager.DELIMITER;
153 }
154 return val;
155 }
156
157 public void store(LXPattern pattern) {
158 className = null;
159 parameters.clear();
160 className = pattern.getClass().getName();
161 for (LXParameter p : pattern.getParameters()) {
162 parameters.put(p.getLabel(), p.getValuef());
163 }
164 manager.write();
165 }
166
167 public void select() {
168 Engine.Deck deck = midiEngine.getFocusedDeck();
169 for (LXPattern pattern : deck.getPatterns()) {
170 if (pattern.getClass().getName().equals(className)) {
171 for (String pLabel : parameters.keySet()) {
172 for (LXParameter p : pattern.getParameters()) {
173 if (p.getLabel().equals(pLabel)) {
174 p.setValue(parameters.get(pLabel));
175 }
176 }
177 }
178 deck.goPattern(pattern);
179 manager.onPresetLoaded(this, pattern);
180 break;
181 }
182 }
183 }
184 }
185