Add missing files.
authorCarl Hetherington <carl@carlh.net>
Thu, 3 Dec 2009 21:53:08 +0000 (21:53 +0000)
committerCarl Hetherington <carl@carlh.net>
Thu, 3 Dec 2009 21:53:08 +0000 (21:53 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6271 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/session_playlists.h [new file with mode: 0644]
libs/ardour/session_playlists.cc [new file with mode: 0644]

diff --git a/libs/ardour/ardour/session_playlists.h b/libs/ardour/ardour/session_playlists.h
new file mode 100644 (file)
index 0000000..1fca497
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __ardour_session_playlists_h__
+#define __ardour_session_playlists_h__
+
+#include <set>
+#include <vector>
+#include <string>
+#include <glibmm/thread.h>
+#include <boost/shared_ptr.hpp>
+#include <sigc++/trackable.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Playlist;
+class Region;
+class Source;
+class Session;
+       
+class SessionPlaylists : public sigc::trackable
+{
+public:
+       ~SessionPlaylists ();
+       
+       boost::shared_ptr<Playlist> by_name (std::string name);
+       uint32_t source_use_count (boost::shared_ptr<const Source> src) const;
+       template<class T> void foreach (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
+       void get (std::vector<boost::shared_ptr<Playlist> >&);
+       void unassigned (std::list<boost::shared_ptr<Playlist> > & list);
+
+private:
+       friend class Session;
+       
+       bool add (boost::shared_ptr<Playlist>);
+       void remove (boost::shared_ptr<Playlist>);
+       void track (bool, boost::weak_ptr<Playlist>);
+       
+       uint32_t n_playlists() const;
+       void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result);
+       void update_after_tempo_map_change ();
+       void add_state (XMLNode *, bool);
+       bool maybe_delete_unused (sigc::signal<int, boost::shared_ptr<Playlist> >);
+       int load (Session &, const XMLNode&);
+       int load_unused (Session &, const XMLNode&);
+       boost::shared_ptr<Playlist> XMLPlaylistFactory (Session &, const XMLNode&);
+
+       mutable Glib::Mutex lock;
+       typedef std::set<boost::shared_ptr<Playlist> > List;
+       List playlists;
+       List unused_playlists;
+};
+
+}
+
+#endif
diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc
new file mode 100644 (file)
index 0000000..362d812
--- /dev/null
@@ -0,0 +1,336 @@
+#include "pbd/xml++.h"
+#include "pbd/compose.h"
+#include "ardour/debug.h"
+#include "ardour/session_playlists.h"
+#include "ardour/playlist.h"
+#include "ardour/region.h"
+#include "ardour/playlist_factory.h"
+#include "ardour/session.h"
+#include "i18n.h"
+
+using namespace std;
+using namespace PBD;
+using namespace ARDOUR;
+
+SessionPlaylists::~SessionPlaylists ()
+{
+       DEBUG_TRACE (DEBUG::Destruction, "delete playlists\n");
+       
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ) {
+               SessionPlaylists::List::iterator tmp;
+
+               tmp = i;
+               ++tmp;
+
+               DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
+               (*i)->drop_references ();
+
+               i = tmp;
+       }
+
+       DEBUG_TRACE (DEBUG::Destruction, "delete unused playlists\n");
+       for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
+               List::iterator tmp;
+
+               tmp = i;
+               ++tmp;
+
+               DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
+               (*i)->drop_references ();
+
+               i = tmp;
+       }
+
+       playlists.clear ();
+       unused_playlists.clear ();
+}
+
+bool
+SessionPlaylists::add (boost::shared_ptr<Playlist> playlist)
+{
+       Glib::Mutex::Lock lm (lock);
+
+       bool const existing = find (playlists.begin(), playlists.end(), playlist) != playlists.end();
+
+       if (!existing) {
+               playlists.insert (playlists.begin(), playlist);
+               playlist->InUse.connect (sigc::bind (mem_fun (*this, &SessionPlaylists::track), boost::weak_ptr<Playlist>(playlist)));
+       }
+
+       return existing;
+}
+
+void
+SessionPlaylists::remove (boost::shared_ptr<Playlist> playlist)
+{
+       Glib::Mutex::Lock lm (lock);
+
+       List::iterator i;
+
+       i = find (playlists.begin(), playlists.end(), playlist);
+       if (i != playlists.end()) {
+               playlists.erase (i);
+       }
+
+       i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
+       if (i != unused_playlists.end()) {
+               unused_playlists.erase (i);
+       }
+}
+       
+
+void
+SessionPlaylists::track (bool inuse, boost::weak_ptr<Playlist> wpl)
+{
+       boost::shared_ptr<Playlist> pl(wpl.lock());
+
+       if (!pl) {
+               return;
+       }
+
+       List::iterator x;
+
+       if (pl->hidden()) {
+               /* its not supposed to be visible */
+               return;
+       }
+
+       {
+               Glib::Mutex::Lock lm (lock);
+
+               if (!inuse) {
+
+                       unused_playlists.insert (pl);
+
+                       if ((x = playlists.find (pl)) != playlists.end()) {
+                               playlists.erase (x);
+                       }
+
+
+               } else {
+
+                       playlists.insert (pl);
+
+                       if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
+                               unused_playlists.erase (x);
+                       }
+               }
+       }
+}
+
+uint32_t
+SessionPlaylists::n_playlists () const
+{
+       Glib::Mutex::Lock lm (lock);
+       return playlists.size();
+}
+
+boost::shared_ptr<Playlist>
+SessionPlaylists::by_name (string name)
+{
+       Glib::Mutex::Lock lm (lock);
+
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               if ((*i)->name() == name) {
+                       return* i;
+               }
+       }
+       
+       for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+               if ((*i)->name() == name) {
+                       return* i;
+               }
+       }
+
+       return boost::shared_ptr<Playlist>();
+}
+
+void
+SessionPlaylists::unassigned (std::list<boost::shared_ptr<Playlist> > & list)
+{
+       Glib::Mutex::Lock lm (lock);
+
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
+                       list.push_back (*i);
+               }
+       }
+       
+       for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+               if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
+                       list.push_back (*i);
+               }
+       }
+}
+
+void
+SessionPlaylists::get (vector<boost::shared_ptr<Playlist> >& s)
+{
+       Glib::Mutex::Lock lm (lock);
+
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               s.push_back (*i);
+       }
+       
+       for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+               s.push_back (*i);
+       }
+}
+
+void
+SessionPlaylists::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
+{
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ++i)
+               (*i)->get_region_list_equivalent_regions (region, result);
+}
+
+/** Return the number of playlists (not regions) that contain @a src */
+uint32_t
+SessionPlaylists::source_use_count (boost::shared_ptr<const Source> src) const
+{
+       uint32_t count = 0;
+       for (List::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
+               for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
+                               r != (*p)->region_list().end(); ++r) {
+                       if ((*r)->uses_source(src)) {
+                               ++count;
+                               break;
+                       }
+               }
+       }
+       return count;
+}
+
+
+void
+SessionPlaylists::update_after_tempo_map_change ()
+{
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               (*i)->update_after_tempo_map_change ();
+       }
+
+       for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+               (*i)->update_after_tempo_map_change ();
+       }
+}
+
+void
+SessionPlaylists::add_state (XMLNode* node, bool full_state)
+{
+       XMLNode* child = node->add_child ("Playlists");
+       for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+               if (!(*i)->hidden()) {
+                       if (!(*i)->empty()) {
+                               if (full_state) {
+                                       child->add_child_nocopy ((*i)->get_state());
+                               } else {
+                                       child->add_child_nocopy ((*i)->get_template());
+                               }
+                       }
+               }
+       }
+
+       child = node->add_child ("UnusedPlaylists");
+       for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+               if (!(*i)->hidden()) {
+                       if (!(*i)->empty()) {
+                               if (full_state) {
+                                       child->add_child_nocopy ((*i)->get_state());
+                               } else {
+                                       child->add_child_nocopy ((*i)->get_template());
+                               }
+                       }
+               }
+       }
+}
+
+/** @return true for `stop cleanup', otherwise false */
+bool
+SessionPlaylists::maybe_delete_unused (sigc::signal<int, boost::shared_ptr<Playlist> > ask)
+{
+       vector<boost::shared_ptr<Playlist> > playlists_tbd;
+
+       for (List::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
+
+               int status = ask (*x);
+
+               switch (status) {
+               case -1:
+                       return true;
+
+               case 0:
+                       playlists_tbd.push_back (*x);
+                       break;
+
+               default:
+                       /* leave it alone */
+                       break;
+               }
+       }
+
+       /* now delete any that were marked for deletion */
+
+       for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
+               (*x)->drop_references ();
+       }
+
+       playlists_tbd.clear ();
+
+       return false;
+}
+
+int
+SessionPlaylists::load (Session& session, const XMLNode& node)
+{
+       XMLNodeList nlist;
+       XMLNodeConstIterator niter;
+       boost::shared_ptr<Playlist> playlist;
+
+       nlist = node.children();
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+               if ((playlist = XMLPlaylistFactory (session, **niter)) == 0) {
+                       error << _("Session: cannot create Playlist from XML description.") << endmsg;
+               }
+       }
+
+       return 0;
+}
+
+int
+SessionPlaylists::load_unused (Session& session, const XMLNode& node)
+{
+       XMLNodeList nlist;
+       XMLNodeConstIterator niter;
+       boost::shared_ptr<Playlist> playlist;
+
+       nlist = node.children();
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+               if ((playlist = XMLPlaylistFactory (session, **niter)) == 0) {
+                       error << _("Session: cannot create Playlist from XML description.") << endmsg;
+                       continue;
+               }
+
+               // now manually untrack it
+
+               track (false, boost::weak_ptr<Playlist> (playlist));
+       }
+
+       return 0;
+}
+
+boost::shared_ptr<Playlist>
+SessionPlaylists::XMLPlaylistFactory (Session& session, const XMLNode& node)
+{
+       try {
+               return PlaylistFactory::create (session, node);
+       }
+
+       catch (failed_constructor& err) {
+               return boost::shared_ptr<Playlist>();
+       }
+}
+