aboutsummaryrefslogtreecommitdiff
path: root/src/guile/skribilo/engine.scm
diff options
context:
space:
mode:
Diffstat (limited to 'src/guile/skribilo/engine.scm')
-rw-r--r--src/guile/skribilo/engine.scm54
1 files changed, 50 insertions, 4 deletions
diff --git a/src/guile/skribilo/engine.scm b/src/guile/skribilo/engine.scm
index d747ea0..5800486 100644
--- a/src/guile/skribilo/engine.scm
+++ b/src/guile/skribilo/engine.scm
@@ -41,7 +41,9 @@
engine-custom engine-custom-set!
engine-format? engine-add-writer!
processor-get-engine
- push-default-engine pop-default-engine))
+ push-default-engine pop-default-engine
+
+ engine-loaded? when-engine-is-loaded))
(fluid-set! current-reader %skribilo-module-reader)
@@ -180,10 +182,50 @@
new))
+
;;;
-;;; FIND-ENGINE
+;;; Engine loading.
;;;
+;; Each engine is to be stored in its own module with the `(skribilo engine)'
+;; hierarchy. The `engine-id->module-name' procedure returns this module
+;; name based on the engine name.
+
+(define (engine-id->module-name id)
+ `(skribilo engine ,id))
+
+(define (engine-loaded? id)
+ "Check whether engine @var{id} is already loaded."
+ ;; Trick taken from `resolve-module' in `boot-9.scm'.
+ (nested-ref the-root-module
+ `(%app modules ,@(engine-id->module-name id))))
+
+;; A mapping of engine names to hooks.
+(define %engine-load-hook (make-hash-table))
+
+(define (consume-load-hook! id)
+ (with-debug 5 'consume-load-hook!
+ (let ((hook (hashq-ref %engine-load-hook id)))
+ (if hook
+ (begin
+ (debug-item "running hook " hook " for engine " id)
+ (hashq-remove! %engine-load-hook id)
+ (run-hook hook))))))
+
+(define (when-engine-is-loaded id thunk)
+ "Run @var{thunk} only when engine with identifier @var{id} is loaded."
+ (if (engine-loaded? id)
+ (begin
+ ;; Maybe the engine had already been loaded via `use-modules'.
+ (consume-load-hook! id)
+ (thunk))
+ (let ((hook (or (hashq-ref %engine-load-hook id)
+ (let ((hook (make-hook)))
+ (hashq-set! %engine-load-hook id hook)
+ hook))))
+ (add-hook! hook thunk))))
+
+
(define* (lookup-engine id :key (version 'unspecified))
"Look for an engine named @var{name} (a symbol) in the @code{(skribilo
engine)} module hierarchy. If no such engine was found, an error is raised,
@@ -192,15 +234,19 @@ otherwise the requested engine is returned."
(debug-item "id=" id " version=" version)
(let* ((engine (symbol-append id '-engine))
- (m (resolve-module `(skribilo engine ,id))))
+ (m (resolve-module (engine-id->module-name id))))
(if (module-bound? m engine)
- (module-ref m engine)
+ (let ((e (module-ref m engine)))
+ (if e (consume-load-hook! id))
+ e)
(error "no such engine" id)))))
(define* (find-engine id :key (version 'unspecified))
(false-if-exception (apply lookup-engine (list id version))))
+
+
;;;
;;; Engine methods.