1 #include <msp/strings/utils.h>
4 #include "trackchain.h"
8 TrackChain::TrackChain(Layout &l):
11 layout.signal_object_removed.connect(sigc::mem_fun(this, &TrackChain::object_removed));
14 void TrackChain::add_track(Track &track)
16 if(tracks.count(&track))
19 Validity valid = check_validity(track);
21 throw_bad_chain(valid);
23 tracks.insert(&track);
25 on_track_added(track);
28 void TrackChain::add_tracks(const TrackSet &trks)
31 for(TrackSet::const_iterator i=trks.begin(); i!=trks.end(); ++i)
35 while(!pending.empty())
37 Validity valid = UNLINKED;
38 for(TrackSet::iterator i=pending.begin(); i!=pending.end(); ++i)
39 if((valid=check_validity(**i))==VALID)
49 throw_bad_chain(valid);
53 TrackChain::Validity TrackChain::check_validity(Track &track) const
62 return ends[0]->get_link_slot(track)>=0 ? VALID : UNLINKED;
65 Validity result = UNLINKED;
66 for(unsigned i=0; i<2; ++i)
68 int j = ends[i]->get_link_slot(track);
71 const TrackType::Endpoint &ep1 = ends[i].endpoint();
72 const TrackType::Endpoint &ep2 = ends[i]->get_type().get_endpoint(j);
73 if(!ep1.has_common_paths(ep2))
83 void TrackChain::throw_bad_chain(Validity v)
86 throw bad_chain("unlinked");
88 throw bad_chain("bad path");
89 else if(v==INCOMPATIBLE)
90 throw bad_chain("incompatible");
93 void TrackChain::update_ends(Track &track)
96 // We don't really know the proper endpoint yet; just pick something
97 ends[0] = TrackIter(&track, 0);
100 // We're adding the second track; determine endpoints for both
101 ends[0] = TrackIter(&*ends[0], ends[0]->get_link_slot(track));
102 ends[1] = TrackIter(&track, track.get_link_slot(*ends[0]));
107 for(unsigned i=0; i<2; ++i)
108 if(ends[i]->get_link_slot(track)>=0)
113 // Closed loop; clear the ends
114 ends[0] = TrackIter();
115 ends[1] = TrackIter();
118 ends[linked-1] = TrackIter(&track, track.get_link_slot(*ends[linked-1]));
122 bool TrackChain::has_track(Track &t) const
124 return tracks.count(&t);
127 void TrackChain::object_removed(Object &obj)
129 if(Track *track = dynamic_cast<Track *>(&obj))
131 /* TODO If the track was in the middle of the chain, keep only the