]> git.donarmstrong.com Git - lilypond.git/blob - src/inputcommands.cc
c7f7aaff5632c5c1e58e880c1a165ba0fd9d8685
[lilypond.git] / src / inputcommands.cc
1 /*
2   it still sucks.
3   */
4
5 #include "inputcommands.hh"
6 #include "inputcommand.hh"
7 #include "debug.hh"
8 #include "staffcommands.hh"
9 #include "getcommand.hh"
10 #include "command.hh"
11
12 void
13 Commands_at::print() const
14 {
15 #ifndef NPRINT
16     mtor << "{ at "<<when<<'\n'; 
17     mtor << "meter " << whole_per_measure
18          << " pos "<< bars << ":" << whole_in_measure <<'\n';
19     for (PCursor<Input_command *> cc(*this); cc.ok(); cc++) 
20         cc->print();
21     mtor << "}\n";
22 #endif
23 }
24
25 Commands_at::Commands_at(Real dt, Commands_at* prev)
26 {
27     if (prev) {
28         assert(dt >0);
29         when = prev->when + dt;
30         whole_per_measure = prev->whole_per_measure;
31         whole_in_measure = prev->whole_in_measure + dt;
32         bars = prev->bars;
33
34         while ( whole_in_measure >= whole_per_measure ) {
35             whole_in_measure -= whole_per_measure;
36             bars ++;
37         }
38         if (!whole_in_measure) {
39             bottom().add(get_bar_command());
40         }
41     } else {
42         whole_per_measure = 1;
43         whole_in_measure =0;
44         when = 0.0;
45         bars = 0;
46     }
47 }
48
49 void
50 Commands_at::add(Input_command *i )
51 {
52     bottom().add(i);            
53     if (i->args[0] == "METER") { // should check for other meterchanges here.
54         Real l = i->args[1];
55         Real o = i->args[2];
56         whole_per_measure = l/o;                
57     }
58 }
59
60 Commands_at::Commands_at(Commands_at const&src)
61 {
62     when = src.when;
63     whole_in_measure = whole_in_measure;
64     whole_per_measure = whole_per_measure;
65     bars = src.bars;
66     
67     IPointerList<Input_command*> &me(*this);
68     const IPointerList<Input_command*> &that(src);
69     
70     PL_copy(me, that);
71 }
72
73 void
74 Commands_at::setpartial(Real p)
75 {
76     if (when)
77         error_t ("Partial measure only allowed at beginning.", when);
78     if (p<0||p > whole_per_measure)
79         error_t ("Partial measure has incorrect size", when);
80     whole_in_measure = whole_per_measure - p;
81 }
82 Real
83 Commands_at::barleft()
84  
85 {
86     return  whole_per_measure-whole_in_measure;
87 }
88
89 /****************/
90
91 void
92 Input_cursor::find_moment(Real w)
93 {
94     Real last = when();
95     while  (1) {
96         if (! ok() ) {
97             *this = PCursor<Commands_at*>(list().bottom());
98             Real dt = (w - when()) <? ptr()->barleft();
99             assert(dt >= 0);
100             Commands_at * c = new Commands_at(dt, *this);
101             add(c);         
102         } else if (when() == w ) {
103             return ;
104         } else if (when() > w )
105             break;
106         
107         
108         last = when();
109         next();
110     }
111
112     prev();
113     Real dt = (w - when());
114     Commands_at * c = new Commands_at(dt, *this);
115     add(c);
116     next();
117 }
118
119
120
121 /****************/
122 Input_commands::Input_commands(Input_commands const&src)
123     : ptr(src.ptr)
124 {
125     IPointerList<Commands_at*> &me(*this);
126     const IPointerList<Commands_at*> &that(src);
127     
128     PL_copy(me, that);    
129 }
130
131 Input_commands::Input_commands()
132     :    ptr (bottom())
133 {
134     Commands_at * p = new Commands_at(0,0);    
135     bottom().add(p);    
136     ptr = bottom();    
137 }
138
139 void
140 Input_commands::do_skip(int bars, Real wholes)
141 {
142     while (bars > 0) {
143         Real b = ptr->barleft();
144         ptr.find_moment(ptr->when + b);
145         bars --;        
146     }
147     if (wholes) {
148         ptr.find_moment(ptr->when + wholes);
149     }
150 }
151
152
153 void
154 Input_commands::add(Input_command c)
155 {    
156     if (c.args[0] == "PARTIAL") {       
157         ptr->setpartial(c.args[1]);
158     } else if (c.args[0] == "METER") {
159         int beats_per_meas = c.args[1];
160         int one_beat = c.args[2];
161         Input_command *ch = get_meterchange_command(beats_per_meas, one_beat);
162         ptr->add(ch);           
163     } else if  (c.args[0] == "KEY" || c.args[0] == "CLEF") {
164         Input_command *ic = new Input_command(c);
165         ptr->add(ic);
166     } else if (c.args[0] == "SKIP") {
167         int bars = c.args[1] ;
168         Real wholes= c.args[2];
169         do_skip(bars, wholes);
170     } else if (c.args[0] == "RESET") {
171         ptr= top();
172     }
173     
174 }
175
176 Staff_commands*
177 Input_commands::parse() const
178 {
179     print();
180     Staff_commands*nc = new Staff_commands;
181
182     {   /* all pieces should start with a breakable. */
183         Command c(0.0);
184         c.code = INTERPRET;
185         c.args.add("BAR");
186         c.args.add("empty");
187         nc->process_add(c);
188     }
189
190     for (PCursor<Commands_at*> i(*this); i.ok(); i++)
191         for (PCursor<Input_command *> cc(**i); cc.ok(); cc++) {
192             if (cc->args.sz() &&  cc->args[0] !="") {
193                 Command c = **cc;
194                 c.when = i->when;
195                 nc->process_add(c);
196             }
197         }
198     
199     return nc;
200 }
201
202
203 void
204 Input_commands::print() const
205 {
206 #ifndef NPRINT
207     for (PCursor<Commands_at*> cc(*this); cc.ok() ; cc++) {
208         cc->print();
209     }
210 #endif
211 }
212 /****************/
213
214 Real
215 Input_cursor::when()const
216 {
217     return (*this)->when; 
218 }
219 Input_cursor::Input_cursor(PCursor<Commands_at *>c)
220     : PCursor<Commands_at*>(c)
221 {
222 }