]> git.donarmstrong.com Git - lilypond.git/blob - staff.cc
release: 0.0.3
[lilypond.git] / staff.cc
1 #include "staff.hh"
2 #include "debug.hh"
3 #include "pscore.hh"
4
5 void
6 Staff::clean_cols()
7 {
8     PCursor<Staff_column *> stc(cols);
9     for(; stc.ok(); ){
10         if (!stc->score_column->used())
11             stc.del();
12         else
13             stc++;
14     }
15 }
16
17 /*
18     maak een staff column, met specs in args.
19
20     (sorry wat is het vroeg vandaag..)
21     */
22 Staff_column *
23 Staff::get_col(Mtime w, bool mus)
24 {
25     Score_column* sc = score_->find_col(w,mus);
26     assert(sc->when == w);
27     PCursor<Staff_column *> stc(cols);
28     for (; stc.ok(); stc++) {
29         if (*sc  < *stc->score_column)
30             break;
31         if (sc == stc->score_column)
32             return stc;
33     }
34     Staff_column* newst = create_col(sc);
35
36     if (!stc.ok()) {
37         cols.bottom().add(newst);
38         return cols.bottom();
39     }
40     
41     if (mus) {
42         stc.insert(newst);
43         return newst;
44     }
45
46     if ((stc-1)->when() == newst->when()) {
47         stc--;
48     }
49
50     stc.insert(newst);
51     
52     return newst;
53 }
54
55
56 void
57 Staff::add_voice(Voice *v)
58 {
59     voices.bottom().add(v);
60 }
61
62 /*
63     put all stuff grouped vertically in the Staff_cols
64     */
65 void
66 Staff::setup_staffcols()
67 {
68     
69     for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
70
71         Mtime now = vc->start;
72         for (PCursor<Voice_element *> ve(vc->elts); ve.ok(); ve++) {
73
74             Staff_column *sc=get_col(now,true);
75             sc->add(ve);
76             now += ve->duration;            
77         }       
78     }
79
80     for (PCursor<Command*> cc(commands); cc.ok(); cc++) {
81         Staff_column *sc=get_col(cc->when,false);
82         sc->s_commands.add(cc);
83     }
84 }
85
86 /// merge commands from score
87 void
88 Staff::add_commands(PointerList<Command*> const &cl)
89 {
90     PCursor<Command*> score_c(cl);
91     PCursor<Command*> cc(commands);
92     
93     while (score_c.ok()) {
94         while (cc.ok() && cc->when <= score_c->when)
95             cc++;
96         
97         Command*nc = new Command (*(* score_c));
98         if (cc.ok()) {
99             // cc->when > score_c->when
100             cc.insert( nc );
101         } else {
102             commands.bottom().add( nc);
103             cc = commands.bottom();
104         }
105         score_c++;
106     }
107
108     // now integrate break commands with other commands.
109     // may be do this in derived functions.
110 }
111
112 void
113 Staff::process()
114 {
115     setup_staffcols();
116     OK();
117     for (PCursor<Staff_column*> sc(cols); sc.ok(); sc++) {
118         sc->process_commands();
119         sc->process_requests();
120     }
121     grant_requests();
122 }
123
124 void
125 Staff::OK() const
126 {
127 #ifndef NDEBUG
128     cols.OK();
129     commands.OK();
130     voices.OK();
131     assert(score_);    
132 #endif    
133 }
134
135
136 Mtime
137 Staff::last() const {
138     Mtime l = 0.0;
139     for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
140         l = MAX(l, vc->last());
141     }
142     return l;
143 }
144
145
146 void
147 Staff::print() const
148 {
149     mtor << "Staff {\n";
150     for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
151         vc->print();
152         
153     }
154     mtor <<"}\n";
155 }
156
157 /****************************************************************/
158
159 bool
160 Staff_column::mus() const
161 {
162     return score_column->musical;
163 }
164
165 Mtime
166 Staff_column::when() const
167 {
168     return score_column->when;
169 }
170
171 void
172 Staff_column::add(Voice_element*ve)
173 {
174     Mtime d= ve->duration;
175     if (d){
176         score_column->durations.add(d);
177     }
178         
179     v_elts.add(ve);
180 }
181
182 Staff_column::Staff_column(Score_column*s) {
183     score_column = s;
184 }