]> git.donarmstrong.com Git - lilypond.git/blob - lily/folded-repeat-iterator.cc
* flower
[lilypond.git] / lily / folded-repeat-iterator.cc
1 /*
2   folded-repeat-iterator.cc -- implement Folded_repeat_iterator
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1999--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "folded-repeat-iterator.hh"
10
11 #include "input.hh"
12 #include "repeated-music.hh"
13 #include "simultaneous-music-iterator.hh"
14 #include "context.hh"
15
16 Folded_repeat_iterator::Folded_repeat_iterator ()
17 {
18   main_iter_ = 0;
19   alternative_iter_ = 0;
20 }
21
22 bool
23 Folded_repeat_iterator::ok () const
24 {
25   return main_iter_ || alternative_iter_;
26 }
27 void
28 Folded_repeat_iterator::do_quit ()
29 {
30   if (main_iter_)main_iter_->quit ();
31   if (alternative_iter_)alternative_iter_->quit ();
32 }
33
34 Moment
35 Folded_repeat_iterator::pending_moment () const
36 {
37   if (main_iter_)
38     {
39       return main_iter_->pending_moment ();
40     }
41   else
42     return main_length_mom_ + alternative_iter_->pending_moment ();
43 }
44
45 void
46 Folded_repeat_iterator::construct_children ()
47 {
48   Music *mus = get_music ();
49   main_iter_ = unsmob_iterator (get_iterator (Repeated_music::body (mus)));
50   if (!main_iter_->ok ())
51     {
52       leave_body ();
53       enter_alternative ();
54     }
55 }
56
57 void
58 Folded_repeat_iterator::process (Moment m)
59 {
60   if (!m.to_bool ())
61     {
62       bool success = try_music (get_music ());
63       if (!success)
64         get_music ()->origin ()->warning (_ ("no one to print a repeat brace"));
65     }
66
67   if (main_iter_)
68     {
69       main_iter_->process (m);
70       if (!main_iter_->ok ())
71         leave_body ();
72     }
73
74   if (!main_iter_ && !alternative_iter_)
75     {
76       enter_alternative ();
77     }
78
79   if (alternative_iter_)
80     {
81       alternative_iter_->process (m - main_length_mom_);
82       if (!alternative_iter_->ok ())
83         {
84           alternative_iter_->quit ();
85           alternative_iter_ = 0;
86         }
87     }
88 }
89
90 void
91 Folded_repeat_iterator::leave_body ()
92 {
93   Music *mus = get_music ();
94
95   main_iter_->quit ();
96   main_iter_ = 0;
97   main_length_mom_ += Repeated_music::body (mus)->get_length ();
98 }
99
100 void
101 Folded_repeat_iterator::enter_alternative ()
102 {
103   Music *mus = get_music ();
104   if (scm_is_pair (Repeated_music::alternatives (mus)))
105     {
106       /*
107         ugh.
108       */
109       Simultaneous_music_iterator *s = new Simultaneous_music_iterator;
110       s->create_separate_contexts_ = true;
111       s->init_translator (mus, get_outlet ());
112
113       alternative_iter_ = s;
114       alternative_iter_->construct_children ();
115
116       scm_gc_unprotect_object (s->self_scm ());
117     }
118 }
119
120 Music_iterator *
121 Folded_repeat_iterator::try_music_in_children (Music *m) const
122 {
123   if (main_iter_)
124     {
125       return main_iter_->try_music (m);
126     }
127   if (alternative_iter_)
128     return alternative_iter_->try_music (m);
129   return 0;
130 }
131 void
132 Folded_repeat_iterator::derived_mark () const
133 {
134   if (main_iter_)
135     scm_gc_mark (main_iter_->self_scm ());
136   if (alternative_iter_)
137     scm_gc_mark (alternative_iter_->self_scm ());
138 }
139
140 void
141 Folded_repeat_iterator::derived_substitute (Context *f, Context *t)
142 {
143   if (main_iter_)
144     main_iter_->substitute_outlet (f, t);
145   if (alternative_iter_)
146     alternative_iter_->substitute_outlet (f, t);
147 }
148
149 IMPLEMENT_CTOR_CALLBACK (Folded_repeat_iterator);