diff options
author | David Thompson <dthompson2@worcester.edu> | 2015-11-15 10:47:24 -0500 |
---|---|---|
committer | David Thompson <dthompson2@worcester.edu> | 2015-11-15 10:47:24 -0500 |
commit | 77ddc09a80ca6ba07597adc0313062e6f8649ca4 (patch) | |
tree | 238720c35d1d2d9aabcd664033160132f2cc8b4c /sly/live-reload.scm | |
parent | 168894b85b818d276968b8ab68800e3a1942bdf6 (diff) |
Reimplement live-reload module.
* sly/live-reload.scm (watch-files): New procedure.
(live-reload): Rename to...
(with-live-reload): This.
* doc/api/utils.tex ("Live Reloading"): Update docs.
Diffstat (limited to 'sly/live-reload.scm')
-rw-r--r-- | sly/live-reload.scm | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/sly/live-reload.scm b/sly/live-reload.scm index f354fda..cb40e7c 100644 --- a/sly/live-reload.scm +++ b/sly/live-reload.scm @@ -26,9 +26,40 @@ #:use-module (sly agenda) #:use-module (sly coroutine) #:use-module (sly signal) - #:export (live-reload)) + #:export (watch-files + with-live-reload)) -(define* (live-reload proc #:optional (polling-interval 120)) +(define* (watch-files files thunk #:optional (polling-interval 120)) + "Watch FILES, a list of file names, and apply THUNK each time one of +them changes. A signal is returned that contains the current result +of THUNK. The POLLING-INTERVAL flag determines how often FILES are +polled for changes, defaulting to two seconds." + (define (current-mtime file-name) + (let ((info (stat file-name))) + (max (stat:mtime info) (stat:ctime info)))) + + (define (max-current-mtime) + (and (every file-exists? files) + (reduce max 0 (map current-mtime files)))) + + (let ((asset (make-signal (thunk)))) + (coroutine + (let loop ((last-mtime (max-current-mtime))) + (wait polling-interval) + (let ((mtime (max-current-mtime))) + (when (cond + ;; Some files do not exist anymore, can't reload. + ((not mtime) #f) + ;; Some files were missing, but are back now. + ((and mtime (not last-mtime)) #t) + ;; All the files exist and existed last time, too, so + ;; check if they have been modified since last time. + (else (> mtime last-mtime))) + (signal-set! asset (thunk))) + (loop mtime)))) + asset)) + +(define* (with-live-reload proc #:optional (polling-interval 120)) "Return a new procedure that re-applies PROC whenever the associated file is modified. The new procedure returns a signal that contains the return value of PROC. The first argument to PROC must be a @@ -37,21 +68,5 @@ file name string. A simple polling method is used to test for updates. Files are polled every POLLING-INTERVAL ticks (120 by default)." (lambda (file-name . args) - (define (load-asset) - (apply proc file-name args)) - - (define (current-mtime) - (let ((info (stat file-name))) - (max (stat:mtime info) (stat:ctime info)))) - - (let ((asset (make-signal (load-asset)))) - (coroutine - (let loop ((last-mtime (current-mtime))) - (wait polling-interval) - (let ((mtime (if (file-exists? file-name) - (current-mtime) - last-mtime))) - (when (> mtime last-mtime) - (signal-set! asset (load-asset))) - (loop mtime)))) - asset))) + (watch-files (list file-name) + (lambda () (apply proc file-name args))))) |