Simplify GUIOBjectState a bit by just walking the XML
authorCarl Hetherington <carl@carlh.net>
Fri, 20 Jan 2012 18:02:43 +0000 (18:02 +0000)
committerCarl Hetherington <carl@carlh.net>
Fri, 20 Jan 2012 18:02:43 +0000 (18:02 +0000)
directly rather than maintaining internal data
structures.

git-svn-id: svn://localhost/ardour2/branches/3.0@11287 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/gui_object.cc
gtk2_ardour/gui_object.h
gtk2_ardour/midi_time_axis.cc

index fa708b25ad4ffb4319e81b44713450eb1f327de7..2b516d04dac97e64b16bf0230cd6f14d329cec6f 100644 (file)
 */
 
 #include <iostream>
-#include <iomanip>
 #include <sstream>
 
-#include <boost/variant/static_visitor.hpp>
-
 #include "gui_object.h"
 #include "i18n.h"
 
@@ -30,92 +27,67 @@ using std::string;
 
 const string GUIObjectState::xml_node_name (X_("GUIObjectState"));
 
-GUIObjectState::~GUIObjectState ()
+GUIObjectState::GUIObjectState ()
+       : _state (X_("GUIObjectState"))
 {
-       clear_maps ();
+
 }
 
-void
-GUIObjectState::clear_maps ()
+XMLNode *
+GUIObjectState::find_node (const string& id) const
 {
-       _property_maps.clear ();
+       XMLNodeList const & children = _state.children ();
+       for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+               if ((*i)->name() != X_("Object")) {
+                       continue;
+               }
+
+               XMLProperty* p = (*i)->property (X_("id"));
+               if (p && p->value() == id) {
+                       return *i;
+               }
+       }
+
+       return 0;
 }
 
-class gos_string_vistor : public boost::static_visitor<> {
-  public:
-    gos_string_vistor (std::ostream& o) 
-           : stream (o) {}
-           
-    void operator() (const int64_t& i) {
-           stream << i;
-    }
-
-    void operator() (const std::string& s) {
-           stream << s;
-    }
-
-  private:
-    std::ostream& stream;
-};
-
-std::string 
-GUIObjectState::get_string (const std::string& id, const std::string& prop_name, bool* empty)
+/** Get a string from our state.
+ *  @param id property of Object node to look for.
+ *  @param prop_name name of the Object property to return.
+ *  @param empty if non-0, filled in with true if the property is currently non-existant, otherwise false.
+ *  @return value of property `prop_name', or empty.
+ */
+
+string 
+GUIObjectState::get_string (const string& id, const string& prop_name, bool* empty)
 {
-       StringPropertyMap::iterator i = _property_maps.find (id);
-       
-       if (i == _property_maps.end()) {
+       XMLNode* child = find_node (id);
+       if (!child) {
                if (empty) {
                        *empty = true;
                }
-               return string();
+               return string ();
        }
-       
-       const PropertyMap& pmap (i->second);
-       PropertyMap::const_iterator p = pmap.find (prop_name);
-       
-       if (p == pmap.end()) {
+
+       XMLProperty* p = child->property (prop_name);
+       if (!p) {
                if (empty) {
                        *empty = true;
                }
-               return string();
+               return string ();
        }
-       
-       std::stringstream ss;
-       gos_string_vistor gsv (ss);
-
-       boost::apply_visitor (gsv, p->second);
 
        if (empty) {
                *empty = false;
        }
-       
-       return ss.str ();
+
+       return p->value ();
 }
 
 XMLNode&
 GUIObjectState::get_state () const
 {
-       XMLNode* root = new XMLNode (xml_node_name);
-       
-       for (StringPropertyMap::const_iterator i = _property_maps.begin(); i != _property_maps.end(); ++i) {
-
-               const PropertyMap& pmap (i->second);
-               XMLNode* id_node = new XMLNode (X_("Object"));
-               
-               id_node->add_property ("id", i->first);
-               
-               for (PropertyMap::const_iterator p = pmap.begin(); p != pmap.end(); ++p) {
-                       std::stringstream ss;
-                       gos_string_vistor gsv (ss);
-                       boost::apply_visitor (gsv, p->second);
-                       id_node->add_property (p->first.c_str(), ss.str());
-               }
-               
-               root->add_child_nocopy (*id_node);
-       }
-
-
-       return *root;
+       return *new XMLNode (_state);
 }
 
 int
@@ -124,38 +96,11 @@ GUIObjectState::set_state (const XMLNode& node)
        if (node.name() != xml_node_name) {
                return -1;
        }
-       
-       clear_maps ();
-       
-       for (XMLNodeList::const_iterator i = node.children().begin(); i != node.children().end(); ++i) {
-               if ((*i)->name() == X_("Object")) {
-
-                       XMLNode* child = (*i);
-                       const XMLProperty* idp = child->property (X_("id"));
-
-                       if (!idp) {
-                               continue;
-                       }
-
-                       string id (idp->value());
-                       
-                       for (XMLPropertyList::const_iterator p = child->properties().begin(); p != child->properties().end(); ++p) {
-                               /* note that this always sets the property with
-                                  a string value, and so is not equivalent to
-                                  a call made by the program that passed a
-                                  scalar.
-                               */
-                               if ((*p)->name() != X_("id")) {
-                                       set (id, (*p)->name(), (*p)->value());
-                               }
-                       }
-               }
-       }
 
+       _state = node;
        return 0;
 }
 
-
 void
 GUIObjectState::load (const XMLNode& node)
 {
@@ -165,22 +110,27 @@ GUIObjectState::load (const XMLNode& node)
 GUIObjectState&
 GUIObjectState::operator= (const GUIObjectState& other)
 {
-       _property_maps = other._property_maps;
-
+       _state = other._state;
        return *this;
 }
 
-/** @return begin iterator into our StringPropertyMap */
-GUIObjectState::StringPropertyMap::const_iterator
-GUIObjectState::begin () const
+std::list<string>
+GUIObjectState::all_ids () const
 {
-       return _property_maps.begin ();
-}
+       std::list<string> ids;
+       XMLNodeList const & children = _state.children ();
+       for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+               if ((*i)->name() != X_("Object")) {
+                       continue;
+               }
 
-/** @return end iterator into our StringPropertyMap */
-GUIObjectState::StringPropertyMap::const_iterator
-GUIObjectState::end () const
-{
-       return _property_maps.end ();
+               XMLProperty* p = (*i)->property (X_("id"));
+               if (p) {
+                       ids.push_back (p->value ());
+               }
+       }
+
+       return ids;
 }
 
+       
index 849665670f2c60a8e99842108d11fc657c2d6171..3cbd85c171b0b7a5deca696146d9ef022ec694e9 100644 (file)
 #include "pbd/xml++.h"
 #include "pbd/id.h"
 
-class GUIObjectState {
-  private:
-       typedef boost::variant<int64_t,std::string> Variant;
-       typedef std::map<std::string,Variant> PropertyMap;
+#include "i18n.h"
 
-  public:
-       typedef std::map<std::string,PropertyMap> StringPropertyMap;
+class GUIObjectState
+{
+public:
+       GUIObjectState ();
        
-       ~GUIObjectState();
-
-       StringPropertyMap::const_iterator begin () const;
-       StringPropertyMap::const_iterator end () const;
-
        XMLNode& get_state () const;
        int set_state (const XMLNode&);
 
@@ -52,19 +46,24 @@ class GUIObjectState {
        std::string get_string (const std::string& id, const std::string& prop_name, bool* empty = 0);
 
        template<typename T> void set (const std::string& id, const std::string& prop_name, const T& val) {
-               StringPropertyMap::iterator i = _property_maps.find (id);
-               
-               if (i != _property_maps.end()) {
-                       i->second[prop_name] = val;
-               } else {
-                       _property_maps[id] = PropertyMap();
-                       _property_maps[id][prop_name] = val;
+               XMLNode* child = find_node (id);
+               if (!child) {
+                       child = new XMLNode (X_("Object"));
+                       child->add_property (X_("id"), id);
+                       _state.add_child_nocopy (*child);
                }
+               
+               std::stringstream s;
+               s << val;
+               child->add_property (prop_name.c_str(), s.str());
        }
+
+       std::list<std::string> all_ids () const;
+       
   private:
-       StringPropertyMap _property_maps;
+       XMLNode* find_node (const std::string &) const;
 
-       void clear_maps ();
+       XMLNode _state;
 };
 
 
index 922b5ab031f6e3aa3baeda5851e79a9acd45be62..8b87772ebb0f6d7966ed8de7740537f930d1b47a 100644 (file)
@@ -248,16 +248,16 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
        /* Look for any GUI object state nodes that represent automation children that should exist, and create
         * the children.
         */
-       
-       GUIObjectState& gui_state = gui_object_state ();
-       for (GUIObjectState::StringPropertyMap::const_iterator i = gui_state.begin(); i != gui_state.end(); ++i) {
+
+       list<string> gui_ids = gui_object_state().all_ids ();
+       for (list<string>::const_iterator i = gui_ids.begin(); i != gui_ids.end(); ++i) {
                PBD::ID route_id;
                bool has_parameter;
                Evoral::Parameter parameter (0, 0, 0);
 
-               bool const p = AutomationTimeAxisView::parse_state_id (i->first, route_id, has_parameter, parameter);
+               bool const p = AutomationTimeAxisView::parse_state_id (*i, route_id, has_parameter, parameter);
                if (p && route_id == _route->id () && has_parameter) {
-                       create_automation_child (parameter, string_is_affirmative (gui_object_state().get_string (i->first, X_("visible"))));
+                       create_automation_child (parameter, string_is_affirmative (gui_object_state().get_string (*i, X_("visible"))));
                }
        }
 }