]> git.donarmstrong.com Git - lilypond.git/blobdiff - scommands.cc
release: 0.0.5
[lilypond.git] / scommands.cc
index 82fe9a169100ddaba1d6674818a32fbbc640c0fa..8f86ff6fad47e5e5fb3b620b8ebf382796794495 100644 (file)
@@ -1,5 +1,6 @@
 #include "scommands.hh"
 #include "debug.hh"
+#include "parseconstruct.hh"
 
 /*
   maybe it's time for a "narrowing" cursor?
@@ -78,45 +79,74 @@ Score_commands::is_breakable(Real w)
     }
     return false;
 }
+
+void
+Score_commands::insert_between(Command victim, PCursor<Command*> firstc,
+                              PCursor<Command*> last)
+{
+    assert(last->when==firstc->when);
+    PCursor<Command*> c(firstc+1);
+    while (c != last) {        // hmm what if !last.ok()?
+       if (victim.priority > c->priority) {
+           c.insert(new Command(victim));
+           return;
+       }
+       c++;
+    }
+    last.insert(new Command(victim));    
+    
+}
 void
 Score_commands::add_command_to_break(Command pre, Command mid,Command post)
 {
     Real w = pre.when;
-    
-    Command k(w);
-    
-    PCursor<Command*> c ( first(w));
+    PCursor<Command*> c ( first(w)), f(c), l(c);
+
     while (!c->isbreak())
        c++;
-    c.add(new Command(pre));
-
+    f = c++;
     while (!c->isbreak())
        c++;
-    c.add(new Command(mid));
-
+    l = c++;
+    
+    insert_between(pre, f, l);
+    f = l;
     while (!c->isbreak())
        c++;
-    c.add(new Command(post));
+    l = c++;    
+    insert_between(mid, f, l);
+    f = l;
+    while (!c->isbreak())
+       c++;
+    l = c++;    
+    insert_between(post, f, l);
+    assert(l.ok() && l->when ==w && l->code == BREAK_END);
 }
 
 void
-Score_commands::add(Command c)
+Score_commands::parser_add(Command *c)
 {
-    bool encapsulate =false;
+    bottom().add(c);
+}
 
-    Command pre(c.when);
-    Command mid(c.when);
-    Command post(c.when);
+void
+Score_commands::process_add(Command c)
+{
+    bool encapsulate =false;
+    Real w = c.when;
+    Command pre(w);
+    Command mid(w);
+    Command post(w);
 
 
     if (c.code == TYPESET) {
        if (c.args[0] == "BAR") {
-           set_breakable(c.when);
+           set_breakable(w);
            encapsulate  = true;
            mid = c;
            pre = c;
        }
-       if (c.args[0] == "METER" && is_breakable(c.when)) {
+       if (c.args[0] == "METER" && is_breakable(w)) {
            encapsulate = true;
            mid = c;
            pre = c;
@@ -146,14 +176,14 @@ Score_commands::clean(Real l)
        c.code = TYPESET;
        c.args.add("BAR");
        c.args.add("empty");
-       add(c);
+       process_add(c);
     }
     
     PCursor<Command*> bot(bottom());
 
     while (bot.ok() && bot->when > l) {
-
-       mtor <<"removing "<< bot->code <<" at " << bot->when<<'\n';
+       mtor <<"removing ";
+       bot->print();
        bot.del();
        bot = bottom();
     }
@@ -163,7 +193,7 @@ Score_commands::clean(Real l)
        c.code = TYPESET;
        c.args.add("BAR");
        c.args.add("||");
-       add(c);
+       process_add(c);
     }
     OK();
 }
@@ -173,6 +203,8 @@ Score_commands::OK() const
 {
     for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
        assert(cc->when <= (cc+1)->when);
+       if (cc->when == (cc+1)->when && !cc->isbreak() && !(cc+1)->isbreak())
+           assert(cc->priority >= (cc+1)->priority);
     }
 }
 
@@ -183,3 +215,47 @@ Score_commands::print() const
        cc->print();
     }
 }
+
+Score_commands*
+Score_commands::parse(Real l) const
+{
+    Score_commands*nc = new Score_commands;
+    int beats_per_meas=4;
+    Real measlen = 1.0; // 4/4 by default
+    
+    Real inbar=0.0;
+    int barcount=0;
+    Real wholes=0.0;
+    Real stoppos=0.0;
+
+    {
+       Command c(0.0);
+       c.code = TYPESET;
+       c.args.add("BAR");
+       c.args.add("empty");
+       nc->process_add(c);
+    }
+    for (PCursor<Command*> cc(*this); cc.ok() && cc->when <= l; cc++) {
+       assert (cc->code==INTERPRET);
+       if (cc->args[0] == "METER") {
+           beats_per_meas=cc->args[1].value();
+           int one_beat =cc->args[2].value ();
+           measlen = beats_per_meas/Real(one_beat);
+           nc->process_add(*get_meter_command(wholes,beats_per_meas, one_beat));
+       }
+       if (cc->args[0] == "SKIP") {
+           stoppos = wholes + cc->args[1].value() * measlen + cc->args[2].fvalue();
+           wholes += (measlen-inbar); // skip at least 1 measure
+           barcount++;
+           while (wholes <= stoppos) {
+               nc->process_add(*get_bar_command(wholes)); // liek
+               wholes += measlen;
+               barcount ++;            
+           }
+           wholes = stoppos;
+           //something
+       }
+    }
+    
+    return nc;
+}