cl-scopes/core/core.lisp

70 lines
1.6 KiB
Common Lisp

;;;; cl-scopes/core - here comes the real action
(defpackage :scopes/core
(:use :common-lisp)
(:local-nicknames (:config :scopes/config)
(:message :scopes/core/message))
(:export #:config #:service-config
#:context #:name #:actions #:send
#:action-spec
#:printer))
(in-package :scopes/core)
;;;; config
(defclass config (config:root)
(services))
(defclass service-config (config:base)
(start))
;;;; actions
(defclass action-spec ()
((pattern :reader pattern :initarg :pattern :initform nil)
(handlers :reader handlers :initarg :handlers)))
;;;; context
(defvar *context* nil)
(defclass context ()
((name :reader name :initarg :name)
(actions :accessor actions :initform nil)))
(defgeneric send (rcvr msg)
(:method ((rcvr context) msg)
(let* ((acts (actions rcvr))
(hdlrs (select msg acts)))
(dolist (hdlr hdlrs)
(funcall hdlr rcvr msg)))))
(defun select (msg acts)
(let ((h (message:head-as-list msg))
(hdlrs nil))
(dolist (a acts)
(if (match (pattern a) h)
(dolist (hdlr (handlers a))
(push hdlr hdlrs))))
hdlrs))
(defun match (pat h)
(dolist (item pat)
(if (and item (not (eq item (pop h))))
(return-from match nil)))
t)
;;;; simple printer service
(defun do-print (ctx msg)
(declare (ignore ctx))
(format t "~&~s~%" msg))
(defclass printer (context)
((actions :initform
(list (make-instance 'action-spec
:handlers (list #'do-print))))))
(defun printer (name)
(make-instance 'printer :name name))