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