using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace TrueCraft.Client.Input
{
///
/// Encapsulates keyboard input in an event-driven manner.
///
public sealed class KeyboardComponent : GameComponent
{
///
/// Raised when a key for this keyboard component is pressed.
///
public event EventHandler KeyDown;
///
/// Raised when a key for this keyboard component is released.
///
public event EventHandler KeyUp;
///
/// Gets the state for this keyboard component.
///
public KeyboardState State { get; private set; }
///
/// Creates a new keyboard component.
///
/// The parent game for the component.
public KeyboardComponent(Game game)
: base(game)
{
}
///
/// Initializes this keyboard component.
///
public override void Initialize()
{
State = Keyboard.GetState();
base.Initialize();
}
///
/// Updates this keyboard component.
///
/// The game time for the update.
public override void Update(GameTime gameTime)
{
var newState = Keyboard.GetState();
Process(newState, State);
State = newState;
base.Update(gameTime);
}
///
/// Processes a change between two states.
///
/// The new state.
/// The old state.
private void Process(KeyboardState newState, KeyboardState oldState)
{
var currentKeys = newState.GetPressedKeys();
var lastKeys = oldState.GetPressedKeys();
// LINQ was a saviour here.
var pressed = currentKeys.Except(lastKeys);
var unpressed = lastKeys.Except(currentKeys);
foreach (var key in pressed)
{
var args = new KeyboardKeyEventArgs(key, true);
if (KeyDown != null)
KeyDown(this, args);
}
foreach (var key in unpressed)
{
var args = new KeyboardKeyEventArgs(key, false);
if (KeyUp != null)
KeyUp(this, args);
}
}
///
/// Called when this keyboard component is being disposed of.
///
/// Whether Dispose() called this method.
protected override void Dispose(bool disposing)
{
if (disposing)
{
KeyDown = null;
KeyUp = null;
}
base.Dispose(disposing);
}
}
}