diff options
author | Thomas White <taw@physics.org> | 2021-05-10 20:54:53 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2021-05-10 20:56:02 +0200 |
commit | 1fa25deedd48440dd17521f5e7d41a3e69bd3743 (patch) | |
tree | 6c1a7820c0fcf9c74253d2e3a28c6c8a78e538a5 /guile/starlet/state.scm | |
parent | 0acf5d8958fae9ef959b9bae4917c656081189ef (diff) |
Run cues as single atomic operations
This avoids a potential situation where one parameter of a fixture is
reconfigured before another, which could (in theory) lead to flickering
of lights.
Diffstat (limited to 'guile/starlet/state.scm')
-rw-r--r-- | guile/starlet/state.scm | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/guile/starlet/state.scm b/guile/starlet/state.scm index 13888e8..a889d0c 100644 --- a/guile/starlet/state.scm +++ b/guile/starlet/state.scm @@ -48,7 +48,8 @@ blackout sel selection-hook - value->number)) + value->number + atomically-overlay-state!)) ;; A "state" is an atomically-updating container for an immutable @@ -231,6 +232,23 @@ pre-existing contents." (state-for-each at state)) +(define (atomically-overlay-state! state newbits) + "Apply 'newbits' within 'state', as a single atomic operation." + (let* ((old-ht (atomic-box-ref (get-ht-box state))) + (new-ht (copy-hash-table old-ht))) + (state-for-each (lambda (fix attr val) + (hash-set! new-ht + (cons fix attr) + val)) + newbits) + (unless (eq? (atomic-box-compare-and-swap! + (get-ht-box state) + old-ht + new-ht) + old-ht) + (atomically-overlay-state! state newbits)))) ;; Try again + + (define current-state (make-parameter programmer-state)) |