diff options
Diffstat (limited to 'scommands.cc')
-rw-r--r-- | scommands.cc | 116 |
1 files changed, 96 insertions, 20 deletions
diff --git a/scommands.cc b/scommands.cc index 82fe9a1691..8f86ff6fad 100644 --- a/scommands.cc +++ b/scommands.cc @@ -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; +} |