Event Driven Architecture Programming in Lisp Part 1

  • What is Event Driven Architecture Programming?
    • It is the ability to inform interested objects (consumer/subscriber/sink) of changes of state from other objects (producer/subscriber/source) with events.
  • Why use this architecture?
    • There are two reason to use this architecture. One is to loosely couple the interacting objects. The second is that it is best-suited for use in an asynchronous context.
  • What are the components required?
    • A table that stores event-handlers
    • An interface to register a trigger of events.
    • An interface to register notification of an event trigger.
    • An interface to trigger events.
  • How to represent events?
    • Closures

The interface:

(test-fixture handler-table
    (:setup
      ((handlers (make-handler-table))))

  (:tests

    (should-have-zero-listeners
     (can-fire handlers :whatever-event)
     (assert-false (listeners? handlers :whatever-event)))

    (should-not-make-new-events-handler-or-overwrite-events-handler
     (can-fire handlers :whatever-event)
     (when-fire handlers :whatever-event (lambda () (+ 1 1)))
     (can-fire handlers :whatever-event)
     (assert-true (listeners? handlers :whatever-event)))

    (should-trigger-events
     (can-fire handlers :whatever-event)
     (assert-false (listeners? handlers :whatever-event))
     (when-fire handlers :whatever-event (lambda () (+ 1 1)))
     (assert-equal t (listeners? handlers :whatever-event))
     (assert-equal 1 (fire handlers :whatever-event))
     (when-fire handlers :whatever-event (lambda () (+ 1 20)))
     (assert-equal 2 (fire handlers :whatever-event))))

The implementation:

(defobj events-handler
  (:members ((events (make-list 0))))
  (:methods ((:h-count () (length events))
             (:subscribe (event) (cond ((functionp event)
                                        (push event events))))
             (:trigger () (let ((trigger-count 0))
                            (dolist (event events)
                              (funcall event)
                              (incf trigger-count))
                            trigger-count)))))

(defobj handler-table
  (:members ((events (make-hash-table))))
  (:methods ((:can-fire (event)
               (let ((handler (make-events-handler)))
                 (if (null (gethash event events))
                     (setf (gethash event events) handler))))

             (:when-fire (event expression)
               (let ((handler (gethash event events)))
                 (subscribe handler expression)
                 (setf (gethash event events) handler)))

             (:listeners? (event)
               (let ((handler (gethash event events)))
                 (if (eq (h-count handler) 0) nil t)))

             (:fire (event)
               (let ((handler (gethash event events)))
                (trigger handler)))))

Actual usage:

(defobj view
  (:members ((publisher (make-handler-table))
             (data nil)))
  (:methods ((:init ()
               (can-fire publisher :update)
               (can-fire publisher :reset))
             (:update-view ()
               (fire publisher :update))
             (:reset-view ()
               (fire publisher :reset))
             (:get-data ()
               data)
             (:set-data (value)
               (setf data value))
             (:update-handler (handler)
               (when-fire publisher :update handler))
             (:reset-handler (handler)
               (when-fire publisher :reset handler)))))

This is a rough draft, but I think it will work

Advertisements

One Response to Event Driven Architecture Programming in Lisp Part 1

  1. […] Vote Event Driven Architecture Programming in Lisp Part 1 […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: