Kieren MacMillan <kie...@kierenmacmillan.info> writes: > Hi Jean, > >> Well, it's not too hard to implement them. > > In the hopes that it’s also not too hard for Super-Jean to implement anchors… > ;) > > Is there a world in which one could write something like > > global = { > \anchor #'intro > s1*8 > \anchor #'verse > s1*8 > \anchor #'chorus > s1*8 > } > > and then > > chorusMusic = { > \gotoAnchor #'chorus > c'1 > } > > would make a whole note c' appear in the 17th measure of the score?
It takes an iterator to wait an unspecified amount of time, and those can only be written in C++ right now. There actually is some ancient local branch in my repository with a sketch of an idea, but it likely doesn't work at all for anything. But maybe it gives someone an idea...
>From 4f86263cb78f33ad56706f0f9b6668622c417870 Mon Sep 17 00:00:00 2001 From: David Kastrup <d...@gnu.org> Date: Fri, 17 Jul 2015 17:23:17 +0200 Subject: [PATCH] Create a wait music function. --- lily/wait-iterator.cc | 112 +++++++++++++++++++++++++++++++++++++ ly/music-functions-init.ly | 11 ++++ scm/define-music-types.scm | 6 ++ 3 files changed, 129 insertions(+) create mode 100644 lily/wait-iterator.cc diff --git a/lily/wait-iterator.cc b/lily/wait-iterator.cc new file mode 100644 index 0000000000..939ba34c9b --- /dev/null +++ b/lily/wait-iterator.cc @@ -0,0 +1,112 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2016 David Kastrup <d...@gnu.org> + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "lily-guile.hh" +#include "context.hh" +#include "input.hh" +#include "international.hh" +#include "moment.hh" +#include "music.hh" +#include "music-iterator.hh" + +class Wait_iterator : public Music_wrapper_iterator +{ + bool triggered_; + SCM procedure_; +protected: + virtual void derived_mark () const; + virtual Moment pending_moment () const; + virtual void process (Moment); + virtual bool ok () const; + virtual bool run_always () const; +public: + Wait_iterator (); + DECLARE_SCHEME_CALLBACK (constructor, ()); + virtual void construct_children (); +}; + +Wait_iterator::Wait_iterator () + : triggered_ (false), procedure_ (SCM_UNDEFINED) +{ +} + +void +Wait_iterator::derived_mark () const +{ + scm_gc_mark (procedure_); +} + +Moment +Wait_iterator::pending_moment () const +{ + if (triggered_) + return Moment (0); + Moment m; + m.set_infinite (1); + return m; +} + +bool +Wait_iterator::run_always () const +{ + return triggered + || !Music_wrapper_iterator::ok () + || Music_wrapper_iterator::run_always (); +} + +void +Wait_iterator::process (Moment m) +{ + if (triggered_) + return; + if (scm_is_true (scm_call_1 (procedure_, get_outlet ()->self_scm ()))) + { + triggered_ = true; + return; + } + if (!Music_wrapper_iterator::ok ()) + { + Music_wrapper_iterator::construct_children (); + if (!Music_wrapper_iterator::ok ()) + return; + } + Music_wrapper_iterator::process (m); +} + +bool +Wait_iterator::ok () const +{ + return !triggered_; +} + +void +Wait_iterator::construct_children () +{ + procedure_ = get_music ()->get_property ("procedure"); + if (!ly_is_procedure (procedure_)) + { + get_music ()->origin ()->warning (_ ("Bad procedure")); + triggered_ = true; + return; + } + + Music_iterator::construct_children (); +} + +IMPLEMENT_CTOR_CALLBACK (Wait_iterator) diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index aaea08d83f..b74fc11a14 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -2226,6 +2226,17 @@ vshape = ease of tweaking." (once (propertyTweak 'show-control-points #t (shape offsets item)))) +waitFor = +#(define-music-function (music) (ly:music?) + (_i "Wait for the occurence of the given @var{music} in the +current context. Use it, for example, as +@example +\\context Score \\waitFor \\mark "A" +@end example +") + (make-music 'WaitMusic + 'element music)) + withMusicProperty = #(define-music-function (sym val music) (symbol? scheme? ly:music?) diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index e61667de3c..97b7b93e7e 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -913,6 +913,12 @@ brackets start and stop.") (start-callback . ,ly:music-wrapper::start-callback) (types . (volta-specification music-wrapper-music)) )) + + (WaitMusic + . ((description . "Waits for the given event.") + (iterator-ctor . ,ly:wait-iterator::constructor) + (types . (wait-music)) + )) )) (set! music-descriptions -- 2.37.2
-- David Kastrup