refactor(events): rewrite EventStream code

Structs now register themselves as a listener. The EventStream
will use introspection to determine what handlers the listener
implements.