Overtone gets an event system

Overtone now has a global event system. You can subscribe to any event:

  (on :chorus-finished #(fade-chorus-echo))

And publish any event:

  (event ::chorus-finished)

optionally with added properties:

  (event ::chorus-finished :timestamp (+ clock tick))

This is a great example of the power of having a Lisp like Clojure on top of the JVM. Using a fixed thread pool executor from the java.util.concurrent package made this incredibly simple, and since we use a reference variable to store the event handlers all modifications are safe-guarded by the STM.

(ns overtone.core.event
  (:import (java.util.concurrent Executors LinkedBlockingQueue))
  (:use (overtone.core util)))

(def NUM-THREADS (cpu-count))
(defonce thread-pool (Executors/newFixedThreadPool NUM-THREADS))
(defonce event-handlers* (ref {}))

(defn on
  "Runs handler whenever events of type event-type are fired.  The handler can 
  optionally except a single event argument, which is a map containing the 
  :event-type property and any other properties specified when it was fired.
  
  (on ::booted #(do-stuff))
  (on ::midi-note-down (fn [event] (funky-bass (:note event))))"
  [event-type handler]
  (dosync
    (let [handlers (get @event-handlers* event-type [])]
      (alter event-handlers* assoc event-type (conj handlers handler)))))

(defn remove-handler
  "Remove an event handler previously registered to handle events of
event-type."
  [event-type handler]
  (dosync
    (let [handlers (get @event-handlers* event-type [])]
      (alter event-handlers* assoc event-type (filter #(not (= handler %))
handlers)))))

(defn clear-handlers
  "Remove all handlers for events of type event-type."
  [event-type]
  (dosync (alter event-handlers* dissoc event-type)))

(defn- handle-event [event]
  (doseq [handler (get @event-handlers* (:event-type event) [])]
    (if (zero? (arg-count handler))
      (handler)
      (handler event))))

(defn event
  "Fire an event of type event-type with any number of additional properties.

  (event ::my-event)
  (event ::filter-sweep-done :instrument :phat-bass)"
  [event-type & args]
  (.execute thread-pool #(handle-event (apply hash-map :event-type event-type
args))))

The only external code besides this file were a couple functions I added to the utilities for getting the number of available CPU cores and getting the arity of a function.

(defn cpu-count
  "Get the number of CPUs on this machine."
  []
  (.availableProcessors (Runtime/getRuntime)))

(defn arg-count 
  "Get the arity of a function." 
  [f] 
  (let [m (first (.getDeclaredMethods (class f))) 
        p (.getParameterTypes m)] 
    (alength p)))

This is probably not optimal in a couple areas, but it should get us pretty far. I added the arg-count detection because in my very first test of the code I got an error because I was trying to use an event handler that took no arguments.

  (on ::foo #(println "This is a foo event handler."))
  (event ::foo)

It’s so natural in clojure though, that I had to make it work. Now it will only pass the event argument if it sees that the arity isn’t zero, so these kinds of event handlers will work fine. Performing this reflection on every event handler might be a bit of useless overhead, but until we get to that level of optimization I’m not going to worry about it.

The default right now is to use a thread pool with as many threads as there are available CPU cores. This is just a guess as to what will actually provide efficient handling of events though, so if we start using the event system for high-throughput events we may want to do some experiments.

Internet Exchange

This is a well done video about the decentralized architecture of the internet and exchange points. It’s kind of a video info-graphic.

I remember dreaming of animations like this while studying networking, algorithms and data structures. I hope one day there are graphics and animation libraries made to visualize program structures like this, so you could just insert some event sends to update the state of the visualization and it would take care of the rest. (i.e. pretty graphics, interpolation, etc…) There are so many chart and graph libraries out there, but it seems like the world of info-graphics could be so much richer.

A New Os Abstraction

Is there a better metaphor than the Unix file interface for a 21st century OS, or are OS level services even the right level to be unifying behind a common abstraction? Read here first…

http://bywicket.com/users/mikel/weblog/fbc2a/Closos.html

Using objects, closures, prototypes, frames or whatever you want to call chunks of state and code, seems like the wrong approach to me. Unix files are really encompass two different types of abstractions: a hierarchical namespace interface using directories, and a byte stream oriented interface for doing I/O. Using something as generic as a closure or an object seems like going against the benefits of finding a unified interface.

I think the next generation metaphor will be some kind of database layer with a standardized data model and a powerful query system. The utility of google style full-text search, spotlight and quicksilver for intelligent access to data and applications, and the rich libraries modern programming languages have for interacting with sequences and databases all point to a DB abstraction. Limiting the functional capabilities to a query language also makes this type of abstraction suitable for distributed data access layers, where you wouldn’t want to be executing foreign code.Edit2:33 pm

Coming Alive

Some good reading today:

On John Koza’s software evolution system that has successfully evolved multiple inventions that have been awarded patents. This could become a very interesting area as computing power and cheap access to the cloud keeps ramping up.

John Koza’s Invention Machine

On the present and future of games that blend reality and the virtual world. Rode your bike to work today instead of driving, 200 points! Cooked your own dinner… boooo-yah, 500 points. You just saved on your health insurance payment for the day.

The Future of Games

On Emmy Miller, a software composer (as in a program that learns and autonomously generates pieces of music) that is coming out with an album shortly.

Cyborg Composer

Blog Engines Are Overrated

Well after spending far too long experimenting with a variety of blog engines and other annoying “web applications”, I’ve realized that really I want to be able to blog using the same tools that I use to develop software. Why waste so much time and effort writing posts in an HTML form window when you sit inside of a text editor most of your life anyway? So, here we go again. Now using Jekyll, the git-hub style, blogging-plus, toolchain.