]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-0.0.9
authorfred <fred>
Fri, 8 Nov 1996 13:35:04 +0000 (13:35 +0000)
committerfred <fred>
Fri, 8 Nov 1996 13:35:04 +0000 (13:35 +0000)
hdr/staff.hh [new file with mode: 0644]
src/staff.cc [new file with mode: 0644]

diff --git a/hdr/staff.hh b/hdr/staff.hh
new file mode 100644 (file)
index 0000000..ee95864
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef STAFF_HH
+#define STAFF_HH
+
+#include "score.hh"
+#include "voice.hh"
+#include "command.hh"
+
+
+/// base class for a collection of voices.
+struct Staff {
+    /// synchronous horizontal stuff
+    PointerList<Voice*> voices;
+
+    /// commands in chronological order
+    PointerList<Command *> commands;
+
+    /// runtime field
+    PointerList<Staff_column*> cols;
+
+    /// indirections to the Score and PScore
+    Score *score_;
+    PScore *pscore_;
+
+    /****************************************************************/
+    Staff(const Staff&src);
+    void add_voice(Voice *v);
+    void add_staff_column(Staff_column *sp);
+
+    Paperdef*paper()const;
+    /// interpret all requests and add items to #destination#.
+    void process();
+    /**
+    This routines calls virtual functions from Staff, to delegate the
+    interpretation of requests to a derived class of Staff */
+    void setup_staffcols();
+
+    void OK() const;
+    void print() const;
+    Real last() const;
+    void clean_cols() ;
+    Staff_column * get_col(Real,bool);
+
+    void add_commands(PointerList<Command* >const & sv);
+    /**
+    add all commands from sv.
+
+    PRE
+    sv is time-ordered.
+    */
+
+    Staff();
+    /**
+      Should construct with Score as arg, but this isn't known during parsing.      
+      */
+    /****************************************************************
+      VIRTUALS
+    ****************************************************************/
+    virtual Staff*clone()const=0;    
+    virtual void set_output(PScore * destination)=0;
+    virtual void walk()=0;    
+    virtual Staff_column * create_col(Score_column * )=0;
+    virtual ~Staff() { }
+};
+#endif
+
+
diff --git a/src/staff.cc b/src/staff.cc
new file mode 100644 (file)
index 0000000..3a32801
--- /dev/null
@@ -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;    
+}