8710369a6431b4af4fd78de3970fda9ead1d3585
[ardour.git] / libs / ardour / ardour / configuration_variable.h
1 #ifndef __ardour_configuration_variable_h__
2 #define __ardour_configuration_variable_h__
3
4 #include <sstream>
5 #include <ostream>
6
7 #include <pbd/xml++.h>
8
9 namespace ARDOUR {
10
11 class ConfigVariableBase {
12   public:
13         enum Owner {
14                 Default = 0x1,
15                 System = 0x2,
16                 Config = 0x4,
17                 Session = 0x8,
18                 Interface = 0x10
19         };
20
21         ConfigVariableBase (std::string str) : _name (str), _owner (Default) {}
22         virtual ~ConfigVariableBase() {}
23
24         std::string name() const { return _name; }
25         Owner owner() const { return _owner; }
26
27         virtual void add_to_node (XMLNode& node) = 0;
28         virtual bool set_from_node (const XMLNode& node, Owner owner) = 0;
29
30
31   protected:
32         std::string _name;
33         Owner _owner;
34
35         void notify ();
36         void miss ();
37 };
38
39 template<class T>
40 class ConfigVariable : public ConfigVariableBase
41 {
42   public:
43         ConfigVariable (std::string str) : ConfigVariableBase (str) {}
44         ConfigVariable (std::string str, T val) : ConfigVariableBase (str), value (val) {}
45
46         virtual bool set (T val, Owner owner) {
47                 if (val == value) {
48                         miss ();
49                         return false;
50                 }
51                 value = val;
52                 _owner = (ConfigVariableBase::Owner)(_owner |owner);
53                 notify ();
54                 return true;
55         }
56
57         T get() const {
58                 return value;
59         }
60
61         void add_to_node (XMLNode& node) {
62                 std::stringstream ss;
63                 ss << value;
64                 cerr << "Config variable " << _name << " stored as " << ss.str() << endl;
65                 XMLNode* child = new XMLNode ("Option");
66                 child->add_property ("name", _name);
67                 child->add_property ("value", ss.str());
68                 node.add_child_nocopy (*child);
69         }
70
71         bool set_from_node (const XMLNode& node, Owner owner) {
72
73                 if (node.name() == "Config") {
74
75                         /* ardour.rc */
76
77                         const XMLProperty* prop;
78                         XMLNodeList nlist;
79                         XMLNodeConstIterator niter;
80                         XMLNode* child;
81                         
82                         nlist = node.children();
83                         
84                         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
85                                 
86                                 child = *niter;
87                                 
88                                 if (child->name() == "Option") {
89                                         if ((prop = child->property ("name")) != 0) {
90                                                 if (prop->value() == _name) {
91                                                         if ((prop = child->property ("value")) != 0) {
92                                                                 std::stringstream ss;
93                                                                 ss << prop->value();
94                                                                 ss >> value;
95                                                                 _owner = (ConfigVariableBase::Owner)(_owner |owner);
96                                                                 return true;
97                                                         }
98                                                 }
99                                         }
100                                 }
101                         }
102                         
103                 } else if (node.name() == "Options") {
104
105                         /* session file */
106
107                         XMLNodeList olist;
108                         XMLNodeConstIterator oiter;
109                         XMLNode* option;
110                         const XMLProperty* opt_prop;
111                         
112                         olist = node.children();
113                         
114                         for (oiter = olist.begin(); oiter != olist.end(); ++oiter) {
115                                 
116                                 option = *oiter;
117                                 
118                                 if (option->name() == _name) {
119                                         if ((opt_prop = option->property ("val")) != 0) {
120                                                 std::stringstream ss;
121                                                 ss << opt_prop->value();
122                                                 ss >> value;
123                                                 _owner = (ConfigVariableBase::Owner)(_owner |owner);
124                                                 return true;
125                                         }
126                                 }
127                         }
128                 }
129
130                 return false;
131         }
132
133   protected:
134         virtual T get_for_save() { return value; }
135         T value;
136 };
137
138 template<class T>
139 class ConfigVariableWithMutation : public ConfigVariable<T>
140 {
141   public:
142         ConfigVariableWithMutation (std::string name, T val, T (*m)(T)) 
143                 : ConfigVariable<T> (name, val), mutator (m) {}
144
145         bool set (T val, ConfigVariableBase::Owner owner) {
146                 if (unmutated_value != val) {
147                         unmutated_value = val;
148                         return ConfigVariable<T>::set (mutator (val), owner);
149                 } 
150                 return false;
151         }
152
153   protected:
154         virtual T get_for_save() { return unmutated_value; }
155         T unmutated_value;
156         T (*mutator)(T);
157 };
158
159 }
160
161 #endif /* __ardour_configuration_variable_h__ */