(defpackage #:observable (:use #:cl) (:export :observable :on :off :notify)) (in-package :observable) (defclass observable () ((observers :accessor observers :initform (make-hash-table)))) (defmethod on ((self observable) event f) (push f (gethash event (observers self)))) (defmethod off ((self observable) event f) (setf (gethash event (observers self)) (remove f (gethash event (observers self))))) (defmethod notify ((self observable) event &optional value) (loop for observer in (gethash event (observers self)) do (funcall observer value)))