Move ARDOUR::Change into PBD so that Stateful can be aware of
what Change a State reflects. Hence allow Stateful to do some of the work of set/get_state in Region. git-svn-id: svn://localhost/ardour2/branches/3.0@6671 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -33,13 +33,20 @@ namespace sys {
|
||||
class path;
|
||||
}
|
||||
|
||||
enum Change {
|
||||
range_guarantee = ~0
|
||||
};
|
||||
|
||||
Change new_change ();
|
||||
|
||||
/** Base (non template) part of State */
|
||||
class StateBase
|
||||
{
|
||||
public:
|
||||
StateBase (std::string const & p)
|
||||
StateBase (std::string const & p, Change c)
|
||||
: _have_old (false)
|
||||
, _xml_property_name (p)
|
||||
, _change (c)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -47,6 +54,7 @@ public:
|
||||
StateBase (StateBase const & s)
|
||||
: _have_old (s._have_old)
|
||||
, _xml_property_name (s._xml_property_name)
|
||||
, _change (s._change)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -57,10 +65,13 @@ public:
|
||||
}
|
||||
|
||||
virtual void diff (XMLNode *, XMLNode *) const = 0;
|
||||
virtual Change set_state (XMLNode const &) = 0;
|
||||
virtual void add_state (XMLNode &) const = 0;
|
||||
|
||||
protected:
|
||||
bool _have_old;
|
||||
std::string _xml_property_name;
|
||||
Change _change;
|
||||
};
|
||||
|
||||
/** Class to represent a single piece of state in a Stateful object */
|
||||
@@ -68,8 +79,8 @@ template <class T>
|
||||
class State : public StateBase
|
||||
{
|
||||
public:
|
||||
State (std::string const & p, T const & v)
|
||||
: StateBase (p)
|
||||
State (std::string const & p, Change c, T const & v)
|
||||
: StateBase (p, c)
|
||||
, _current (v)
|
||||
{
|
||||
|
||||
@@ -86,6 +97,7 @@ public:
|
||||
/* XXX: isn't there a nicer place to do this? */
|
||||
_have_old = s._have_old;
|
||||
_xml_property_name = s._xml_property_name;
|
||||
_change = s._change;
|
||||
|
||||
_current = s._current;
|
||||
_old = s._old;
|
||||
@@ -112,21 +124,50 @@ public:
|
||||
|
||||
void diff (XMLNode* old, XMLNode* current) const {
|
||||
if (_have_old) {
|
||||
std::stringstream o;
|
||||
o << _old;
|
||||
old->add_property (_xml_property_name.c_str(), o.str().c_str());
|
||||
std::stringstream c;
|
||||
c << _current;
|
||||
current->add_property (_xml_property_name.c_str(), c.str().c_str());
|
||||
old->add_property (_xml_property_name.c_str(), to_string (_old));
|
||||
current->add_property (_xml_property_name.c_str(), to_string (_current));
|
||||
}
|
||||
}
|
||||
|
||||
/** Try to set state from the property of an XML node.
|
||||
* @param node XML node.
|
||||
* @return Change effected, or 0.
|
||||
*/
|
||||
Change set_state (XMLNode const & node) {
|
||||
XMLProperty const * p = node.property (_xml_property_name.c_str());
|
||||
|
||||
if (p) {
|
||||
std::stringstream s (p->value ());
|
||||
T v;
|
||||
s >> v;
|
||||
|
||||
if (v == _current) {
|
||||
return Change (0);
|
||||
}
|
||||
|
||||
set (v);
|
||||
return _change;
|
||||
}
|
||||
|
||||
return Change (0);
|
||||
}
|
||||
|
||||
void add_state (XMLNode & node) const {
|
||||
node.add_property (_xml_property_name.c_str(), to_string (_current));
|
||||
}
|
||||
|
||||
private:
|
||||
void set (T const & v) {
|
||||
_old = _current;
|
||||
_have_old = true;
|
||||
_current = v;
|
||||
}
|
||||
|
||||
std::string to_string (T const & v) const {
|
||||
std::stringstream s;
|
||||
s << v;
|
||||
return s.str ();
|
||||
}
|
||||
|
||||
T _current;
|
||||
T _old;
|
||||
@@ -163,6 +204,8 @@ class Stateful {
|
||||
|
||||
void add_instant_xml (XMLNode&, const sys::path& directory_path);
|
||||
XMLNode *instant_xml (const std::string& str, const sys::path& directory_path);
|
||||
Change set_state_using_states (XMLNode const &);
|
||||
void add_states (XMLNode &);
|
||||
|
||||
XMLNode *_extra_xml;
|
||||
XMLNode *_instant_xml;
|
||||
|
||||
@@ -35,6 +35,27 @@ namespace PBD {
|
||||
int Stateful::current_state_version = 0;
|
||||
int Stateful::loading_state_version = 0;
|
||||
|
||||
PBD::Change
|
||||
new_change ()
|
||||
{
|
||||
Change c;
|
||||
static uint32_t change_bit = 1;
|
||||
|
||||
/* catch out-of-range */
|
||||
if (!change_bit)
|
||||
{
|
||||
fatal << _("programming error: ")
|
||||
<< "change_bit out of range in ARDOUR::new_change()"
|
||||
<< endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
c = Change (change_bit);
|
||||
change_bit <<= 1; // if it shifts too far, change_bit == 0
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
Stateful::Stateful ()
|
||||
{
|
||||
_extra_xml = 0;
|
||||
@@ -175,5 +196,32 @@ Stateful::diff ()
|
||||
|
||||
return make_pair (old, current);
|
||||
}
|
||||
|
||||
/** Set state of _states from an XML node.
|
||||
* @param node Node.
|
||||
* @return Changes made.
|
||||
*/
|
||||
Change
|
||||
Stateful::set_state_using_states (XMLNode const & node)
|
||||
{
|
||||
Change c = Change (0);
|
||||
|
||||
for (list<StateBase*>::iterator i = _states.begin(); i != _states.end(); ++i) {
|
||||
c = Change (c | (*i)->set_state (node));
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Add state of _states to an XML node.
|
||||
* @param node Node.
|
||||
*/
|
||||
void
|
||||
Stateful::add_states (XMLNode & node)
|
||||
{
|
||||
for (list<StateBase*>::iterator i = _states.begin(); i != _states.end(); ++i) {
|
||||
(*i)->add_state (node);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace PBD
|
||||
|
||||
Reference in New Issue
Block a user