]> git.donarmstrong.com Git - lilypond.git/blobdiff - src/inputcommands.cc
release: 0.0.17
[lilypond.git] / src / inputcommands.cc
index 457fb9a57d116e9fb3b78a585e9e69276204c7a1..c7f7aaff5632c5c1e58e880c1a165ba0fd9d8685 100644 (file)
 #include "getcommand.hh"
 #include "command.hh"
 
-Input_commands::Input_commands(Input_commands const&src)
-    : ptr(src.ptr)
+void
+Commands_at::print() const
 {
-    IPointerList<Input_command*> &me(*this);
-    const IPointerList<Input_command*> &that(src);
-    
-    PL_copy(me, that);    
+#ifndef NPRINT
+    mtor << "{ at "<<when<<'\n'; 
+    mtor << "meter " << whole_per_measure
+        << " pos "<< bars << ":" << whole_in_measure <<'\n';
+    for (PCursor<Input_command *> cc(*this); cc.ok(); cc++) 
+       cc->print();
+    mtor << "}\n";
+#endif
 }
 
-Input_commands::Input_commands()
-    :    ptr (bottom())
+Commands_at::Commands_at(Real dt, Commands_at* prev)
 {
-    Input_command c(0.0);              
-    bottom().add(new Input_command(c));    
-    ptr = bottom();    
+    if (prev) {
+       assert(dt >0);
+       when = prev->when + dt;
+       whole_per_measure = prev->whole_per_measure;
+       whole_in_measure = prev->whole_in_measure + dt;
+       bars = prev->bars;
+
+       while ( whole_in_measure >= whole_per_measure ) {
+           whole_in_measure -= whole_per_measure;
+           bars ++;
+       }
+       if (!whole_in_measure) {
+           bottom().add(get_bar_command());
+       }
+    } else {
+       whole_per_measure = 1;
+       whole_in_measure =0;
+       when = 0.0;
+       bars = 0;
+    }
 }
 
 void
-Input_commands::truncate(Real last)
+Commands_at::add(Input_command *i )
+{
+    bottom().add(i);           
+    if (i->args[0] == "METER") { // should check for other meterchanges here.
+       Real l = i->args[1];
+       Real o = i->args[2];
+       whole_per_measure = l/o;                
+    }
+}
+
+Commands_at::Commands_at(Commands_at const&src)
 {
-    bool reset_ = false;
+    when = src.when;
+    whole_in_measure = whole_in_measure;
+    whole_per_measure = whole_per_measure;
+    bars = src.bars;
     
-    if (ptr.when() >= last)
-       reset_=true;
-    PCursor<Input_command*> i(*this);
+    IPointerList<Input_command*> &me(*this);
+    const IPointerList<Input_command*> &that(src);
     
-    while (i.ok() && i ->when < last)
-       i++;
+    PL_copy(me, that);
+}
 
-    while (i.ok())
-       i.del();
+void
+Commands_at::setpartial(Real p)
+{
+    if (when)
+       error_t ("Partial measure only allowed at beginning.", when);
+    if (p<0||p > whole_per_measure)
+       error_t ("Partial measure has incorrect size", when);
+    whole_in_measure = whole_per_measure - p;
+}
+Real
+Commands_at::barleft()
+{
+    return  whole_per_measure-whole_in_measure;
+}
 
-    if (reset_) {
-       reset();
+/****************/
+
+void
+Input_cursor::find_moment(Real w)
+{
+    Real last = when();
+    while  (1) {
+       if (! ok() ) {
+           *this = PCursor<Commands_at*>(list().bottom());
+           Real dt = (w - when()) <? ptr()->barleft();
+           assert(dt >= 0);
+           Commands_at * c = new Commands_at(dt, *this);
+           add(c);         
+       } else if (when() == w ) {
+           return ;
+       } else if (when() > w )
+           break;
+       
        
-       while(ptr.ok())
-           ptr++;      
+       last = when();
+       next();
     }
+
+    prev();
+    Real dt = (w - when());
+    Commands_at * c = new Commands_at(dt, *this);
+    add(c);
+    next();
 }
 
-/*
-  ugh. This sux.
-  */
-void
-Input_commands::find_moment(Real w)
+
+
+/****************/
+Input_commands::Input_commands(Input_commands const&src)
+    : ptr(src.ptr)
 {
-    assert(w >= ptr.when());
-    while (ptr.ok() && ptr.when() < w) {
-       ptr++;
-    }
+    IPointerList<Commands_at*> &me(*this);
+    const IPointerList<Commands_at*> &that(src);
     
-    if (!ptr.ok()) {
-       int bars_left =int(floor( (w - ptr.last + ptr.whole_in_measure)
-                                 /ptr.whole_per_measure));
-       if (bars_left) {
-           Real bar_when = ptr.last - ptr.whole_in_measure + ptr.whole_per_measure;
-           ptr.addbot(get_bar_command(bar_when));
-           find_moment(w);     // tail-recursion. todo
-       } else {
-           ptr.addbot(new Input_command(w));
-       }
+    PL_copy(me, that);    
+}
 
-    } else if (ptr.when() != w) {
-       ptr.insert(new Input_command(w));
-       ptr--;  
-    }
+Input_commands::Input_commands()
+    :    ptr (bottom())
+{
+    Commands_at * p = new Commands_at(0,0);    
+    bottom().add(p);    
+    ptr = bottom();    
 }
 
 void
-Input_commands::do_skip(int & bars, Real & wholes)
+Input_commands::do_skip(int bars, Real wholes)
 {
-    if (wholes) {
-       find_moment(ptr.when() +wholes);
-       wholes = 0.0;   
+    while (bars > 0) {
+       Real b = ptr->barleft();
+       ptr.find_moment(ptr->when + b);
+       bars --;        
     }
-
-    if (bars) {
-       ptr.last_command_here(); // find any METER change commands.
-       if (ptr.whole_in_measure){
-           Real barleft = ptr.whole_per_measure - ptr.whole_in_measure;
-           do_skip(bars, barleft);
-       }else {
-           find_moment(ptr.when() + bars*ptr.whole_per_measure);
-           bars = 0;
-       }
+    if (wholes) {
+       ptr.find_moment(ptr->when + wholes);
     }
 }
 
@@ -101,46 +153,30 @@ Input_commands::do_skip(int & bars, Real & wholes)
 void
 Input_commands::add(Input_command c)
 {    
-    if (c.args[0] == "PARTIAL") {
-       Real p = c.args[1].fvalue();
-       ptr.setpartial(p);
-       
+    if (c.args[0] == "PARTIAL") {      
+       ptr->setpartial(c.args[1]);
     } else if (c.args[0] == "METER") {
-       int beats_per_meas, one_beat;
-       Real r;
-       
-       interpret_meter(&c, beats_per_meas, one_beat, r);
+       int beats_per_meas = c.args[1];
+       int one_beat = c.args[2];
        Input_command *ch = get_meterchange_command(beats_per_meas, one_beat);
-       ch->when = ptr.when();  
-       ptr.add(ch);
-               
+       ptr->add(ch);           
     } else if  (c.args[0] == "KEY" || c.args[0] == "CLEF") {
        Input_command *ic = new Input_command(c);
-       ic->when = ptr.when();
-       ptr.add(ic);
+       ptr->add(ic);
     } else if (c.args[0] == "SKIP") {
-       int bars = c.args[1].value() ;
-       Real wholes= c.args[2].fvalue();
-       while (bars > 0 || wholes > 0.0) {
-           do_skip(bars, wholes);
-       }
+       int bars = c.args[1] ;
+       Real wholes= c.args[2];
+       do_skip(bars, wholes);
     } else if (c.args[0] == "RESET") {
-       reset();        
+       ptr= top();
     }
     
 }
 
-void
-Input_commands::reset()
-{
-    ptr = top();
-    ptr.reset();
-}
-
-
 Staff_commands*
 Input_commands::parse() const
 {
+    print();
     Staff_commands*nc = new Staff_commands;
 
     {   /* all pieces should start with a breakable. */
@@ -151,10 +187,14 @@ Input_commands::parse() const
        nc->process_add(c);
     }
 
-    for (PCursor<Input_command*> cc(*this); cc.ok(); cc++) {
-       if (cc->args.sz() &&  cc->args[0] !="")
-           nc->process_add(**cc);
-    }
+    for (PCursor<Commands_at*> i(*this); i.ok(); i++)
+       for (PCursor<Input_command *> cc(**i); cc.ok(); cc++) {
+           if (cc->args.sz() &&  cc->args[0] !="") {
+               Command c = **cc;
+               c.when = i->when;
+               nc->process_add(c);
+           }
+       }
     
     return nc;
 }
@@ -164,9 +204,19 @@ void
 Input_commands::print() const
 {
 #ifndef NPRINT
-    for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
+    for (PCursor<Commands_at*> cc(*this); cc.ok() ; cc++) {
        cc->print();
     }
-    ptr.print();
 #endif
 }
+/****************/
+
+Real
+Input_cursor::when()const
+{
+    return (*this)->when; 
+}
+Input_cursor::Input_cursor(PCursor<Commands_at *>c)
+    : PCursor<Commands_at*>(c)
+{
+}