summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd/properties.h
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-02-13 17:51:40 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-02-13 17:51:40 +0000
commitab7f800fb4021948a8ad925e7dadf4f82252ac65 (patch)
tree2d26f1c8010c43362a31fc49c09bc6edeba604a0 /libs/pbd/pbd/properties.h
parentfccd7d5103b897959b5f816aebd9613aee111433 (diff)
split out State... objects and rename as Property...
git-svn-id: svn://localhost/ardour2/branches/3.0@6682 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/pbd/properties.h')
-rw-r--r--libs/pbd/pbd/properties.h211
1 files changed, 211 insertions, 0 deletions
diff --git a/libs/pbd/pbd/properties.h b/libs/pbd/pbd/properties.h
new file mode 100644
index 0000000000..5bab97229c
--- /dev/null
+++ b/libs/pbd/pbd/properties.h
@@ -0,0 +1,211 @@
+/*
+ Copyright (C) 2010 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __pbd_properties_h__
+#define __pbd_properties_h__
+
+#include <string>
+#include <list>
+#include <glib/glib.h>
+
+class XMLNode;
+
+namespace PBD {
+
+enum PropertyChange {
+ range_guarantee = ~0
+};
+
+PropertyChange new_change ();
+
+/** Base (non template) part of Property */
+class PropertyBase
+{
+public:
+ PropertyBase (GQuark quark, PropertyChange c)
+ : _have_old (false)
+ , _property_quark (q)
+ , _change (c)
+ {
+
+ }
+
+ /** Forget about any old value for this state */
+ void clear_history () {
+ _have_old = false;
+ }
+
+ virtual void diff (XMLNode *, XMLNode *) const = 0;
+ virtual PropertyChange set_state (XMLNode const &) = 0;
+ virtual void add_state (XMLNode &) const = 0;
+
+ std::string property_name() const { return g_quark_to_string (_property_quark); }
+ PropertyChange change() const { return _change; }
+
+ bool operator== (GQuark q) const {
+ return _property_quark == q;
+ }
+
+protected:
+ bool _have_old;
+ GQuark _property_quark;
+ PropertyChange _change;
+};
+
+/** Parent class for classes which represent a single property in a Stateful object */
+template <class T>
+class PropertyTemplate : public PropertyBase
+{
+public:
+ PropertyTemplate (GQuark q, PropertyChange c, T const & v)
+ : PropertyBase (q, c)
+ , _current (v)
+ {
+
+ }
+
+ PropertyTemplate<T> & operator= (PropertyTemplate<T> const & s) {
+ /* XXX: isn't there a nicer place to do this? */
+ _have_old = s._have_old;
+ _property_quark = s._property_quark;
+ _change = s._change;
+
+ _current = s._current;
+ _old = s._old;
+ return *this;
+ }
+
+ T & operator= (T const & v) {
+ set (v);
+ return _current;
+ }
+
+ T & operator+= (T const & v) {
+ set (_current + v);
+ return _current;
+ }
+
+ bool operator== (const T& other) const {
+ return _current == other;
+ }
+
+ bool operator!= (const T& other) const {
+ return _current != other;
+ }
+
+ operator T const & () const {
+ return _current;
+ }
+
+ T const & val () const {
+ return _current;
+ }
+
+ void diff (XMLNode* old, XMLNode* current) const {
+ if (_have_old) {
+ old->add_property (g_quark_to_string (_property_quark), to_string (_old));
+ current->add_property (g_quark_to_string (_property_quark), to_string (_current));
+ }
+ }
+
+ /** Try to set state from the property of an XML node.
+ * @param node XML node.
+ * @return PropertyChange effected, or 0.
+ */
+ PropertyChange set_state (XMLNode const & node) {
+ XMLProperty const * p = node.property (g_quark_to_string (_property_quark));
+
+ if (p) {
+ T const v = from_string (p->value ());
+
+ if (v == _current) {
+ return PropertyChange (0);
+ }
+
+ set (v);
+ return _change;
+ }
+
+ return PropertyChange (0);
+ }
+
+ void add_state (XMLNode & node) const {
+ node.add_property (g_quark_to_string (_property_quark), to_string (_current));
+ }
+
+protected:
+ void set (T const & v) {
+ _old = _current;
+ _have_old = true;
+ _current = v;
+ }
+
+ virtual std::string to_string (T const & v) const = 0;
+ virtual T from_string (std::string const & s) const = 0;
+
+ T _current;
+ T _old;
+};
+
+template<class T>
+std::ostream& operator<< (std::ostream& os, PropertyTemplate<T> const & s)
+{
+ return os << s.val();
+}
+
+/** Representation of a single piece of state in a Stateful; for use
+ * with types that can be written to / read from stringstreams.
+ */
+template <class T>
+class Property : public PropertyTemplate<T>
+{
+public:
+ Property (GQuark q, PropertyChange c, T const & v)
+ : PropertyTemplate<T> (q, c, v)
+ {
+
+ }
+
+ T & operator= (T const & v) {
+ this->set (v);
+ return this->_current;
+ }
+
+private:
+ std::string to_string (T const & v) const {
+ // XXX LocaleGuard
+ std::stringstream s;
+ s.precision (12); // in case its floating point
+ s << v;
+ return s.str ();
+ }
+
+ T from_string (std::string const & s) const {
+ // XXX LocaleGuard
+ std::stringstream t (s);
+ T v;
+ t.precision (12); // in case its floating point
+ t >> v;
+ return v;
+ }
+};
+
+} /* namespace PBD */
+
+#endif /* __pbd_properties_h__ */