plugin.rkt

#410
Raw
Author
winny
Created
Nov. 25, 2021, 3:23 a.m.
Expires
Never
Size
1.7 KB
Hits
113
Syntax
Racket
#lang racket

(require racket/rerequire)
;; (require "signatures/plugin-sig.rkt")
(provide (all-defined-out))

(define-signature plugin^
  (description ; string?
   load ; (-> void?)
   unload ; (-> void?)
   dependencies))

(struct Plugin [name description dependencies load unload] #:transparent)
(define (mod->unit-name name)
  (string->symbol (format "~a@" (match name
                                  [(regexp #rx"([^/]+)\\.rkt" (list _ base)) base]))))
(define loaded-plugins (make-hash))
(define (load-plugin name)
  (dynamic-rerequire name #:verbosity 'none)
  (define-values/invoke-unit (dynamic-require name (mod->unit-name name))
    (import)
    (export plugin^))
  (load)
  (define p (Plugin name description dependencies load unload))
  (hash-set! loaded-plugins name p)
  p)
(define (stale-plugin? p)
  (not (empty? (dynamic-rerequire (Plugin-name p) #:verbosity 'none))))
(define (unload-plugin p)
  (begin0
      ((Plugin-unload p))
    (hash-remove! loaded-plugins (Plugin-name p))))
(define (reload-plugin p)
  (unload-plugin p)
  (load-plugin (Plugin-name p)))

(define (load-directory dir)
  (for ([p (in-directory dir)])
    (load-plugin p)))

(module+ main
  (define targets '("plugins/hello.rkt"))
  (displayln "Starting up...")
  (for ([p targets])
    (load-plugin p))
  (printf "loaded plugins: ~v\n" (hash-keys loaded-plugins))
  (displayln "Shutting down...")
  (for ([p (in-hash-values (hash-copy loaded-plugins))])
    (unload-plugin p)))

;; example plugin below!!!
#lang racket/unit
(require "../main.rkt")
(import)
(export plugin^)
(define dependencies '(sayer))
(define version "0.1")
(define description "Greet users")
(define (load)
  (printf "Hello ~a loaded.\n" version))
(define (unload)
  (printf "Hello ~a unloaded.\n" version))