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