1 /**
2 * Copyright © Underground Rekordz 2019
3 * License: MIT (https://github.com/UndergroundRekordz/Musicpulator/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module musicpulator.songautomation;
7 
8 import std.string : format;
9 import std.algorithm : map;
10 import std.traits : isNumeric;
11 import std.array : join, array;
12 
13 import musicpulator.core;
14 
15 /// Wrapper around a song automation.
16 final class SongAutomation(T)
17 if (isNumeric!T)
18 {
19   private:
20   /// The name of the automation.
21   string _name;
22   /// The values of the automation.
23   InternalMaxSizeCollection!(T, 32) _values;
24 
25   public:
26   /**
27   * Creates a new song automation.
28   * Params:
29   *   name =      The name of the automation.
30   *   initValue = The initial value of the automation.
31   */
32   this(string name, T initValue = T.init)
33   {
34     _name = name;
35 
36     _values.add(initValue);
37   }
38 
39   @property
40   {
41     /// Gets the name.
42     string name() { return _name; }
43 
44     /// Sets the name of the automation.
45     void name(string newName)
46     {
47       _name = newName;
48     }
49 
50     /// Gets the values of the automation.
51     InternalMaxSizeCollection!(T, 32) values() { return _values; }
52 
53     /// Gets the base value of the automation.
54     T value() { return _values[0]; }
55 
56     /// Sets the base value of the automation.
57     void value(T newValue)
58     {
59       _values[0] = newValue;
60     }
61   }
62 
63   /**
64   * Adds a value to the automation.
65   * Params:
66   *   value = The value to add.
67   */
68   void addValue(T value)
69   {
70     _values.add(value);
71   }
72 
73   /**
74   * Modifies an automation point.
75   * Params:
76   *   value =           The new value of the automation point.
77   *   automationPoint = The point to modify.
78   */
79   void modifyValue(T value, size_t automationPoint)
80   {
81     if (automationPoint < _values.length)
82     {
83       _values[automationPoint] = value;
84     }
85   }
86 
87   /// Converts the automation to a string. This will call toJson().
88   override string toString()
89   {
90     return toJson();
91   }
92 
93   /// Converts the automation to json.
94   string toJson()
95   {
96     return `{"name":"%s","value":%s,"values":%s}`
97       .format(_name ? _name : "null", value, values);
98   }
99 
100   /// Converts the automation to xml.
101   string toXml()
102   {
103     return `<SongAutomation name="%s" value="%s">%s</SongAutomation>`.
104       format(_name, value, values.map!(v => "<SongAutomationValue>%s</SongAutomationValue>".format(v)).array.join);
105   }
106 }