From: Han-Wen Nienhuys Date: Thu, 4 Jan 2007 20:39:34 +0000 (+0100) Subject: allow callbacks on object values too. Init via meta field. X-Git-Tag: release/2.11.9-1~29 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=635bff94c5a920d5866be4ff16751d771a35b7da;p=lilypond.git allow callbacks on object values too. Init via meta field. --- diff --git a/lily/grob-property.cc b/lily/grob-property.cc index 27fb897d1b..e8e74059ed 100644 --- a/lily/grob-property.cc +++ b/lily/grob-property.cc @@ -53,8 +53,8 @@ Grob::get_property_alist_chain (SCM def) const extern void check_interfaces_for_property (Grob const *me, SCM sym); -void #ifndef NDEBUG +void Grob::internal_set_property (SCM sym, SCM v, char const *file, int line, char const *fun) { SCM grob_p = ly_lily_module_constant ("ly:grob?"); @@ -68,11 +68,32 @@ Grob::internal_set_property (SCM sym, SCM v, char const *file, int line, char co scm_display (scm_list_2 (sym, type), scm_current_output_port ()); assert (0); } + + internal_set_value_on_alist (&mutable_property_alist_, + sym, v); + + + if (ly_is_procedure (modification_callback)) + scm_apply_0 (modification_callback, + scm_list_n (self_scm (), + scm_from_locale_string (file), + scm_from_int (line), + scm_from_locale_string (fun), + sym, v, SCM_UNDEFINED)); +} #else +void Grob::internal_set_property (SCM sym, SCM v) { + internal_set_value_on_alist (&mutable_property_alist_, + sym, v); + +} #endif +void +Grob::internal_set_value_on_alist (SCM *alist, SCM sym, SCM v) +{ /* Perhaps we simply do the assq_set, but what the heck. */ if (!is_live ()) return; @@ -87,20 +108,9 @@ Grob::internal_set_property (SCM sym, SCM v) check_interfaces_for_property (this, sym); } -#ifndef NDEBUG - if (ly_is_procedure (modification_callback)) - scm_apply_0 (modification_callback, - scm_list_n (self_scm (), - scm_from_locale_string (file), - scm_from_int (line), - scm_from_locale_string (fun), - sym, v, SCM_UNDEFINED)); -#endif - - mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, sym, v); + *alist = scm_assq_set_x (*alist, sym, v); } -//#define PROFILE_PROPERTY_ACCESSES SCM Grob::internal_get_property_data (SCM sym) const { @@ -137,7 +147,8 @@ Grob::internal_get_property (SCM sym) const if (ly_is_procedure (val) || is_simple_closure (val)) { - val = ((Grob*)this)->try_callback (sym, val); + Grob *me = ((Grob*)this); + val = me->try_callback_on_alist (&me->mutable_property_alist_, sym, val); } return val; @@ -151,15 +162,14 @@ bool debug_property_callbacks = 0; #endif SCM -Grob::try_callback (SCM sym, SCM proc) +Grob::try_callback_on_alist (SCM *alist, SCM sym, SCM proc) { SCM marker = ly_symbol2scm ("calculation-in-progress"); /* need to put a value in SYM to ensure that we don't get a cyclic call chain. */ - mutable_property_alist_ - = scm_assq_set_x (mutable_property_alist_, sym, marker); + *alist = scm_assq_set_x (*alist, sym, marker); #ifndef NDEBUG if (debug_property_callbacks) @@ -175,6 +185,7 @@ Grob::try_callback (SCM sym, SCM proc) simple_closure_expression (proc), false, 0, 0); } + #ifndef NDEBUG if (debug_property_callbacks) grob_property_callback_stack = scm_cdr (grob_property_callback_stack); @@ -188,12 +199,13 @@ Grob::try_callback (SCM sym, SCM proc) if (value == SCM_UNSPECIFIED) { value = internal_get_property (sym); + assert (value == SCM_EOL || value == marker); if (value == marker) - mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, marker); + *alist = scm_assq_remove_x (*alist, marker); } else - set_property (sym, value); - + internal_set_value_on_alist (alist, sym, value); + return value; } @@ -216,13 +228,25 @@ Grob::internal_del_property (SCM sym) SCM Grob::internal_get_object (SCM sym) const { -#ifdef PROFILE_PROPERTY_ACCESSES - note_property_access (&grob_property_lookup_table, sym); -#endif + if (profile_property_accesses) + note_property_access (&grob_property_lookup_table, sym); SCM s = scm_sloppy_assq (sym, object_alist_); + + if (s != SCM_BOOL_F) + { + SCM val = scm_cdr (s); + if (ly_is_procedure (val) + || is_simple_closure (val)) + { + Grob *me = ((Grob*)this); + val = me->try_callback_on_alist (&me->object_alist_, sym, val); + } + + return val; + } - return (s == SCM_BOOL_F) ? SCM_EOL : scm_cdr (s); + return SCM_EOL; } bool diff --git a/lily/grob.cc b/lily/grob.cc index 139a387989..0591ab115f 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -59,7 +59,16 @@ Grob::Grob (SCM basicprops, SCM meta = get_property ("meta"); if (scm_is_pair (meta)) - interfaces_ = scm_cdr (scm_assq (ly_symbol2scm ("interfaces"), meta)); + { + interfaces_ = scm_cdr (scm_assq (ly_symbol2scm ("interfaces"), meta)); + + SCM object_cbs = scm_assq (ly_symbol2scm ("object-callbacks"), meta); + if (scm_is_pair (object_cbs)) + { + for (SCM s = scm_cdr (object_cbs); scm_is_pair (s); s = scm_cdr (s)) + set_object (scm_caar (s), scm_cdar (s)); + } + } if (get_property_data ("X-extent") == SCM_EOL) set_property ("X-extent", Grob::stencil_width_proc); @@ -633,15 +642,10 @@ ADD_INTERFACE (Grob, "transparent " ); - - - - /**************************************************************** CALLBACKS ****************************************************************/ - static SCM grob_stencil_extent (Grob *me, Axis a) { diff --git a/lily/include/grob.hh b/lily/include/grob.hh index 3a06afda20..08ad8c7835 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -44,6 +44,9 @@ protected: void substitute_object_links (SCM, SCM); Real get_offset (Axis a) const; SCM try_callback (SCM, SCM); + SCM try_callback_on_alist (SCM *, SCM, SCM); + void internal_set_value_on_alist (SCM *alist, SCM sym, SCM val); + public: /* friends */