2 Copyright (C) 2000-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_stateful_h__
21 #define __pbd_stateful_h__
26 #include "pbd/xml++.h"
42 /** Base (non template) part of State */
46 StateBase (std::string const & p, Change c)
48 , _xml_property_name (p)
54 StateBase (StateBase const & s)
55 : _have_old (s._have_old)
56 , _xml_property_name (s._xml_property_name)
62 /** Forget about any old value for this state */
63 void clear_history () {
67 virtual void diff (XMLNode *, XMLNode *) const = 0;
68 virtual Change set_state (XMLNode const &) = 0;
69 virtual void add_state (XMLNode &) const = 0;
73 std::string _xml_property_name;
77 /** Class to represent a single piece of state in a Stateful object */
79 class State : public StateBase
82 State (std::string const & p, Change c, T const & v)
89 State (State<T> const & s)
92 _current = s._current;
96 State<T> & operator= (State<T> const & s) {
97 /* XXX: isn't there a nicer place to do this? */
98 _have_old = s._have_old;
99 _xml_property_name = s._xml_property_name;
102 _current = s._current;
107 T & operator= (T const & v) {
112 T & operator+= (T const & v) {
117 operator T () const {
121 T const & get () const {
125 void diff (XMLNode* old, XMLNode* current) const {
127 old->add_property (_xml_property_name.c_str(), to_string (_old));
128 current->add_property (_xml_property_name.c_str(), to_string (_current));
132 /** Try to set state from the property of an XML node.
133 * @param node XML node.
134 * @return Change effected, or 0.
136 Change set_state (XMLNode const & node) {
137 XMLProperty const * p = node.property (_xml_property_name.c_str());
140 std::stringstream s (p->value ());
155 void add_state (XMLNode & node) const {
156 node.add_property (_xml_property_name.c_str(), to_string (_current));
160 void set (T const & v) {
166 std::string to_string (T const & v) const {
176 /** Base class for objects with saveable and undoable state */
182 virtual XMLNode& get_state (void) = 0;
184 virtual int set_state (const XMLNode&, int version) = 0;
186 void add_state (StateBase & s) {
187 _states.push_back (&s);
190 /* Extra XML nodes */
192 void add_extra_xml (XMLNode&);
193 XMLNode *extra_xml (const std::string& str);
195 const PBD::ID& id() const { return _id; }
197 void clear_history ();
198 std::pair<XMLNode *, XMLNode*> diff ();
200 static int current_state_version;
201 static int loading_state_version;
205 void add_instant_xml (XMLNode&, const sys::path& directory_path);
206 XMLNode *instant_xml (const std::string& str, const sys::path& directory_path);
207 Change set_state_using_states (XMLNode const &);
208 void add_states (XMLNode &);
211 XMLNode *_instant_xml;
214 std::string _xml_node_name; ///< name of node to use for this object in XML
215 std::list<StateBase*> _states; ///< state variables that this object has
220 #endif /* __pbd_stateful_h__ */