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