]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/context.cc
Issue 5024: Rework the Preinit framework into something simpler
[lilypond.git] / lily / context.cc
index 7e3c646a6f7e2569ea7451213e6ab9fe6b58c10c..a614146058f55273bc2070d0976c356d10d346b7 100644 (file)
@@ -49,9 +49,13 @@ Context::check_removal ()
       ctx->check_removal ();
       if (ctx->is_removable ())
         {
-          recurse_over_translators (ctx, &Translator::finalize,
-                                    &Translator_group::finalize,
-                                    UP);
+          recurse_over_translators
+            (ctx,
+             Callback0_wrapper::make_smob
+             <Translator, &Translator::finalize> (),
+             Callback0_wrapper::make_smob
+             <Translator_group, &Translator_group::finalize> (),
+             UP);
           send_stream_event (ctx, "RemoveContext", 0, 0);
         }
     }
@@ -90,8 +94,7 @@ Context::Context ()
 
   smobify_self ();
 
-  Scheme_hash_table *tab = new Scheme_hash_table;
-  properties_scm_ = tab->unprotect ();
+  properties_scm_ = Scheme_hash_table::make_smob ();
   event_source_ = new Dispatcher ();
   event_source_->unprotect ();
   events_below_ = new Dispatcher ();
@@ -252,7 +255,25 @@ Context::set_property_from_event (SCM sev)
       ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?"));
 
       if (ok)
-        set_property (sym, val);
+        {
+          if (to_boolean (ev->get_property ("once")))
+            {
+              if (Global_context *g = get_global_context ())
+                {
+                  SCM old_val = SCM_UNDEFINED;
+                  if (here_defined (sym, &old_val))
+                    g->add_finalization (scm_list_4 (ly_context_set_property_x_proc,
+                                                     self_scm (),
+                                                     sym,
+                                                     old_val));
+                  else
+                    g->add_finalization (scm_list_3 (ly_context_unset_property_proc,
+                                                     self_scm (),
+                                                     sym));
+                }
+            }
+          set_property (sym, val);
+        }
     }
 }
 
@@ -262,8 +283,28 @@ Context::unset_property_from_event (SCM sev)
   Stream_event *ev = unsmob<Stream_event> (sev);
 
   SCM sym = ev->get_property ("symbol");
-  type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
-  unset_property (sym);
+  bool ok = type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
+
+  if (ok)
+    {
+      if (to_boolean (ev->get_property ("once")))
+        {
+          if (Global_context *g = get_global_context ())
+            {
+              SCM old_val = SCM_UNDEFINED;
+              if (here_defined (sym, &old_val))
+                g->add_finalization (scm_list_4 (ly_context_set_property_x_proc,
+                                                 self_scm (),
+                                                 sym,
+                                                 old_val));
+              else
+                g->add_finalization (scm_list_3 (ly_context_unset_property_proc,
+                                                 self_scm (),
+                                                 sym));
+            }
+        }
+      unset_property (sym);
+    }
 }
 
 /*
@@ -715,6 +756,11 @@ Context::print_smob (SCM port, scm_print_state *) const
   return 1;
 }
 
+void
+Context::derived_mark () const
+{
+}
+
 SCM
 Context::mark_smob () const
 {
@@ -735,10 +781,12 @@ Context::mark_smob () const
   if (events_below_)
     scm_gc_mark (events_below_->self_scm ());
 
+  derived_mark ();
+
   return properties_scm_;
 }
 
-const char Context::type_p_name_[] = "ly:context?";
+const char * const Context::type_p_name_ = "ly:context?";
 
 Global_context *
 Context::get_global_context () const