David Kastrup <d...@gnu.org> writes: > David Kastrup <d...@gnu.org> writes: > >> Jan-Peter Voigt <jp.vo...@gmx.de> writes: >> >>> Do you have another idea how to do that? >> >> Timing is established by iterators and they work on music expressions, >> not events. So you need to have an iterator in the race from the start. >> Few iterators have variable length. The sequential iterator can have an >> elements-callback delivering music expressions. Those can have a >> structure and/or length determined at callback time. >> >> Kicking this into orderly operation does not seem like it would be >> reasonably workable. >> >> Iterators are not user-definable at the moment. Either a general >> facility or a more specific "wait-iterator" would seem warranted. > > You might want to use \lyricsto to add your private control context to > the Score context. When switching off everything that can track > melismata, you might get woken up once per event regardless of how long > your actual expressions are. > > But it might make more sense to work on actual infrastructure for this > rather than fudging around with existing facilities not intended for it.
As an example: I've created a \waitFor music function that does something similar to what you want. It was just quite useless in the original state since it waited for a particular expression, and you cannot use it to wait for \mark "B" when the mark has been generated with \mark \default . It turns out, looking at it, that the C++ code already does something more useful, namely taking the "procedure" callback for evaluating a triggering condition. While the LilyPond code does not yet match the C++ code: so I probably gave up for some reason after noticing that this still wasn't what I could be using. So this definitely needs fleshing out into something more useful. But it illustrates the kind of iterator you likely want to be using: I seem to remember that I was able to make the original version (before fudging the procedure callback into the C++ code) do something.
>From eda3025f4aebd5b400a40de3fe72bf4e58baf363 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 d41da5b5b6..e87196957b 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -2014,6 +2014,17 @@ void = Use this if you want to have a scheme expression evaluated because of its side-effects, but its value ignored.")) +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 348bcd0e87..61689a3701 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -753,6 +753,12 @@ Syntax: @code{\\\\}") (length-callback . ,ly:repeated-music::volta-music-length) (types . (repeated-music volta-repeated-music)) )) + + (WaitMusic + . ((description . "Waits for the given event.") + (iterator-ctor . ,ly:wait-iterator::constructor) + (types . (wait-music)) + )) )) (set! music-descriptions -- 2.11.0
-- David Kastrup
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel