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