X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Flibr2c2%2Ftrackiter.cpp;fp=source%2Flibr2c2%2Ftrackiter.cpp;h=3c6295bb974437720b7677cf18bdbadab9136381;hb=1ff06c5bc46a677fa389ef86c6b26664368f1653;hp=0000000000000000000000000000000000000000;hpb=9b05c573a38639827697fe393d55b7c76f5bde45;p=r2c2.git diff --git a/source/libr2c2/trackiter.cpp b/source/libr2c2/trackiter.cpp new file mode 100644 index 0000000..3c6295b --- /dev/null +++ b/source/libr2c2/trackiter.cpp @@ -0,0 +1,171 @@ +/* $Id$ + +This file is part of R²C² +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include +#include "track.h" +#include "trackiter.h" +#include "tracktype.h" + +using namespace std; +using namespace Msp; + +namespace R2C2 { + +TrackIter::TrackIter(): + _track(0), + _entry(0) +{ } + +TrackIter::TrackIter(Track *t, unsigned e): + _track(t), + _entry(t ? e : 0) +{ + if(_track && _entry>_track->get_type().get_endpoints().size()) + throw InvalidParameterValue("Endpoint index not valid for track"); +} + +const TrackType::Endpoint &TrackIter::endpoint() const +{ + if(!_track) + throw InvalidState("TrackIter is null"); + + return _track->get_type().get_endpoint(_entry); +} + +int TrackIter::get_exit(unsigned path) const +{ + const vector &eps = _track->get_type().get_endpoints(); + + // Find an endpoint that's connected to the entry and has the requested path + for(unsigned i=0; iget_active_path()); +} + +TrackIter TrackIter::next(unsigned path) const +{ + if(!_track) + return TrackIter(); + + int exit = get_exit(path); + if(exit<0) + return TrackIter(); + + TrackIter result; + result._track = _track->get_link(exit); + result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0); + + return result; +} + +TrackIter TrackIter::reverse() const +{ + if(!_track) + return TrackIter(); + + return reverse(_track->get_active_path()); +} + +TrackIter TrackIter::reverse(unsigned path) const +{ + if(!_track) + return TrackIter(); + + int exit = get_exit(path); + if(exit<0) + return TrackIter(); + + return TrackIter(_track, exit); +} + +TrackIter TrackIter::flip() const +{ + if(!_track) + return TrackIter(); + + TrackIter result; + result._track = _track->get_link(_entry); + result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0); + + return result; +} + +Track &TrackIter::operator*() const +{ + if(!_track) + throw InvalidState("TrackIter is null"); + + return *_track; +} + +bool TrackIter::operator==(const TrackIter &other) const +{ + return _track==other._track && _entry==other._entry; +} + + +TrackLoopIter::TrackLoopIter(): + _looped(false) +{ } + +TrackLoopIter::TrackLoopIter(Track *t, unsigned e): + TrackIter(t, e), + _visited(new TrackList()), + _last(_visited->insert(_visited->end(), track())), + _looped(false) +{ } + +TrackLoopIter::TrackLoopIter(const TrackIter &i): + TrackIter(i), + _visited(new TrackList()), + _last(_visited->insert(_visited->end(), track())), + _looped(false) +{ } + +TrackLoopIter::TrackLoopIter(const TrackIter &i, RefPtr v, const TrackList::iterator &l): + TrackIter(i), + _looped(false) +{ + if(track()) + { + _visited = v; + _last = l; + _looped = (_visited && find(_visited->begin(), _last, track())!=_last); + + ++_last; + if(_last!=_visited->end()) + { + _visited = new TrackList(_visited->begin(), _last); + _last = _visited->end(); + } + _visited->push_back(track()); + --_last; + } +} + +TrackLoopIter TrackLoopIter::next() const +{ + return TrackLoopIter(TrackIter::next(), _visited, _last); +} + +TrackLoopIter TrackLoopIter::next(unsigned path) const +{ + return TrackLoopIter(TrackIter::next(path), _visited, _last); +} + +} // namespace R2C2