#include <unistd.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
#include "pbd/debug.h"
#include "pbd/stateful.h"
#include "pbd/property_list.h"
#include "pbd/properties.h"
#include "pbd/destructible.h"
-#include "pbd/filesystem.h"
#include "pbd/xml++.h"
#include "pbd/error.h"
int Stateful::loading_state_version = 0;
Stateful::Stateful ()
- : _frozen (0)
- , _properties (new OwnedPropertyList)
+ : _properties (new OwnedPropertyList)
+ , _stateful_frozen (0)
{
_extra_xml = 0;
_instant_xml = 0;
Stateful::~Stateful ()
{
- delete _properties;
+ delete _properties;
// Do not delete _extra_xml. The use of add_child_nocopy()
// means it needs to live on indefinately.
}
XMLNode *
-Stateful::extra_xml (const string& str)
+Stateful::extra_xml (const string& str, bool add_if_missing)
{
- if (_extra_xml == 0) {
- return 0;
+ XMLNode* node = 0;
+
+ if (_extra_xml) {
+ node = _extra_xml->child (str.c_str());
}
- const XMLNodeList& nlist = _extra_xml->children();
- XMLNodeConstIterator i;
+ if (!node && add_if_missing) {
+ node = new XMLNode (str);
+ add_extra_xml (*node);
+ }
- for (i = nlist.begin(); i != nlist.end(); ++i) {
- if ((*i)->name() == str) {
- return (*i);
- }
- }
+ return node;
+}
- return 0;
+void
+Stateful::save_extra_xml (const XMLNode& node)
+{
+ /* Looks for the child node called "Extra" and makes _extra_xml
+ point to a copy of it. Will delete any existing node pointed
+ to by _extra_xml if a new Extra node is found, but not
+ otherwise.
+ */
+
+ const XMLNode* xtra = node.child ("Extra");
+
+ if (xtra) {
+ delete _extra_xml;
+ _extra_xml = new XMLNode (*xtra);
+ }
}
void
-Stateful::add_instant_xml (XMLNode& node, const sys::path& directory_path)
+Stateful::add_instant_xml (XMLNode& node, const std::string& directory_path)
{
- sys::create_directories (directory_path); // may throw
+ if (!Glib::file_test (directory_path, Glib::FILE_TEST_IS_DIR)) {
+ if (g_mkdir_with_parents (directory_path.c_str(), 0755) != 0) {
+ error << string_compose(_("Error: could not create directory %1"), directory_path) << endmsg;
+ return;
+ }
+ }
if (_instant_xml == 0) {
_instant_xml = new XMLNode ("instant");
_instant_xml->remove_nodes_and_delete (node.name());
_instant_xml->add_child_copy (node);
- sys::path instant_xml_path(directory_path);
-
- instant_xml_path /= "instant.xml";
+ std::string instant_xml_path = Glib::build_filename (directory_path, "instant.xml");
XMLTree tree;
- tree.set_filename(instant_xml_path.to_string());
+ tree.set_filename(instant_xml_path);
/* Important: the destructor for an XMLTree deletes
all of its nodes, starting at _root. We therefore
tree.set_root (copy);
if (!tree.write()) {
- error << string_compose(_("Error: could not write %1"), instant_xml_path.to_string()) << endmsg;
+ error << string_compose(_("Error: could not write %1"), instant_xml_path) << endmsg;
}
}
XMLNode *
-Stateful::instant_xml (const string& str, const sys::path& directory_path)
+Stateful::instant_xml (const string& str, const std::string& directory_path)
{
if (_instant_xml == 0) {
- sys::path instant_xml_path(directory_path);
- instant_xml_path /= "instant.xml";
+ std::string instant_xml_path = Glib::build_filename (directory_path, "instant.xml");
- if (exists(instant_xml_path)) {
+ if (Glib::file_test (instant_xml_path, Glib::FILE_TEST_EXISTS)) {
XMLTree tree;
- if (tree.read(instant_xml_path.to_string())) {
+ if (tree.read(instant_xml_path)) {
_instant_xml = new XMLNode(*(tree.root()));
} else {
- warning << string_compose(_("Could not understand XML file %1"), instant_xml_path.to_string()) << endmsg;
+ warning << string_compose(_("Could not understand XML file %1"), instant_xml_path) << endmsg;
return 0;
}
} else {
}
/** Set our property values from an XML node.
- * Derived types can call this from ::set_state() (or elsewhere)
+ * Derived types can call this from set_state() (or elsewhere)
* to get basic property setting done.
* @return IDs of properties that were changed.
*/
Stateful::set_values (XMLNode const & node)
{
PropertyChange c;
-
+
for (OwnedPropertyList::iterator i = _properties->begin(); i != _properties->end(); ++i) {
if (i->second->set_value (node)) {
c.add (i->first);
PropertyChange c;
PropertyList::const_iterator p;
- DEBUG_TRACE (DEBUG::Stateful, string_compose ("Stateful %1 setting properties from list of %2\n", this, property_list.size()));
+ DEBUG_TRACE (DEBUG::Stateful, string_compose ("Stateful %1 setting properties from list of %2\n", this, property_list.size()));
- for (PropertyList::const_iterator pp = property_list.begin(); pp != property_list.end(); ++pp) {
- DEBUG_TRACE (DEBUG::Stateful, string_compose ("in plist: %1\n", pp->second->property_name()));
- }
-
- for (PropertyList::const_iterator i = property_list.begin(); i != property_list.end(); ++i) {
- if ((p = _properties->find (i->first)) != _properties->end()) {
+ for (PropertyList::const_iterator pp = property_list.begin(); pp != property_list.end(); ++pp) {
+ DEBUG_TRACE (DEBUG::Stateful, string_compose ("in plist: %1\n", pp->second->property_name()));
+ }
+
+ for (PropertyList::const_iterator i = property_list.begin(); i != property_list.end(); ++i) {
+ if ((p = _properties->find (i->first)) != _properties->end()) {
- DEBUG_TRACE (
+ DEBUG_TRACE (
DEBUG::Stateful,
string_compose ("actually setting property %1 using %2\n", p->second->property_name(), i->second->property_name())
);
c.add (i->first);
}
} else {
- DEBUG_TRACE (DEBUG::Stateful, string_compose ("passed in property %1 not found in own property list\n",
- i->second->property_name()));
- }
+ DEBUG_TRACE (DEBUG::Stateful, string_compose ("passed in property %1 not found in own property list\n",
+ i->second->property_name()));
+ }
}
post_set (c);
void
Stateful::add_property (PropertyBase& s)
{
- _properties->add (s);
+ _properties->add (s);
}
void
}
{
- Glib::Mutex::Lock lm (_lock);
- if (_frozen) {
+ Glib::Threads::Mutex::Lock lm (_lock);
+ if (property_changes_suspended ()) {
_pending_changed.add (what_changed);
return;
}
void
Stateful::suspend_property_changes ()
{
- _frozen++;
+ g_atomic_int_add (&_stateful_frozen, 1);
}
void
PropertyChange what_changed;
{
- Glib::Mutex::Lock lm (_lock);
+ Glib::Threads::Mutex::Lock lm (_lock);
- if (_frozen && --_frozen > 0) {
+ if (property_changes_suspended() && g_atomic_int_dec_and_test (&_stateful_frozen) == FALSE) {
return;
}
}
}
- mid_thaw (what_changed);
+ mid_thaw (what_changed);
- send_change (what_changed);
+ send_change (what_changed);
}
bool
Stateful::changed() const
{
for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
- if (i->second->changed()) {
- return true;
- }
- }
+ if (i->second->changed()) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
bool
PropertyList*
Stateful::property_factory (const XMLNode& history_node) const
{
- PropertyList* prop_list = new PropertyList;
+ PropertyList* prop_list = new PropertyList;
- for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
- PropertyBase* prop = i->second->clone_from_xml (history_node);
+ for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ PropertyBase* prop = i->second->clone_from_xml (history_node);
- if (prop) {
- prop_list->add (prop);
- }
- }
+ if (prop) {
+ prop_list->add (prop);
+ }
+ }
- return prop_list;
+ return prop_list;
}
void
}
}
+bool
+Stateful::set_id (const XMLNode& node)
+{
+ const XMLProperty* prop;
+
+ if ((prop = node.property ("id")) != 0) {
+ _id = prop->value ();
+ return true;
+ }
+
+ return false;
+}
+
+void
+Stateful::reset_id ()
+{
+ _id = ID ();
+}
+
+void
+Stateful::set_id (const string& str)
+{
+ _id = str;
+}
} // namespace PBD