lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Checkpoints (was re: Adding durations (for \after))


From: David Kastrup
Subject: Re: Checkpoints (was re: Adding durations (for \after))
Date: Fri, 18 Nov 2022 17:17:50 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)

Kieren MacMillan <kieren@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 <dak@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 <dak@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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]