Allolib  1.0
C++ Components For Interactive Multimedia
al_PresetHandler.hpp
1 #ifndef AL_PRESETHANDLER_H
2 #define AL_PRESETHANDLER_H
3 
4 /* Allolib --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology,
8  UCSB. Copyright (C) 2012-2018. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright
15  notice, this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above
18  copyright notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from this
23  software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
26  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
29  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 
37  File description:
38  Preset classes that encapsulates storing values for groups of parameters
39  File author(s):
40  AndrĂ©s Cabrera mantaraya36@gmail.com
41 */
42 
43 #include <algorithm>
44 #include <atomic>
45 #include <condition_variable>
46 #include <functional>
47 #include <map>
48 #include <mutex>
49 #include <string>
50 #include <thread>
51 #include <vector>
52 
53 #include "al/protocol/al_OSC.hpp"
54 #include "al/system/al_Time.hpp"
55 #include "al/ui/al_Parameter.hpp"
56 #include "al/ui/al_ParameterServer.hpp"
57 
58 namespace al {
59 
67 public:
68  typedef std::map<std::string, std::vector<ParameterField>> ParameterStates;
77  PresetHandler(std::string rootDirectory, bool verbose = false);
78 
88  PresetHandler(TimeMasterMode timeMasterMode = TimeMasterMode::TIME_MASTER_CPU,
89  std::string rootDirectory = "presets", bool verbose = false);
90 
91  ~PresetHandler();
92 
102  void storePreset(std::string name);
103 
119  void storePreset(int index, std::string name = "", bool overwrite = true);
128  void recallPreset(std::string name);
129 
141  std::string recallPreset(int index);
142 
143  void recallPresetSynchronous(std::string name);
144 
149  std::string recallPresetSynchronous(int index);
150 
162  void setInterpolatedPreset(int index1, int index2, double factor);
163 
164  void setInterpolatedPreset(std::string presetName1, std::string presetName2,
165  double factor);
166 
167  // static void setParameterValues(ParameterMeta *param,
168  // std::vector<ParameterField> &values);
173  void setInterpolatedValues(ParameterStates &startValues,
174  ParameterStates &endValues, double factor = 1.0);
175 
176  std::map<int, std::string> availablePresets();
177  std::string getPresetName(int index);
178  std::string getCurrentPresetName() { return mCurrentPresetName; }
179 
189  void skipParameter(std::string parameterAddr, bool skip = true);
190 
191  int getCurrentPresetIndex();
192 
193  float getMorphTime();
194  void setMorphTime(float time);
195  void setMaxMorphTime(float time);
196  void stopMorphing() { mTotalSteps.store(0); }
197  void morphTo(ParameterStates &parameterStates, float morphTime);
198  void morphTo(std::string presetName, float morphTime);
199 
200  void setMorphStepTime(float stepTime) { mMorphInterval = stepTime; }
201 
202  void stepMorphing(double stepTime);
203 
206  void stepMorphing();
207 
208  void setSubDirectory(std::string directory);
209  std::string getSubDirectory() { return mSubDir; }
210 
212  std::string getCurrentPath();
213 
214  void setRootPath(std::string path);
215 
217  std::string getRootPath();
218 
222  void print();
223 
230  std::function<void(int index, void *sender, void *userData)> cb,
231  void *userData = nullptr);
232 
239  std::function<void(int index, std::string name, void *userData)> cb,
240  void *userData = nullptr);
241 
247  void registerMorphTimeCallback(Parameter::ParameterChangeCallback cb);
248 
249  typedef const std::function<void(std::string)> PresetMapCallback;
254  void registerPresetMapCallback(PresetMapCallback cb);
255 
256  PresetHandler &registerParameter(ParameterMeta &parameter);
257 
258  PresetHandler &operator<<(ParameterMeta &param) {
259  return this->registerParameter(param);
260  }
261 
262  PresetHandler &registerParameterBundle(ParameterBundle &bundle);
263 
264  PresetHandler &operator<<(ParameterBundle &bundle) {
265  return this->registerParameterBundle(bundle);
266  }
267 
268  std::vector<ParameterMeta *> parameters() { return mParameters; }
269 
270  std::string buildMapPath(std::string mapName, bool useSubDirectory = false);
271 
272  std::vector<std::string> availablePresetMaps();
273 
274  std::map<int, std::string> readPresetMap(std::string mapName = "default");
275 
276  void setCurrentPresetMap(std::string mapName = "default",
277  bool autoCreate = false);
278 
279  void setPresetMap(std::map<int, std::string> presetsMap) {
280  mPresetsMap = presetsMap;
281  }
282 
283  void storeCurrentPresetMap(std::string mapName = "",
284  bool useSubDirectory = false);
285 
293  void useCallbacks(bool use) { mUseCallbacks = use; }
294 
295  void changeParameterValue(std::string presetName, std::string parameterPath,
296  float newValue);
297 
308  static int asciiToPresetIndex(int ascii, int offset = 0);
309 
310  [[deprecated]] void verbose(bool isVerbose) { mVerbose = isVerbose; }
311  void setVerbose(bool isVerbose = true) { mVerbose = isVerbose; }
312  bool verbose() { return mVerbose; }
313 
320  ParameterStates loadPresetValues(std::string name);
321 
329  bool savePresetValues(const ParameterStates &values, std::string presetName,
330  bool overwrite = true);
331 
332  void setTimeMaster(TimeMasterMode masterMode);
333 
334  void startCpuThread();
335  void stopCpuThread();
336 
337 private:
338  // std::vector<float> getParameterValue(ParameterMeta *p);
339  // void setParametersInBundle(ParameterBundle *bundle, std::string
340  // bundlePrefix,
341  // PresetHandler *handler, double factor = 1.0);
342  static void morphingFunction(PresetHandler *handler);
343 
344  ParameterStates getBundleStates(ParameterBundle *bundle, std::string id);
345 
346  bool mVerbose{false};
347  bool mUseCallbacks{true};
348  std::string mRootDir;
349  std::string mSubDir; // Optional sub directory, e.g. for preset map archives
350 
351  std::string mCurrentMapName;
352  std::string mCurrentPresetName;
353  std::vector<ParameterMeta *> mParameters;
354 
355  std::vector<std::string> mSkipParameters;
356  std::mutex mSkipParametersLock;
357 
358  std::map<std::string, std::vector<ParameterBundle *>> mBundles;
359 
360  // Protects file writing from this class. Only one file may be written at
361  // a time.
362  std::mutex mFileLock;
363 
364  std::mutex mTargetLock;
365  ParameterStates mTargetValues;
366  ParameterStates mStartValues;
367 
368  TimeMasterMode mTimeMasterMode{TimeMasterMode::TIME_MASTER_CPU};
369 
370  Parameter mMorphTime{"morphTime", "", 0.0, 0.0, 20.0};
371 
372  std::atomic<uint64_t> mMorphStepCount{0};
373  std::atomic<uint64_t> mTotalSteps{0};
374  // std::atomic<float> mCurrentMorphIndex;
375  bool mCpuThreadRunning{false}; // To keep the morphing thread alive
376  std::unique_ptr<std::thread> mMorphingThread;
377  // std::condition_variable mMorphConditionVar;
378  double mMorphInterval{0.02};
379  // std::atomic<bool> mMorphing;
380 
381  std::vector<std::function<void(int index, void *sender, void *userData)>>
382  mCallbacks;
383  std::vector<void *> mCallbackUdata;
384  std::vector<std::function<void(int index, std::string name, void *userData)>>
385  mStoreCallbacks;
386  std::vector<void *> mStoreCallbackUdata;
387  std::vector<std::function<void(std::string)>> mPresetsMapCbs;
388 
389  std::map<int, std::string> mPresetsMap;
390 };
391 
392 } // namespace al
393 
394 #endif // AL_PRESETHANDLER_H
The ParameterMeta class defines the base interface for Parameter metadata.
The PresetHandler class handles sorting and recalling of presets.
void skipParameter(std::string parameterAddr, bool skip=true)
Add or remove a parameter address from group that will be skipped when recalling presets.
void registerPresetMapCallback(PresetMapCallback cb)
Register a callback to be notified when preset map cahges.
ParameterStates loadPresetValues(std::string name)
load preset into parameter states data structure without setting values
std::string getRootPath()
Base path without appending sub directory.
void storePreset(int index, std::string name="", bool overwrite=true)
Store preset at index. The name argument specifies the preset name.
std::string recallPreset(int index)
Recall a preset by index number.
void registerPresetCallback(std::function< void(int index, void *sender, void *userData)> cb, void *userData=nullptr)
Register a callback to be notified when a preset is loaded.
std::string getCurrentPath()
Path including subdirectory if any.
std::string recallPresetSynchronous(int index)
recall immediately (not using the morph thread)
void useCallbacks(bool use)
useCallbacks determines whether to call the internal callbacks
PresetHandler(std::string rootDirectory, bool verbose=false)
PresetHandler contructor.
bool savePresetValues(const ParameterStates &values, std::string presetName, bool overwrite=true)
save list of parameter states into text preset file
void setInterpolatedPreset(int index1, int index2, double factor)
Set parameters to values interpolated between two presets.
void storePreset(std::string name)
Stores preset.
void registerStoreCallback(std::function< void(int index, std::string name, void *userData)> cb, void *userData=nullptr)
Register a callback to be notified when a preset is stored.
static int asciiToPresetIndex(int ascii, int offset=0)
Map QWERTY ascii keys to presets 0-49.
void setInterpolatedValues(ParameterStates &startValues, ParameterStates &endValues, double factor=1.0)
Interpolate between start and end values according to factor.
PresetHandler(TimeMasterMode timeMasterMode=TimeMasterMode::TIME_MASTER_CPU, std::string rootDirectory="presets", bool verbose=false)
Constructor with option to set time master mode.
void registerMorphTimeCallback(Parameter::ParameterChangeCallback cb)
Register a callback to be notified when morph time parameter is changed.
void recallPreset(std::string name)
Recall a preset by name.
Definition: al_App.hpp:23