]> git.donarmstrong.com Git - lilypond.git/blob - lily/global-context.cc
* Documentation/user/refman.itely: documentation patch by Edward
[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 "music-output-def.hh"
19
20 Global_context::Global_context (Music_output_def*o)
21 {
22   output_def_ = o;
23   definition_ = o->find_context_def (ly_symbol2scm ("Global"));
24   unsmob_context_def (definition_)->apply_default_property_operations (this);
25 }
26
27 Music_output_def* 
28 Global_context::get_output_def () const
29 {
30   return output_def_;
31 }
32
33 void
34 Global_context::add_moment_to_process (Moment m)
35 {
36   if (m  > final_mom_)
37     return;
38
39   if (m < now_mom_)
40     programming_error ("Trying to freeze in time.");
41   
42   for (int i=0; i <  extra_mom_pq_.size (); i++)
43     if (extra_mom_pq_[i] == m)
44       return;
45   extra_mom_pq_.insert (m);
46 }
47
48 Moment
49 Global_context::sneaky_insert_extra_moment (Moment w)
50 {
51   while (extra_mom_pq_.size () && extra_mom_pq_.front () <= w)
52     w = extra_mom_pq_.get ();
53   return w;
54 }
55
56 int
57 Global_context::get_moments_left () const
58 {
59   return extra_mom_pq_.size ();
60 }
61
62 void
63 Global_context::prepare (Moment m)
64 {
65   prev_mom_  = now_mom_;
66   now_mom_ = m;
67
68   if (get_score_context ())
69     get_score_context ()->prepare (m);
70 }
71
72 Moment
73 Global_context::now_mom () const
74 {
75   return now_mom_;
76 }
77
78 Score_context*
79 Global_context::get_score_context () const
80 {
81   return (gh_pair_p (context_list_))
82     ? dynamic_cast<Score_context*> (unsmob_context (gh_car (context_list_)))
83     : 0;
84 }
85
86 Music_output*
87 Global_context::get_output ()
88 {
89   return get_score_context ()->get_output ();
90 }
91
92 void
93 Global_context::one_time_step ()
94 {
95   get_score_context ()->one_time_step ();
96   apply_finalizations ();
97   check_removal ();
98 }
99
100 void
101 Global_context::finish ()
102 {
103   if (get_score_context ())
104     get_score_context ()->finish ();
105 }
106
107 void
108 Global_context::run_iterator_on_me (Music_iterator * iter)
109 {
110   if (iter-> ok ())
111     prev_mom_ = now_mom_ = iter->pending_moment ();
112
113   bool first = true;
114   while (iter->ok () || get_moments_left ())
115     {
116       Moment w;
117       w.set_infinite (1);
118       if (iter->ok ())
119         {
120           w = iter->pending_moment ();
121         }
122
123       w = sneaky_insert_extra_moment (w);
124       if (w.main_part_.is_infinity ())
125         break ;
126       
127 #if 0      
128       //      printf ("proccing %s\n ",       w.to_string ().to_str0 ());
129       if (first)
130         {
131           /*
132             Huh? 
133            */
134           set_property ("measurePosition", w.smobbed_copy ());
135         }
136 #endif
137       
138       prepare (w);
139
140       if (iter->ok ())
141         iter->process (w);
142
143       if (!get_score_context ()) 
144         {
145           SCM key = ly_symbol2scm ("Score");
146           Context_def * t = unsmob_context_def (get_output_def ()
147                                                 ->find_context_def (key));
148           if (!t)
149             error (_f ("can't find `%s' context", "Score"));
150           
151           add_context (t->instantiate (SCM_EOL));
152
153           Score_context *sc = dynamic_cast<Score_context*> (t);
154           sc->prepare (w);
155         }
156       
157       one_time_step ();
158       first = false;      
159     }
160 }
161
162 void
163 Global_context::apply_finalizations ()
164 {
165   SCM lst = get_property ("finalizations");
166   set_property ("finalizations" , SCM_EOL); 
167   for (SCM s = lst ; gh_pair_p (s); s = gh_cdr (s))
168     {
169       scm_primitive_eval (gh_car (s));
170     }
171 }
172
173 /*
174    Add a function to execute before stepping to the next time step.
175  */
176 void
177 Global_context::add_finalization (SCM x)
178 {
179   SCM lst = get_property ("finalizations");
180   lst = scm_cons (x, lst);
181   set_property ("finalizations" ,lst); 
182 }
183