summaryrefslogtreecommitdiff
path: root/scommands.cc
diff options
context:
space:
mode:
Diffstat (limited to 'scommands.cc')
-rw-r--r--scommands.cc116
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;
+}