(setf *handler-hash* (make-hash-table :test 'eq))
Then I made a couple of simple functions:
(defun register-handler (obj handler)
(setf (gethash obj *handler-hash*)
(append (gethash obj *handler-hash*) (list handler))))
(defun fire (object &rest e)
(let ((handlers (gethash object *handler-hash*)))
(loop
for i in handlers
do (setf e (apply i e))
while e)))
Now, with these two functions I can create events for any object. As long as the (eq... test says they are the same. So lets take *standard-input*:
(register-handler *standard-input* (lambda (&rest x)
(format t "I was passed: ~A~%" x)
'(world)))
(register-handler *standard-input* (lambda (&rest x)
(format t "I was passed: ~A~%" x)
'(goodbye)))
(register-handler *standard-input* (lambda (&rest x)
(format t "I was passed: ~A~%" x)
'nil))
(register-handler *standard-input* (lambda (&rest x)
(format t "I was passed: ~A~%" x)
'(anyone still here?)))
And then fire an event with (fire *standard-input* 'hello)...
I was passed: (HELLO)
I was passed: (WORLD)
I was passed: (GOODBYE)
You get the idea. Here, events can modify the following events, and even stop the event chain altogether. Of course there are many other considerations such as unregistering events and such, but this is still a lot of functionality in two small functions and a hash table!
No comments:
Post a Comment