summaryrefslogtreecommitdiff
path: root/src/staff.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/staff.cc')
-rw-r--r--src/staff.cc172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/staff.cc b/src/staff.cc
new file mode 100644
index 0000000000..3a32801b2f
--- /dev/null
+++ b/src/staff.cc
@@ -0,0 +1,172 @@
+#include "staff.hh"
+#include "swalker.hh"
+#include "stcol.hh"
+#include "sccol.hh"
+#include "debug.hh"
+
+Staff::Staff(Staff const&src)
+{
+ PL_copy(voices,src.voices);
+ PL_copy(commands,src.commands);
+ assert(!cols.size()); // cols is a runtime field.
+
+ score_ = src.score_;
+ pscore_ = src.pscore_;
+}
+
+Paperdef*
+Staff::paper() const{
+ return score_->paper_;
+}
+
+void
+Staff::clean_cols()
+{
+ PCursor<Staff_column *> stc(cols);
+ for(; stc.ok(); ){
+ if (!stc->score_column->used())
+ stc.del();
+ else
+ stc++;
+ }
+}
+
+Staff_column *
+Staff::get_col(Real w, bool mus)
+{
+ Score_column* sc = score_->find_col(w,mus);
+ assert(sc->when == w);
+ PCursor<Staff_column *> stc(cols);
+ for (; stc.ok(); stc++) {
+ if (*stc->score_column > *sc) // too far
+ break;
+ if (sc == stc->score_column)
+ return stc;
+ }
+ Staff_column* newst = create_col(sc);
+
+ if (!stc.ok()) {
+ cols.bottom().add(newst);
+ return cols.bottom();
+ }
+
+ if (mus) {
+ stc.insert(newst);
+ return newst;
+ }
+
+ if ((stc-1)->when() == newst->when()) {
+ stc--;
+ }
+
+ stc.insert(newst);
+
+ return newst;
+}
+
+
+void
+Staff::add_voice(Voice *v)
+{
+ voices.bottom().add(v);
+}
+
+/*
+ put all stuff grouped vertically in the Staff_cols
+ */
+void
+Staff::setup_staffcols()
+{
+
+ for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
+
+ Real now = vc->start;
+ for (PCursor<Voice_element *> ve(vc->elts); ve.ok(); ve++) {
+
+ Staff_column *sc=get_col(now,true);
+ sc->add(ve);
+ now += ve->duration;
+ }
+ }
+
+ for (PCursor<Command*> cc(commands); cc.ok(); cc++) {
+ Staff_column *sc=get_col(cc->when,false);
+ sc->s_commands.add(cc);
+ }
+}
+
+/// merge commands from score
+void
+Staff::add_commands(PointerList<Command*> const &cl)
+{
+ PCursor<Command*> score_c(cl);
+ PCursor<Command*> cc(commands);
+
+ while (score_c.ok()) {
+ while (cc.ok() && cc->when <= score_c->when)
+ cc++;
+
+ Command*nc = new Command (*(* score_c));
+ if (cc.ok()) {
+ // cc->when > score_c->when
+ cc.insert( nc );
+ } else {
+ commands.bottom().add( nc);
+ cc = commands.bottom();
+ }
+ score_c++;
+ }
+
+ // now integrate break commands with other commands.
+ // maybe do this in derived functions.
+}
+
+void
+Staff::process()
+{
+ setup_staffcols();
+ OK();
+ walk();
+}
+
+void
+Staff::OK() const
+{
+#ifndef NDEBUG
+ cols.OK();
+ commands.OK();
+ voices.OK();
+ assert(score_);
+#endif
+}
+
+
+Real
+Staff::last() const
+{
+ Real l = 0.0;
+ for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
+ l = MAX(l, vc->last());
+ }
+ return l;
+}
+
+
+void
+Staff::print() const
+{
+#ifndef NPRINT
+ mtor << "Staff {\n";
+ for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
+ vc->print();
+
+ }
+ mtor <<"}\n";
+#endif
+}
+
+Staff::Staff()
+{
+ score_ =0;
+ pscore_=0;
+}