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