new port design, probably about 90% done (i.e it mostly works and this commit is...
[ardour.git] / libs / ardour / source.cc
index bf07ede70b725a1d13412c9389cd62592455c6cb..a11e82f1e81b245e912ca9f3e2a1439ee2fbd71c 100644 (file)
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <sys/stat.h>
@@ -34,6 +33,7 @@
 #include <pbd/pthread_utils.h>
 
 #include <ardour/source.h>
+#include <ardour/playlist.h>
 
 #include "i18n.h"
 
@@ -42,33 +42,34 @@ using std::max;
 
 using namespace ARDOUR;
 
-sigc::signal<void,Source*> Source::SourceCreated;
-
-
-Source::Source (string name, DataType type)
-       : _type(type)
+Source::Source (Session& s, const string& name, DataType type)
+       : SessionObject(s, name)
+       , _type(type)
 {
-       assert(_name.find("/") == string::npos);
+       // not true.. is this supposed to be an assertion?
+       //assert(_name.find("/") == string::npos);
 
-       _name = name;
-       _use_cnt = 0;
        _timestamp = 0;
+       _length = 0;
+       _in_use = 0;
 }
 
-Source::Source (const XMLNode& node) 
-       : _type(DataType::AUDIO)
+Source::Source (Session& s, const XMLNode& node) 
+       : SessionObject(s, "unnamed source")
+       , _type(DataType::AUDIO)
 {
-       _use_cnt = 0;
        _timestamp = 0;
+       _length = 0;
+       _in_use = 0;
 
        if (set_state (node) || _type == DataType::NIL) {
                throw failed_constructor();
        }
-       assert(_name.find("/") == string::npos);
 }
 
 Source::~Source ()
 {
+       notify_callbacks ();
 }
 
 XMLNode&
@@ -79,7 +80,7 @@ Source::get_state ()
 
        node->add_property ("name", _name);
        node->add_property ("type", _type.to_string());
-       _id.print (buf);
+       _id.print (buf, sizeof (buf));
        node->add_property ("id", buf);
 
        if (_timestamp != 0) {
@@ -114,28 +115,61 @@ Source::set_state (const XMLNode& node)
        if ((prop = node.property ("timestamp")) != 0) {
                sscanf (prop->value().c_str(), "%ld", &_timestamp);
        }
-       assert(_name.find("/") == string::npos);
+       
+       // Don't think this is valid, absolute paths fail
+       //assert(_name.find("/") == string::npos);
 
        return 0;
 }
 
 void
-Source::use ()
+Source::update_length (nframes_t pos, nframes_t cnt)
 {
-       _use_cnt++;
+       if (pos + cnt > _length) {
+               _length = pos+cnt;
+       }
 }
 
 void
-Source::release ()
+Source::add_playlist (boost::shared_ptr<Playlist> pl)
 {
-       if (_use_cnt) --_use_cnt;
+       std::pair<PlaylistMap::iterator,bool> res;
+       std::pair<boost::shared_ptr<Playlist>, uint32_t> newpair (pl, 1);
+       Glib::Mutex::Lock lm (playlist_lock);
+
+       res = _playlists.insert (newpair);
+
+       if (!res.second) {
+               /* it already existed, bump count */
+               res.first->second++;
+       }
+               
+       pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr<Playlist> (pl)));
 }
 
 void
-Source::update_length (jack_nframes_t pos, jack_nframes_t cnt)
+Source::remove_playlist (boost::weak_ptr<Playlist> wpl)
 {
-       if (pos + cnt > _length) {
-               _length = pos+cnt;
+       boost::shared_ptr<Playlist> pl (wpl.lock());
+
+       if (!pl) {
+               return;
+       }
+
+       PlaylistMap::iterator x;
+       Glib::Mutex::Lock lm (playlist_lock);
+
+       if ((x = _playlists.find (pl)) != _playlists.end()) {
+               if (x->second > 1) {
+                       x->second--;
+               } else {
+                       _playlists.erase (x);
+               }
        }
 }
 
+uint32_t
+Source::used () const
+{
+       return _playlists.size();
+}