]> git.donarmstrong.com Git - lilypond.git/blob - lily/global-context.cc
Nitpick run.
[lilypond.git] / lily / global-context.cc
1 /*
2   global-context.cc -- implement Global_context
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "global-context.hh"
10
11 #include <cstdio>
12
13 #include "warn.hh"
14 #include "music.hh"
15 #include "music-iterator.hh"
16 #include "score-context.hh"
17 #include "context-def.hh"
18 #include "output-def.hh"
19 #include "lilypond-key.hh"
20
21 Global_context::Global_context (Output_def *o, Moment final, Object_key *key)
22   : Context (new Lilypond_context_key (key,
23                                        Moment (0),
24                                        "Global", "", 0))
25 {
26   output_def_ = o;
27   final_mom_ = final;
28   definition_ = find_context_def (o, ly_symbol2scm ("Global"));
29
30   Context_def *globaldef = unsmob_context_def (definition_);
31   if (!globaldef)
32     programming_error ("no `Global' context found");
33   else
34     globaldef->apply_default_property_operations (this);
35   accepts_list_ = scm_list_1 (ly_symbol2scm ("Score"));
36 }
37
38 Output_def *
39 Global_context::get_output_def () const
40 {
41   return output_def_;
42 }
43
44 void
45 Global_context::add_moment_to_process (Moment m)
46 {
47   if (m > final_mom_)
48     return;
49
50   if (m < now_mom_)
51     programming_error ("trying to freeze in time");
52
53   for (int i = 0; i < extra_mom_pq_.size (); i++)
54     if (extra_mom_pq_[i] == m)
55       return;
56   extra_mom_pq_.insert (m);
57 }
58
59 Moment
60 Global_context::sneaky_insert_extra_moment (Moment w)
61 {
62   while (extra_mom_pq_.size () && extra_mom_pq_.front () <= w)
63     w = extra_mom_pq_.get ();
64   return w;
65 }
66
67 int
68 Global_context::get_moments_left () const
69 {
70   return extra_mom_pq_.size ();
71 }
72
73 void
74 Global_context::prepare (Moment m)
75 {
76   prev_mom_ = now_mom_;
77   now_mom_ = m;
78
79   clear_key_disambiguations ();
80   if (get_score_context ())
81     get_score_context ()->prepare (m);
82 }
83
84 Moment
85 Global_context::now_mom () const
86 {
87   return now_mom_;
88 }
89
90 Score_context *
91 Global_context::get_score_context () const
92 {
93   return (scm_is_pair (context_list_))
94     ? dynamic_cast<Score_context *> (unsmob_context (scm_car (context_list_)))
95     : 0;
96 }
97
98 SCM
99 Global_context::get_output ()
100 {
101   return get_score_context ()->get_output ();
102 }
103
104 void
105 Global_context::one_time_step ()
106 {
107   get_score_context ()->one_time_step ();
108   apply_finalizations ();
109   check_removal ();
110 }
111
112 void
113 Global_context::finish ()
114 {
115   if (get_score_context ())
116     get_score_context ()->finish ();
117 }
118
119 void
120 Global_context::run_iterator_on_me (Music_iterator *iter)
121 {
122   if (iter->ok ())
123     prev_mom_ = now_mom_ = iter->pending_moment ();
124
125   bool first = true;
126   while (iter->ok () || get_moments_left ())
127     {
128       Moment w;
129       w.set_infinite (1);
130       if (iter->ok ())
131         w = iter->pending_moment ();
132
133       w = sneaky_insert_extra_moment (w);
134       if (w.main_part_.is_infinity ())
135         break;
136
137       if (first)
138         {
139           /*
140             Need this to get grace notes at start of a piece correct.
141           */
142           first = false;
143           set_property ("measurePosition", w.smobbed_copy ());
144         }
145
146       prepare (w);
147
148       if (iter->ok ())
149         iter->process (w);
150
151       if (!get_score_context ())
152         {
153           SCM sym = ly_symbol2scm ("Score");
154           Context_def *t = unsmob_context_def (find_context_def (get_output_def (),
155                                                                  sym));
156           if (!t)
157             error (_f ("can't find `%s' context", "Score"));
158
159           Object_key const *key = get_context_key ("Score", "");
160           Context *c = t->instantiate (SCM_EOL, key);
161           add_context (c);
162
163           Score_context *sc = dynamic_cast<Score_context *> (c);
164           sc->prepare (w);
165         }
166
167       one_time_step ();
168     }
169 }
170
171 void
172 Global_context::apply_finalizations ()
173 {
174   SCM lst = get_property ("finalizations");
175   set_property ("finalizations", SCM_EOL);
176   for (SCM s = lst; scm_is_pair (s); s = scm_cdr (s))
177
178     /* TODO: make safe.  */
179     scm_primitive_eval (scm_car (s));
180 }
181
182 /* Add a function to execute before stepping to the next time step.  */
183 void
184 Global_context::add_finalization (SCM x)
185 {
186   SCM lst = get_property ("finalizations");
187   lst = scm_cons (x, lst);
188   set_property ("finalizations", lst);
189 }
190
191 Moment
192 Global_context::previous_moment () const
193 {
194   return prev_mom_;
195 }
196
197 Context *
198 Global_context::get_default_interpreter ()
199 {
200   if (get_score_context ())
201     return get_score_context ()->get_default_interpreter ();
202   else
203     return Context::get_default_interpreter ();
204 }