summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd/properties.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/pbd/pbd/properties.h')
-rw-r--r--libs/pbd/pbd/properties.h199
1 files changed, 58 insertions, 141 deletions
diff --git a/libs/pbd/pbd/properties.h b/libs/pbd/pbd/properties.h
index 1c3519766f..274dfffd9c 100644
--- a/libs/pbd/pbd/properties.h
+++ b/libs/pbd/pbd/properties.h
@@ -27,96 +27,19 @@
#include <glib.h>
#include "pbd/xml++.h"
+#include "pbd/property_basics.h"
+#include "pbd/property_list.h"
namespace PBD {
-typedef GQuark PropertyID;
-
-template<typename T>
-struct PropertyDescriptor {
- PropertyID id;
- typedef T value_type;
-};
-
-class PropertyChange : public std::set<PropertyID>
-{
-public:
- PropertyChange() {}
-
- template<typename T>
- PropertyChange(PropertyDescriptor<T> p) { insert (p.id); }
-
- PropertyChange(const PropertyChange& other) : std::set<PropertyID> (other) {}
-
- PropertyChange operator=(const PropertyChange& other) {
- clear ();
- insert (other.begin (), other.end ());
- return *this;
- }
-
- template<typename T>
- PropertyChange operator=(PropertyDescriptor<T> p) {
- clear ();
- insert (p.id);
- return *this;
- }
-
- template<typename T>
- bool contains (PropertyDescriptor<T> p) const { return find (p.id) != end (); }
-
- bool contains (const PropertyChange& other) const {
- for (const_iterator x = other.begin (); x != other.end (); ++x) {
- if (find (*x) != end ()) {
- return true;
- }
- }
- return false;
- }
-
- void add (PropertyID id) { (void) insert (id); }
- void add (const PropertyChange& other) { (void) insert (other.begin (), other.end ()); }
- template<typename T>
- void add (PropertyDescriptor<T> p) { (void)insert (p.id); }
-};
-
-/** Base (non template) part of Property */
-class PropertyBase
-{
-public:
- PropertyBase (PropertyID pid)
- : _property_id (pid)
- , _have_old (false)
- {}
-
- /** Forget about any old value for this state */
- void clear_history () {
- _have_old = false;
- }
-
- virtual void diff (XMLNode*, XMLNode*) const = 0;
- virtual void diff (PropertyChange&) const = 0;
- virtual bool set_state (XMLNode const&) = 0;
- virtual void add_state (XMLNode&) const = 0;
-
- const gchar*property_name () const { return g_quark_to_string (_property_id); }
- PropertyID id () const { return _property_id; }
-
- bool operator==(PropertyID pid) const {
- return _property_id == pid;
- }
-
-protected:
- PropertyID _property_id;
- bool _have_old;
-};
-
-/** Parent class for classes which represent a single property in a Stateful object */
+/** Parent class for classes which represent a single scalar property in a Stateful object
+ */
template<class T>
class PropertyTemplate : public PropertyBase
{
public:
PropertyTemplate (PropertyDescriptor<T> p, T const& v)
- : PropertyBase (p.id)
+ : PropertyBase (p.property_id)
, _current (v)
{}
@@ -156,25 +79,22 @@ public:
return _current;
}
- void diff (XMLNode* old, XMLNode* current) const {
- if (_have_old) {
- old->add_property (property_name (), to_string (_old));
- current->add_property (property_name (), to_string (_current));
- }
- }
-
- void diff (PropertyChange& c) const {
- if (_have_old) {
- c.add (_property_id);
- }
+ /** If this property has been changed since the last clear_history() call
+ (or its construction), add an (XML) property describing the old value
+ to the XMLNode @param old and another describing the current value to
+ the XMLNode @param current.
+ */
+ void add_history_state (XMLNode* history_node) const {
+ history_node->add_property (property_name(), to_string (_current));
}
/** Try to set state from the property of an XML node.
* @param node XML node.
* @return true if the value of the property is changed
*/
- bool set_state (XMLNode const& node) {
- XMLProperty const* p = node.property (property_name ());
+ bool set_state_from_owner_state (XMLNode const& owner_state) {
+
+ XMLProperty const* p = owner_state.property (property_name());
if (p) {
T const v = from_string (p->value ());
@@ -188,11 +108,19 @@ public:
return false;
}
- void add_state (XMLNode& node) const {
- node.add_property (property_name (), to_string (_current));
+ void add_state_to_owner_state (XMLNode& owner_state) const {
+ owner_state.add_property (property_name(), to_string (_current));
}
protected:
+ /** Constructs a PropertyTemplate with a default
+ value for _old and _current.
+ */
+
+ PropertyTemplate (PropertyDescriptor<T> p)
+ : PropertyBase (p.property_id)
+ {}
+
void set (T const& v) {
_old = _current;
_have_old = true;
@@ -212,7 +140,7 @@ 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
+/** Representation of a single piece of scalar state in a Stateful; for use
* with types that can be written to / read from stringstreams.
*/
template<class T>
@@ -222,6 +150,21 @@ public:
Property (PropertyDescriptor<T> q, T const& v)
: PropertyTemplate<T> (q, v)
{}
+
+ void diff (PropertyList& before, PropertyList& after) const {
+ if (this->_have_old) {
+ before.add (new Property<T> (this->property_id(), this->_old));
+ after.add (new Property<T> (this->property_id(), this->_current));
+ }
+ }
+
+ Property<T>* maybe_clone_self_if_found_in_history_node (const XMLNode& node) const {
+ const XMLProperty* prop = node.property (this->property_name());
+ if (!prop) {
+ return 0;
+ }
+ return new Property<T> (this->property_id(), from_string (prop->value()));
+ }
T & operator=(T const& v) {
this->set (v);
@@ -229,6 +172,12 @@ public:
}
private:
+ friend class PropertyFactory;
+
+ Property (PropertyDescriptor<T> q)
+ : PropertyTemplate<T> (q)
+ {}
+
/* Note that we do not set a locale for the streams used
* in to_string() or from_string(), because we want the
* format to be portable across locales (i.e. C or
@@ -254,7 +203,7 @@ private:
/** Specialization, for std::string which is common and special (see to_string() and from_string()
* Using stringstream to read from a std::string is easy to get wrong because of whitespace
- * delineation, etc.
+ * separators, etc.
*/
template<>
class Property<std::string> : public PropertyTemplate<std::string>
@@ -264,6 +213,13 @@ public:
: PropertyTemplate<std::string> (q, v)
{}
+ void diff (PropertyList& before, PropertyList& after) const {
+ if (this->_have_old) {
+ before.add (new Property<std::string> (PropertyDescriptor<std::string> (this->property_id()), this->_old));
+ after.add (new Property<std::string> (PropertyDescriptor<std::string> (this->property_id()), this->_current));
+ }
+ }
+
std::string & operator=(std::string const& v) {
this->set (v);
return this->_current;
@@ -280,48 +236,9 @@ private:
};
-class PropertyList : public std::map<PropertyID, PropertyBase*>
-{
-public:
- PropertyList() : _property_owner (true) {}
- virtual ~PropertyList() {
- if (_property_owner) {
- for (std::map<PropertyID, PropertyBase*>::iterator i = begin (); i != end (); ++i) {
- delete i->second;
- }
- }
- }
-
- /* Classes that own property lists use this to add their
- * property members to their plists.
- */
- bool add (PropertyBase& p) {
- return insert (value_type (p.id (), &p)).second;
- }
-
- /* Code that is constructing a property list for use
- * in setting the state of an object uses this.
- */
- template<typename T, typename V>
- bool add (PropertyDescriptor<T> pid, const V& v) {
- return insert (value_type (pid.id, new Property<T> (pid, (T)v))).second;
- }
-
-protected:
- bool _property_owner;
-};
-
-/** A variant of PropertyList that does not delete its
- * property list in its destructor. Objects with their
- * own Properties store them in an OwnedPropertyList
- * to avoid having them deleted at the wrong time.
- */
-class OwnedPropertyList : public PropertyList
-{
-public:
- OwnedPropertyList() { _property_owner = false; }
-};
-
} /* namespace PBD */
+#include "pbd/property_list_impl.h"
+#include "pbd/property_basics_impl.h"
+
#endif /* __pbd_properties_h__ */