2 Copyright (C) 2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef __pbd_properties_h__
21 #define __pbd_properties_h__
25 #include <glib/glib.h>
35 PropertyChange new_change ();
37 /** Base (non template) part of Property */
41 PropertyBase (GQuark quark, PropertyChange c)
49 /** Forget about any old value for this state */
50 void clear_history () {
54 virtual void diff (XMLNode *, XMLNode *) const = 0;
55 virtual PropertyChange set_state (XMLNode const &) = 0;
56 virtual void add_state (XMLNode &) const = 0;
58 std::string property_name() const { return g_quark_to_string (_property_quark); }
59 PropertyChange change() const { return _change; }
61 bool operator== (GQuark q) const {
62 return _property_quark == q;
67 GQuark _property_quark;
68 PropertyChange _change;
71 /** Parent class for classes which represent a single property in a Stateful object */
73 class PropertyTemplate : public PropertyBase
76 PropertyTemplate (GQuark q, PropertyChange c, T const & v)
83 PropertyTemplate<T> & operator= (PropertyTemplate<T> const & s) {
84 /* XXX: isn't there a nicer place to do this? */
85 _have_old = s._have_old;
86 _property_quark = s._property_quark;
89 _current = s._current;
94 T & operator= (T const & v) {
99 T & operator+= (T const & v) {
104 bool operator== (const T& other) const {
105 return _current == other;
108 bool operator!= (const T& other) const {
109 return _current != other;
112 operator T const & () const {
116 T const & val () const {
120 void diff (XMLNode* old, XMLNode* current) const {
122 old->add_property (g_quark_to_string (_property_quark), to_string (_old));
123 current->add_property (g_quark_to_string (_property_quark), to_string (_current));
127 /** Try to set state from the property of an XML node.
128 * @param node XML node.
129 * @return PropertyChange effected, or 0.
131 PropertyChange set_state (XMLNode const & node) {
132 XMLProperty const * p = node.property (g_quark_to_string (_property_quark));
135 T const v = from_string (p->value ());
138 return PropertyChange (0);
145 return PropertyChange (0);
148 void add_state (XMLNode & node) const {
149 node.add_property (g_quark_to_string (_property_quark), to_string (_current));
153 void set (T const & v) {
159 virtual std::string to_string (T const & v) const = 0;
160 virtual T from_string (std::string const & s) const = 0;
167 std::ostream& operator<< (std::ostream& os, PropertyTemplate<T> const & s)
169 return os << s.val();
172 /** Representation of a single piece of state in a Stateful; for use
173 * with types that can be written to / read from stringstreams.
176 class Property : public PropertyTemplate<T>
179 Property (GQuark q, PropertyChange c, T const & v)
180 : PropertyTemplate<T> (q, c, v)
185 T & operator= (T const & v) {
187 return this->_current;
191 std::string to_string (T const & v) const {
194 s.precision (12); // in case its floating point
199 T from_string (std::string const & s) const {
201 std::stringstream t (s);
203 t.precision (12); // in case its floating point
209 } /* namespace PBD */
211 #endif /* __pbd_properties_h__ */