/*
- unfolded-repeat-iterator.cc -- implement Unfolded_repeat_iterator
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
+unfolded-repeat-iterator.cc -- implement Unfolded_repeat_iterator, Volta_repeat_iterator
+source file of the GNU LilyPond music typesetter
-#include "repeated-music.hh"
-#include "music-list.hh"
-#include "unfolded-repeat-iterator.hh"
-#include "debug.hh"
-#include "translator-group.hh"
-Unfolded_repeat_iterator::~Unfolded_repeat_iterator ()
-{
- delete current_iter_p_;
-}
+(c) 2002--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
-Unfolded_repeat_iterator::Unfolded_repeat_iterator ()
-{
- done_count_ =0;
- current_iter_p_ =0;
- do_main_b_ = false;
- alternative_count_i_ =0;
-}
-/**
-
-If we are in the body of the repeat always go to the current alternative.
+#include "music.hh"
+#include "sequential-iterator.hh"
+#include "translator-group.hh"
-If we are not in the body, then we are in an alternative. If we are
-fully unfolding, advance the current alternative and go back to main.
-If we are semi-unfolding, advance the current alternative, and go to
-the alternative just set.
-
- */
-void
-Unfolded_repeat_iterator::next_element ()
+class Unfolded_repeat_iterator : public Sequential_iterator
{
- Repeated_music const* mus =dynamic_cast<Repeated_music const*> (music_l_);
- delete current_iter_p_;
- current_iter_p_ =0;
+public:
+ DECLARE_SCHEME_CALLBACK(constructor, ());
+protected:
+ virtual SCM get_music_list () const;
+};
- if (do_main_b_)
- {
- done_mom_ += mus->repeat_body_p_->length_mom ();
+SCM
+Unfolded_repeat_iterator::get_music_list () const
+{
+ SCM l = SCM_EOL;
+ SCM *tail = &l;
+
+ SCM body = get_music ()->get_mus_property ("element");
+ SCM alts = get_music ()->get_mus_property ("elements");
+ int alt_count = scm_ilength (alts);
+ int rep_count = gh_scm2int (get_music ()->get_mus_property ("repeat-count"));
- if (full_unfold_b_)
- done_count_ ++;
-
- if (alternative_cons_l_)
- {
- current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
- do_main_b_ = false;
- }
- else if (done_count_ < mus->repeats_i_ && full_unfold_b_)
- {
- current_iter_p_ = get_iterator_p (mus->repeat_body_p_);
- do_main_b_ = true;
- }
- }
- else
+ for (int i = 0; i < rep_count; i++)
{
- /*
- we're not in the main part. So we're either in an alternative, or
- we just finished.
- */
- if (alternative_cons_l_)
- {
- done_mom_ += alternative_cons_l_->car_->length_mom ();
+ if (unsmob_music (body))
+ *tail = gh_cons (body, SCM_EOL) ;
- if (!full_unfold_b_ ||
- mus->repeats_i_ - done_count_ < alternative_count_i_)
- alternative_cons_l_ = alternative_cons_l_->next_;
-
- /*
- we've done the main body as well, but didn't go over the other
- increment. */
- if (full_unfold_b_)
- done_count_ ++;
- }
-
- if (done_count_ < mus->repeats_i_ && alternative_cons_l_)
+ tail = SCM_CDRLOC (*tail);
+
+ if (alt_count)
{
- if (!full_unfold_b_)
- current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
- else
- {
- current_iter_p_ = get_iterator_p (mus->repeat_body_p_);
- do_main_b_ = true;
- }
- }
+ *tail = gh_cons (gh_car (alts), SCM_EOL);
+ tail = SCM_CDRLOC (*tail);
+ if (i >= rep_count - alt_count)
+
+ alts = gh_cdr (alts);
+ }
}
+
+ return l;
}
+class Volta_repeat_iterator : public Sequential_iterator
+{
+public:
+ DECLARE_SCHEME_CALLBACK(constructor, ());
+ Volta_repeat_iterator();
+
+ void add_repeat_command (SCM);
+protected:
+ virtual SCM get_music_list () const;
+ virtual void next_element (bool);
+ virtual void construct_children();
+ virtual void process (Moment);
+
+ bool first_time_;
+ int alt_count_;
+ int rep_count_;
+ int done_count_;
+};
+
-bool
-Unfolded_repeat_iterator::ok () const
+Volta_repeat_iterator::Volta_repeat_iterator()
{
- return current_iter_p_ ;
+ done_count_ = alt_count_ = rep_count_= 0;
+ first_time_ = true;
}
-Moment
-Unfolded_repeat_iterator::next_moment () const
+SCM
+Volta_repeat_iterator::get_music_list()const
{
- return done_mom_ + current_iter_p_->next_moment ();
+ return gh_cons (get_music ()->get_mus_property ("element"),
+ get_music ()->get_mus_property ("elements"));
}
void
-Unfolded_repeat_iterator::construct_children ()
+Volta_repeat_iterator::construct_children ()
{
- Repeated_music const* mus =dynamic_cast<Repeated_music const*> (music_l_);
- full_unfold_b_ = playback_b_ || (!mus->volta_fold_b_);
+ Sequential_iterator::construct_children();
- alternative_cons_l_ = (mus->alternatives_p_)
- ? mus->alternatives_p_->music_p_list_p_->head_
- : 0;
+ SCM alts = get_music ()->get_mus_property ("elements");
- for (Cons<Music> *p = alternative_cons_l_; p; p = p->next_)
- alternative_count_i_ ++;
+ alt_count_ = scm_ilength (alts);
+ rep_count_ = gh_scm2int (get_music ()->get_mus_property ("repeat-count"));
+ done_count_ = 0;
+}
- if (mus->repeat_body_p_)
- {
- current_iter_p_ = get_iterator_p (mus->repeat_body_p_);
- do_main_b_ = true;
- }
- else if (alternative_cons_l_)
+
+/*
+ TODO: add source information for debugging
+ */
+void
+Volta_repeat_iterator::add_repeat_command (SCM what)
+{
+ SCM reps = ly_symbol2scm ("repeatCommands");
+ SCM current_reps = get_outlet ()->internal_get_property (reps);
+
+ Translator_group * where = get_outlet ()->where_defined (reps);
+ if (where
+ && current_reps == SCM_EOL || gh_pair_p (current_reps))
{
- current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
- do_main_b_ = false;
+ current_reps = gh_cons (what, current_reps);
+ where->internal_set_property (reps, current_reps);
}
}
+
void
-Unfolded_repeat_iterator::do_process_and_next (Moment m)
+Volta_repeat_iterator::next_element (bool side_effect)
{
- if (!m)
- {
- Music_iterator *yeah = try_music (music_l_);
- if (yeah)
- set_translator (yeah->report_to_l ());
- else
- music_l_->warning ( _("no one to print a volta bracket"));
- }
- while (1)
- {
- while (!current_iter_p_->ok ())
+ done_count_ ++;
+
+ Sequential_iterator::next_element (side_effect);
+
+ if (side_effect)
+ {
+ if (alt_count_)
{
- next_element();
+ String repstr = to_string (rep_count_ - alt_count_ + done_count_) + ".";
+ if (done_count_ > 1)
+ {
+ add_repeat_command (scm_list_n (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
- if (!current_iter_p_)
- return;
- }
+ if (done_count_ - 1 < alt_count_)
+ add_repeat_command (ly_symbol2scm ("end-repeat"));
+ }
+
+
- if (m - done_mom_ >= current_iter_p_->next_moment ())
- current_iter_p_->process_and_next (m - done_mom_);
+ if (done_count_ == 1 && alt_count_ < rep_count_)
+ {
+ repstr = "1.--" + to_string (rep_count_ - alt_count_ + done_count_) + ".";
+ }
+
+ if (done_count_ <= alt_count_)
+ add_repeat_command (scm_list_n (ly_symbol2scm ("volta"),
+ scm_makfrom0str (repstr.to_str0 ()), SCM_UNDEFINED));
+ }
else
- return;
+ {
+ add_repeat_command (ly_symbol2scm ("end-repeat"));
+ }
}
}
-
+
+
void
-Unfolded_repeat_iterator::do_print () const
+Volta_repeat_iterator::process (Moment m)
{
-#ifndef NPRINT
- DEBUG_OUT << "count " << done_count_ << "done time " << done_mom_ << '\n';
- DEBUG_OUT << "current: ";
- current_iter_p_->print();
-#endif
+ if (first_time_)
+ {
+ add_repeat_command (ly_symbol2scm ("start-repeat"));
+ first_time_ = false;
+ }
+ Sequential_iterator::process(m);
}
-Music_iterator*
-Unfolded_repeat_iterator::try_music_in_children (Music const * m) const
-{
- return current_iter_p_->try_music (m);
-}
+
+IMPLEMENT_CTOR_CALLBACK(Volta_repeat_iterator);
+IMPLEMENT_CTOR_CALLBACK(Unfolded_repeat_iterator);