substitute_outlet() to iterator API.
* lily/new-part-combine-iterator.cc (construct_children):
New_pc_iterator: new class, better part combining.
* lily/tie-column.cc (werner_directions): new function
* lily/parser.yy: plug many memory leaks. We're down to 4 for each
parser run.
2004-01-19 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/include/music-iterator.hh (class Music_iterator): add
+ substitute_outlet() to iterator API.
+
+ * lily/new-part-combine-iterator.cc (construct_children):
+ New_pc_iterator: new class, better part combining.
+
* lily/tie-column.cc (werner_directions): new function
* lily/tie.cc (set_direction): call Tie_column::set_direction ()
--- /dev/null
+\score {
+ \notes \relative c'' {
+
+ \newpartcombine
+ #(list
+ (cons (ly:make-moment 2 4) 'together)
+ (cons (ly:make-moment 4 4) 'apart)
+
+ ) {
+ g2 g g
+ }
+ { f f f }
+ }
+
+ \paper {
+ \translator { \VoiceContext
+ \denies Thread
+ \consists Note_heads_engraver
+ \consists Rest_engraver
+ }
+
+
+ }
+}
scm_gc_mark (child_iter_->self_scm());
}
+void
+Chord_tremolo_iterator::derived_substitute (Translator_group*f, Translator_group*t)
+{
+ if (child_iter_)
+ child_iter_->substitute_outlet (f,t);
+}
+
void
Chord_tremolo_iterator::process (Moment m)
{
if (alternative_iter_)
scm_gc_mark (alternative_iter_->self_scm());
}
+
+void
+Folded_repeat_iterator::derived_substitute (Translator_group*f, Translator_group*t)
+{
+ if (main_iter_)
+ main_iter_->substitute_outlet (f,t);
+ if (alternative_iter_)
+ alternative_iter_->substitute_outlet (f,t);
+}
+
IMPLEMENT_CTOR_CALLBACK (Folded_repeat_iterator);
Chord_tremolo_iterator ();
Chord_tremolo_iterator (Chord_tremolo_iterator const & );
protected:
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+
virtual void derived_mark () const;
virtual Moment pending_moment () const;
virtual void do_quit();
Folded_repeat_iterator (Folded_repeat_iterator const &src);
Folded_repeat_iterator ();
virtual void derived_mark () const;
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+
+
virtual void construct_children ();
virtual Moment pending_moment () const;
virtual void do_quit();
static SCM get_static_get_iterator (Music * mus);
void init_translator (Music *, Translator_group *);
void quit ();
-
-
+ void substitute_outlet (Translator_group* from, Translator_group *to);
+ virtual void derived_substitute (Translator_group*, Translator_group*);
virtual Moment pending_moment () const;
virtual bool ok () const;
virtual SCM get_pending_events (Moment until)const;
virtual void process (Moment until);
virtual void skip (Moment until);
+
virtual void derived_mark ()const;
virtual void construct_children ();
Music_wrapper_iterator ();
Music_wrapper_iterator (Music_wrapper_iterator const&);
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+
virtual void derived_mark () const;
virtual void construct_children () ;
virtual Moment pending_moment () const;
-/*
- part-combine-music-iterator.hh -- declare Part_combine_music_iterator
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2000--2003 Jan Nieuwenhuizen <janneke@gnu.org>
-
- */
-
-#ifndef PART_COMBINE_MUSIC_ITERATOR_HH
-#define PART_COMBINE_MUSIC_ITERATOR_HH
-
-#include "music-iterator.hh"
-
-class Part_combine_music_iterator : public Music_iterator
-{
-public:
- VIRTUAL_COPY_CONS (Music_iterator);
- Part_combine_music_iterator ();
-
- enum State { UNKNOWN, UNRELATED=1, SOLO1=2, SOLO2=4, UNIRHYTHM=8, UNISON=16, UNISILENCE=32, SPLIT_INTERVAL=64 };
- DECLARE_SCHEME_CALLBACK(constructor, ());
-protected:
- virtual void derived_mark () const;
- Part_combine_music_iterator (Part_combine_music_iterator const &);
- virtual void construct_children ();
- virtual Moment pending_moment () const;
- virtual void do_quit();
- virtual void process (Moment);
- virtual SCM get_pending_events (Moment)const;
- virtual Music_iterator *try_music_in_children (Music *) const;
- virtual bool ok () const;
-
-private:
- void change_to (Music_iterator*, SCM, String);
- int get_state (Moment m);
-
- Music_iterator * first_iter_;
- Music_iterator * second_iter_;
- Moment first_until_;
- Moment second_until_;
- int state_;
- String suffix_;
-};
-
-#endif /* PART_COMBINE_MUSIC_ITERATOR_HH */
-
Percent_repeat_iterator ();
Percent_repeat_iterator (Percent_repeat_iterator const & );
protected:
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+
virtual void derived_mark () const;
virtual Moment pending_moment () const;
virtual void do_quit();
DECLARE_SCHEME_CALLBACK(constructor, ());
Sequential_iterator ();
Sequential_iterator (Sequential_iterator const&);
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+
virtual void derived_mark () const;
virtual void construct_children ();
VIRTUAL_COPY_CONS (Music_iterator);
Simultaneous_music_iterator ();
Simultaneous_music_iterator (Simultaneous_music_iterator const&);
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
virtual void derived_mark () const;
DECLARE_SCHEME_CALLBACK(constructor, ());
virtual bool ok () const;
virtual void derived_mark () const;
+ virtual void derived_substitute (Translator_group*,Translator_group*) ;
private:
bool get_busy_status ()const ;
bool melisma_busy ();
scm_gc_mark (lyric_iter_->self_scm());
}
+void
+Lyric_combine_music_iterator::derived_substitute (Translator_group*f,Translator_group* t)
+{
+ if (music_iter_)
+ music_iter_->substitute_outlet (f,t);
+ if (lyric_iter_)
+ lyric_iter_->substitute_outlet (f,t);
+}
+
void
Lyric_combine_music_iterator::construct_children ()
{
set_translator (report);
}
+void
+Music_iterator::substitute_outlet (Translator_group*f, Translator_group *t)
+{
+ if (report_to () == f)
+ set_translator (t);
+ derived_substitute (f,t);
+}
+
+void
+Music_iterator::derived_substitute (Translator_group*,Translator_group*)
+{
+}
SCM
Music_iterator::get_iterator (Music *m) const
scm_gc_mark (child_iter_->self_scm());
}
+void
+Music_wrapper_iterator::derived_substitute (Translator_group*f,Translator_group*t)
+{
+
+ if (child_iter_)
+ child_iter_->substitute_outlet (f,t);
+}
void
Music_wrapper_iterator::construct_children ()
{"midi", MIDI},
{"name", NAME},
{"new", NEWCONTEXT},
+ {"newpartcombine", NEWPARTCOMBINE},
{"notes", NOTES},
{"octave", OCTAVE},
{"once", ONCE},
virtual bool run_always ()const;
virtual bool ok () const;
virtual void derived_mark () const;
+ virtual void derived_substitute (Translator_group*,Translator_group*);
private:
bool start_new_syllable () ;
void find_thread ();
scm_gc_mark (music_context_->self_scm ());
}
+void
+New_lyric_combine_music_iterator::derived_substitute (Translator_group*f, Translator_group*t)
+{
+ if (lyric_iter_)
+ lyric_iter_->substitute_outlet (f,t);
+ if (lyrics_context_ && lyrics_context_==f)
+ lyrics_context_ = t;
+ if (music_context_ && music_context_ == f)
+ music_context_ = t;
+}
+
/*
ID == "" means accept any ID.
*/
--- /dev/null
+/*
+ part-combine-music-iterator.cc -- implement New_pc_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000--2003 Jan Nieuwenhuizen <janneke@gnu.org>
+ */
+
+#include "part-combine-music-iterator.hh"
+#include "translator-group.hh"
+#include "event.hh"
+#include "music-sequence.hh"
+#include "lily-guile.hh"
+#include "warn.hh"
+#include "music-iterator.hh"
+#include "interpretation-context-handle.hh"
+
+class New_pc_iterator : public Music_iterator
+{
+public:
+ VIRTUAL_COPY_CONS (Music_iterator);
+ New_pc_iterator ();
+
+ DECLARE_SCHEME_CALLBACK(constructor, ());
+protected:
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+ virtual void derived_mark () const;
+ New_pc_iterator (New_pc_iterator const &);
+
+ virtual void construct_children ();
+ virtual Moment pending_moment () const;
+ virtual void do_quit();
+ virtual void process (Moment);
+
+ virtual SCM get_pending_events (Moment)const;
+ virtual Music_iterator *try_music_in_children (Music *) const;
+
+ virtual bool ok () const;
+
+private:
+ Music_iterator * first_iter_;
+ Music_iterator * second_iter_;
+ bool is_shared_ ;
+ SCM split_list_;
+
+ Interpretation_context_handle one_;
+ Interpretation_context_handle two_;
+ Interpretation_context_handle shared_;
+
+ void together ();
+ void apart ();
+};
+
+
+New_pc_iterator::New_pc_iterator ()
+{
+ is_shared_ =false;
+ first_iter_ = 0;
+ second_iter_ = 0;
+ split_list_ = SCM_EOL;
+}
+
+void
+New_pc_iterator::derived_mark () const
+{
+ if (first_iter_)
+ scm_gc_mark (first_iter_->self_scm());
+ if (second_iter_)
+ scm_gc_mark(second_iter_->self_scm());
+}
+
+void
+New_pc_iterator::derived_substitute (Translator_group*f,
+ Translator_group*t)
+{
+ if (first_iter_)
+ first_iter_->substitute_outlet (f,t);
+ if (second_iter_)
+ second_iter_->substitute_outlet (f,t);
+}
+
+void
+New_pc_iterator::do_quit ()
+{
+ if (first_iter_)
+ first_iter_->quit();
+ if (second_iter_)
+ second_iter_->quit();
+
+ one_ .set_translator (0);
+ two_.set_translator (0);
+ shared_.set_translator (0);
+}
+
+New_pc_iterator::New_pc_iterator (New_pc_iterator const &src)
+ : Music_iterator (src)
+{
+ first_iter_ = 0;
+ second_iter_ = 0;
+
+ if(src.first_iter_)
+ first_iter_ = src.first_iter_->clone ();
+ if (src.second_iter_)
+ second_iter_ = src.second_iter_->clone ();
+
+ split_list_ = src.split_list_;
+
+ if (first_iter_)
+ scm_gc_unprotect_object (first_iter_->self_scm());
+ if (second_iter_)
+ scm_gc_unprotect_object (second_iter_->self_scm());
+}
+
+Moment
+New_pc_iterator::pending_moment () const
+{
+ Moment p;
+ p.set_infinite (1);
+ if (first_iter_->ok ())
+ p = p <? first_iter_->pending_moment ();
+
+ if (second_iter_->ok ())
+ p = p <? second_iter_->pending_moment ();
+ return p;
+}
+
+bool
+New_pc_iterator::ok () const
+{
+ return first_iter_->ok () || second_iter_->ok ();
+}
+
+void
+New_pc_iterator::together ()
+{
+ first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+ second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+}
+
+void
+New_pc_iterator::apart ()
+{
+ first_iter_->substitute_outlet (shared_.report_to (),one_.report_to ());
+ second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ());
+}
+
+
+void
+New_pc_iterator::construct_children ()
+{
+ split_list_ = get_music ()->get_mus_property ("split-list");
+ SCM lst = get_music ()->get_mus_property ("elements");
+
+ Translator_group *tr
+ = report_to ()->find_create_translator (ly_symbol2scm ("Voice"),
+ "shared", SCM_EOL);
+
+ tr->execute_pushpop_property (ly_symbol2scm ("NoteHead"),
+ ly_symbol2scm ("font-size"), gh_int2scm (3));
+
+
+ shared_ .set_translator (tr);
+ set_translator (tr);
+
+ Translator_group *one = tr->find_create_translator (ly_symbol2scm ("Voice"),
+ "one", SCM_EOL);
+
+ one_.set_translator (one);
+ one->execute_pushpop_property (ly_symbol2scm ("Stem"),
+ ly_symbol2scm ("direction"), gh_int2scm (1));
+
+ set_translator (one);
+ first_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_car (lst))));
+
+
+ Translator_group *two = tr->find_create_translator (ly_symbol2scm ("Voice"),
+ "two", SCM_EOL);
+ two_.set_translator (two);
+ two_.report_to ()->execute_pushpop_property (ly_symbol2scm ("Stem"),
+ ly_symbol2scm ("direction"), gh_int2scm (-1));
+ set_translator (two);
+ second_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_cadr (lst))));
+
+
+ set_translator (tr);
+}
+
+void
+New_pc_iterator::process (Moment m)
+{
+ Moment now = report_to ()->now_mom ();
+ Moment *splitm = 0;
+
+ for (; gh_pair_p (split_list_); split_list_ = gh_cdr (split_list_))
+ {
+ splitm = unsmob_moment (gh_caar (split_list_));
+ if (*splitm > now)
+ break ;
+
+ if (gh_cdar (split_list_) == ly_symbol2scm ("together"))
+ together ();
+ else if (gh_cdar (split_list_) == ly_symbol2scm ("apart"))
+ apart ();
+ else
+ programming_error ("Unknown split directive.");
+ }
+
+ if (first_iter_->ok ())
+ first_iter_->process (m);
+
+ if (second_iter_->ok ())
+ second_iter_->process (m);
+}
+
+Music_iterator*
+New_pc_iterator::try_music_in_children (Music *m) const
+{
+ Music_iterator * i = first_iter_->try_music (m);
+ if (i)
+ return i;
+ else
+ return second_iter_->try_music (m);
+}
+
+
+SCM
+New_pc_iterator::get_pending_events (Moment m)const
+{
+ SCM s = SCM_EOL;
+ if (first_iter_)
+ s = gh_append2 (s,first_iter_->get_pending_events (m));
+ if (second_iter_)
+ s = gh_append2 (second_iter_->get_pending_events (m),s);
+ return s;
+}
+
+IMPLEMENT_CTOR_CALLBACK (New_pc_iterator);
%token OVERRIDE SET REVERT
%token PAPER
%token PARTCOMBINE
+%token NEWPARTCOMBINE
%token PARTIAL
%token PITCHNAMES
%token PROPERTY
;
-
identifier_init:
score_block {
$$ = $1->self_scm ();
$$ = p;
}
+ | NEWPARTCOMBINE embedded_scm Music Music {
+ Music * p= MY_MAKE_MUSIC("NewPartCombineMusic");
+ p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED));
+ p->set_mus_property ("split-list", $2);
+ scm_gc_unprotect_object ($3->self_scm ());
+ scm_gc_unprotect_object ($4->self_scm ());
+
+ $$ = p;
+ }
;
context_change:
#include "music-sequence.hh"
#include "lily-guile.hh"
#include "warn.hh"
+#include "music-iterator.hh"
+
+class Part_combine_music_iterator : public Music_iterator
+{
+public:
+ VIRTUAL_COPY_CONS (Music_iterator);
+ Part_combine_music_iterator ();
+
+ enum State { UNKNOWN, UNRELATED=1, SOLO1=2, SOLO2=4, UNIRHYTHM=8, UNISON=16, UNISILENCE=32, SPLIT_INTERVAL=64 };
+ DECLARE_SCHEME_CALLBACK(constructor, ());
+protected:
+ virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
+
+ virtual void derived_mark () const;
+ Part_combine_music_iterator (Part_combine_music_iterator const &);
+ virtual void construct_children ();
+ virtual Moment pending_moment () const;
+ virtual void do_quit();
+ virtual void process (Moment);
+ virtual SCM get_pending_events (Moment)const;
+ virtual Music_iterator *try_music_in_children (Music *) const;
+ virtual bool ok () const;
+
+private:
+ void change_to (Music_iterator*, SCM, String);
+ int get_state (Moment m);
+
+ Music_iterator * first_iter_;
+ Music_iterator * second_iter_;
+ Moment first_until_;
+ Moment second_until_;
+ int state_;
+ String suffix_;
+};
+
Part_combine_music_iterator::Part_combine_music_iterator ()
{
scm_gc_mark(second_iter_->self_scm());
}
+void
+Part_combine_music_iterator::derived_substitute (Translator_group*f,
+ Translator_group*t)
+{
+ if (first_iter_)
+ first_iter_->substitute_outlet (f,t);
+ if (second_iter_)
+ second_iter_->substitute_outlet (f,t);
+}
+
void
Part_combine_music_iterator::do_quit ()
{
if (child_iter_)
scm_gc_mark (child_iter_->self_scm());
}
+
+void
+Percent_repeat_iterator::derived_substitute(Translator_group*f,Translator_group*t )
+{
+ if (child_iter_)
+ child_iter_->substitute_outlet (f,t);
+}
}
+void
+Sequential_iterator::derived_substitute (Translator_group*f,Translator_group*t)
+{
+ if (iter_)
+ iter_->substitute_outlet (f,t);
+
+}
+
Grace_fixup *
get_grace_fixups (SCM cursor)
{
scm_gc_mark (children_list_);
}
+void
+Simultaneous_music_iterator::derived_substitute(Translator_group*f,Translator_group*t)
+{
+ for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
+ unsmob_iterator (gh_car (s))-> substitute_outlet (f,t);
+}
+
SCM
Simultaneous_music_iterator::get_pending_events (Moment m)const
{
/*
tie dir depends on what Tie_column does.
*/
-
+/*
+ TODO: this doesn't follow standard pattern. Regularize.
+ */
void
Tie_column::add_tie (Grob*me,Grob *s)
{
{
werner_directions (me);
}
-
-
int
tie_compare (Grob* const & s1,
for (int i = ties.size (); i--;)
if (get_grob_direction (ties[i]))
ties.del (i);
-
if (!ties.size ())
return ;
-
Direction d = get_grob_direction (me);
if (d)
(types . (general-music part-combine-music))
(iterator-ctor . ,Part_combine_music_iterator::constructor)
))
+ (NewPartCombineMusic
+ . (
+ (description . "Combine two parts on a staff, either merged or
+as separate voices.")
+
+ (internal-class-name . "Simultaneous_music")
+ (types . (general-music part-combine-music))
+ (iterator-ctor . ,New_pc_iterator::constructor)
+ ))
(PhrasingSlurEvent
. (