1 #include "scommands.hh"
3 #include "parseconstruct.hh"
6 maybe it's time for a "narrowing" cursor?
9 Score_commands::first(Real w)
11 PCursor<Command*> pc(*this);
12 while (pc.ok() && pc->when < w)
19 Score_commands::last_insertion(Real w)
21 PCursor<Command*> pc(*this);
22 while (pc.ok() && pc->when <= w)
28 Score_commands::add_seq(svec<Command> com)
32 Real when = com[0].when;
34 PCursor<Command*> pc(last_insertion(when));
35 for (int i = 0; i < com.sz(); i++) {
36 Command *c = new Command(com[i]);
37 assert(com[i].when == when);
46 Score_commands::set_breakable(Real when)
48 bool found_typeset(false);
49 PCursor<Command*> cc = first(when);
50 for (; cc.ok() && cc->when == when; cc++) {
53 if (cc->code == TYPESET)
57 assert(!found_typeset);
63 k.code = BREAK_MIDDLE;
73 Score_commands::is_breakable(Real w)
75 PCursor<Command*> cc = first(w);
76 for (; cc.ok() && cc->when == w; cc++) {
84 Score_commands::insert_between(Command victim, PCursor<Command*> firstc,
85 PCursor<Command*> last)
87 assert(last->when==firstc->when);
88 PCursor<Command*> c(firstc+1);
89 while (c != last) { // hmm what if !last.ok()?
90 if (victim.priority > c->priority) {
91 c.insert(new Command(victim));
96 last.insert(new Command(victim));
100 Score_commands::add_command_to_break(Command pre, Command mid,Command post)
103 PCursor<Command*> c ( first(w)), f(c), l(c);
105 while (!c->isbreak())
108 while (!c->isbreak())
112 insert_between(pre, f, l);
114 while (!c->isbreak())
117 insert_between(mid, f, l);
119 while (!c->isbreak())
122 insert_between(post, f, l);
123 assert(l.ok() && l->when ==w && l->code == BREAK_END);
127 Score_commands::parser_add(Command *c)
133 Score_commands::process_add(Command c)
135 bool encapsulate =false;
142 if (c.code == TYPESET) {
143 if (c.args[0] == "BAR") {
149 if (c.args[0] == "METER" && is_breakable(w)) {
158 add_command_to_break(pre, mid, post);
167 first and last column should be breakable.
168 Remove any command past the last musical column.
171 Score_commands::clean(Real l)
174 if (!is_breakable(0.0)) {
182 PCursor<Command*> bot(bottom());
184 while (bot.ok() && bot->when > l) {
191 if (!is_breakable(l)) {
202 Score_commands::OK() const
204 for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
205 assert(cc->when <= (cc+1)->when);
206 if (cc->when == (cc+1)->when && !cc->isbreak() && !(cc+1)->isbreak())
207 assert(cc->priority >= (cc+1)->priority);
212 Score_commands::print() const
214 for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
220 Score_commands::parse(Real l) const
222 Score_commands*nc = new Score_commands;
223 int beats_per_meas=4;
224 Real measlen = 1.0; // 4/4 by default
238 for (PCursor<Command*> cc(*this); cc.ok() && cc->when <= l; cc++) {
239 assert (cc->code==INTERPRET);
240 if (cc->args[0] == "METER") {
241 beats_per_meas=cc->args[1].value();
242 int one_beat =cc->args[2].value ();
243 measlen = beats_per_meas/Real(one_beat);
244 nc->process_add(*get_meter_command(wholes,beats_per_meas, one_beat));
246 if (cc->args[0] == "SKIP") {
247 stoppos = wholes + cc->args[1].value() * measlen + cc->args[2].fvalue();
248 wholes += (measlen-inbar); // skip at least 1 measure
250 while (wholes <= stoppos) {
251 nc->process_add(*get_bar_command(wholes)); // liek