title: Design of a polling event API
body: <p>Say you were designing a C++ windowing library. It may or may not provide a callback API, but needs to provide a polling API to facilitate a functional style of programming.</p>
  
  <p>What would the polling API look like?</p>
  
  <h1>Some options</h1>
  
  <h2>SDL style</h2>
  
  <pre><code>struct Event {
      enum { MousePress, KeyPress } type;
      union {
          struct { Point pos; MouseButton b; } mousePress;
          struct { Modifiers mods; char key; } keyPress;
      };
  };
  void userCode() {
      for(;;) {
          Event e; if(pollEvent(&amp;e)) {
              switch(e.type) {
                  case MousePress: cout&lt;&lt;event.mousePress.pos.x; break; // not typesafe
                  case KeyPress: cout&lt;&lt;event.keyPress.key; break;
              }
          }
      }
  }
  </code></pre>
  
  <h2>State style</h2>
  
  <pre><code>struct Input {
      enum { Mouse, Keyboard, Nothing } whatChanged;
      MouseButtonsBitfield pressedButtons;
      bool keysPressed[keyCount];
  };
  void userCode() {
      for(;;) {
          Input in = pollInput();
          switch(in.whatChanged) {
              // typesafe yay
              case Mouse: cout &lt;&lt; "is LMB pressed? " &lt;&lt; bool(in.pressedButtons&amp;LeftButton); break;
              case Keyboard: cout &lt;&lt; "is A pressed? " &lt;&lt; in.keysPressed['A']; break;
          }
      }
  }
  </code></pre>
  
  <h2>Fun functional pseudo-C++ style</h2>
  
  <pre><code>struct Event {
      // transforms listener by notifying it of event,
      // returns transormed listener. nondestructive.
      template&lt;class Listener&gt; // sadly invalid, templates can't be virtual.
                                                // a solution is to make Listener the base
                                                // of a hierarchy and make Listener::handle virtual
                                                // but then we're forced to use imperative style
      virtual Listener transform(Listener const&amp;) =0;
  };
  struct MousePress : Event { // yay we're extensible via inheritance
      template&lt;class Listener&gt;
      virtual Listener transform(Listener const&amp; listener) {
          return listener.handle(*this); // calls the MousePress overload
      }
      Point pos; MouseButton b;
  };
  struct KeyPress : Event {
      template&lt;class Listener&gt;
      virtual Listener transform(Listener const&amp; listener) {
          return listener.handle(*this); // calls the KeyPress overload
      }
      Modifiers mods; char key;
  };
  struct NoEvent : Event {
      template&lt;class Listener&gt;
      virtual Listener transform(Listener const&amp; listener) {
          return listener.handle(*this);
      }
  };
  struct UserWidget {
      UserWidget handle(NoEvent) {
          return UserWidget();
      }
      UserWidget handle(MousePress p) {
          return (UserWidget) { string("pressed at")+lex_cast&lt;string&gt;(p.pos)) };
      }
      UserWidget handle(KeyPress k) {
          return (UserWidget) { string("pressed key=")+lex_cast&lt;string&gt;(k.key)) };
      }
      string pendingOutput;
  };
  void userTick(UserWidget const&amp; w) {
      cout&lt;&lt;w.pendingOutput;
      userTick(pollEvent().transform(w));
  }
  void userCode() {
      userTick(UserWidget());
  }
  </code></pre>
  
  <p>Answers for other languages than C++ are OK, if they provide interesting insight.</p>
  
  <p>No comments on encapsulation please - yes public fields should really be accessors, i left that out for clarity.</p>