]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/zone.cpp
eddcfc9386749fb4ca6ece84be58a361d17a4124
[r2c2.git] / source / libr2c2 / zone.cpp
1 #include <msp/strings/format.h>
2 #include "block.h"
3 #include "layout.h"
4 #include "track.h"
5 #include "zone.h"
6
7 using namespace std;
8 using namespace Msp;
9
10 namespace R2C2 {
11
12 Zone::Zone(Layout &l):
13         layout(l),
14         number(0)
15 {
16         layout.add_zone(*this);
17 }
18
19 Zone::~Zone()
20 {
21         layout.remove_zone(*this);
22 }
23
24 void Zone::set_name(const string &g, const string &q, unsigned n)
25 {
26         group = g;
27         qualifier = q;
28         number = n;
29
30         signal_name_changed.emit(group, qualifier, number);
31 }
32
33 string Zone::get_name() const
34 {
35         string result = group;
36         if(!qualifier.empty())
37         {
38                 result += ' ';
39                 result += qualifier;
40         }
41         if(number)
42                 result += format(" %d", number);
43         return result;
44 }
45
46 void Zone::add_track(Track &track)
47 {
48         if(!is_valid(track))
49                 throw logic_error("unconnected");
50
51         tracks.insert(&track);
52 }
53
54 bool Zone::add_tracks(const TrackSet &trks)
55 {
56         TrackSet pending = trks;
57         bool first = true;
58         while(1)
59         {
60                 bool ok = false;
61                 for(TrackSet::const_iterator i=pending.begin(); i!=pending.end(); ++i)
62                         if(is_valid(**i))
63                         {
64                                 tracks.insert(*i);
65                                 pending.erase(i);
66                                 ok = true;
67                                 break;
68                         }
69
70                 if(!ok)
71                 {
72                         if(first)
73                                 throw logic_error("unconnected");
74                         return pending.empty();
75                 }
76
77                 first = false;
78         }
79 }
80
81 void Zone::save(list<DataFile::Statement> &st) const
82 {
83         st.push_back((DataFile::Statement("group"), group));
84         if(!qualifier.empty())
85                 st.push_back((DataFile::Statement("qualifier"), qualifier));
86         if(number)
87                 st.push_back((DataFile::Statement("number"), number));
88
89         set<unsigned> block_ids;
90         for(TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
91                 block_ids.insert((*i)->get_block().get_id());
92
93         for(set<unsigned>::const_iterator i=block_ids.begin(); i!=block_ids.end(); ++i)
94                 st.push_back((DataFile::Statement("block"), *i));
95 }
96
97 bool Zone::is_valid(Track &t) const
98 {
99         if(tracks.empty())
100                 return true;
101
102         const vector<Track *> &links = t.get_links();
103         for(vector<Track *>::const_iterator i=links.begin(); i!=links.end(); ++i)
104                 if(*i && tracks.count(*i))
105                         return true;
106
107         return false;
108 }
109
110
111 Zone::Loader::Loader(Zone &z):
112         DataFile::ObjectLoader<Zone>(z)
113 {
114         add("block",     &Loader::block);
115         add("group",     &Zone::group);
116         add("number",    &Zone::number);
117         add("qualifier", &Zone::qualifier);
118 }
119
120 void Zone::Loader::block(unsigned b)
121 {
122         Block &blk = obj.layout.get_block(b);
123         const set<Track *> &btracks = blk.get_tracks();
124         obj.tracks.insert(btracks.begin(), btracks.end());
125 }
126
127 } // namespace R2C2