diff options
Diffstat (limited to 'src/guile/skribilo/engine.scm')
-rw-r--r-- | src/guile/skribilo/engine.scm | 54 |
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. |