Input Mocking in XNA

I have updated my input library to a level where I think I can release it into the Nuclex Framework now. The design was tailored to make the input manager mockable (replaceable with a dummy object for unit testing), but the effort of mocking the entire input manager (versus just one input device) on an ad hoc basis was a bit too high (or too unreadable when using a dynamic mock object library).

So the final revision has mocked input devices and a matching input manager built in:

UML diagram showing the IInputService implemented by a real and a mock manager

You can now write code like this:

void Test() {
  var input = new MockInputManager();
  
  // Set up the object under test
  var consumer = SomeInputConsumer(input);
  
  input.GetMouse().MoveTo(12, 34);
  input.GetMouse().Press(MouseButtons.Left);
  input.GetMouse().Release(MouseButtons.Left);
  input.Update();
  
  var expectedPosition = new Vector2(12, 34);
  Assert.That(consumer.LastMouseClickPosition, Is.EqualTo(expectedPosition));
}

I also added support for WM_INPUT. Traditionally, mouse input is served via WM_MOUSEMOVE, but WM_INPUT offers sub-pixel accuracy. I think the term for this is “high definition mouse input”. After I had finished, I noticed that my Logitech G9x (5700 DPI) apparently doesn’t do high definition, so I disabled the WM_INPUT code for now.

As I understand it, WM_INPUT also leaves it to the driver whether the mouse reports relative movement (how far the mouse has moved since the last position report) or absolute movement (coordinates of the mouse cursor within a confined area). The latter is only being used by touchpads on notebooks as far as I can tell, but still…

I’ll have to think some more about this (and maybe lend me a Microsoft 1000 DPI “high definition” mouse :P). Either I leave out WM_INPUT entirely or I ignore WM_INPUT if the driver is reporting absolute positions or I use those absolutely positions as velocity (so touchpad players can still do shooters). Any comments?