using System;
using System.Collections.Generic;
using Chernobyl.Collections.Generic.Event;
using Chernobyl.Event;
using Chernobyl.Mathematics.Mechanics;
namespace Chernobyl.Input.Controls.Axis
{
///
/// A helper class that allows for easy creation of IAxis classes.
///
public abstract class AxisControl : Control, IAxisControl
{
///
/// Constructor.
///
/// The services class that contains the
/// dependencies that are to be injected into this object.
protected AxisControl(IEventCollection services)
: this(services, new List())
{ }
///
/// Constructor.
///
/// The services class that contains the
/// dependencies that are to be injected into this object.
/// The list to use to hold the children controls.
protected AxisControl(IEventCollection services, ICollection childList)
: base(childList)
{
Sensitivity = 1.0f;
}
///
/// The amount the axis was in a certain direction
/// (the previous value of "CurrentValue").
///
public float PreviousValue { get; protected set; }
///
/// The amount the axis is in a certain direction currently.
///
public float CurrentValue { get; private set; }
///
/// The amount of change, from the axis' to
/// its .
///
public float ChangeAmount { get; private set; }
///
/// Invoked when this axis moves.
///
public event EventHandler> OnMove;
///
/// Invoked when this axis moves up.
///
public event EventHandler> OnUp;
///
/// Invoked when this axis moves down.
///
public event EventHandler> OnDown;
///
/// Calculates the new and
/// and raises events if necessary.
///
/// The amount of time that has
/// passed since this update was last called.
public override void Update(TimeSpan deltaTime)
{
// The PreviousValue must be set prior to retrieving the value from
// OverridableChangeAmount here because a derived class may use
// PreviousValue to calculate the OverridableChangeAmount (mouse
// axes may do this for example).
PreviousValue = CurrentValue;
ChangeAmount = OverridableChangeAmount * Sensitivity;
CurrentValue = PreviousValue + ChangeAmount;
// check if the new button state has changed
if (ChangeAmount != 0.0f)
{
// yes it has
EventArgs e = new EventArgs(this);
if (ChangeAmount < 0.0f)
{
InvokeOnDown(this, e);
InvokeOnMove(this, e);
}
else
{
InvokeOnUp(this, e);
InvokeOnMove(this, e);
}
}
base.Update(deltaTime);
}
///
/// The sensitivity of this axis. A sensitivity of 1 is the default.
/// A lower sensitivity (between 0.0 and 1.0) causes this axis to report
/// a smaller number for it's current value while a greater sensitivity
/// (greater than 1.0) causes the value reported to be greater.
///
public float Sensitivity { get; set; }
///
/// The amount of change, from the axis'
/// to its . Implementors should return
/// the raw change amount and not try to apply
/// to the returned value. The
/// class will apply the
/// value for you.
///
protected abstract float OverridableChangeAmount { get; }
///
/// Invokes the OnMove event. This method allows
/// derived classes to invoke the event which is
/// not directly allowed.
///
/// The invoker of the event.
/// The events arguments.
protected void InvokeOnMove(IAxisControl sender, EventArgs e)
{
if (OnMove != null)
OnMove(sender, e);
}
///
/// Invokes the OnDown event. This method allows
/// derived classes to invoke the event which is
/// not directly allowed.
///
/// The invoker of the event.
/// The events arguments.
protected void InvokeOnDown(IAxisControl sender, EventArgs e)
{
if (OnDown != null)
OnDown(sender, e);
}
///
/// Invokes the OnUp event. This method allows
/// derived classes to invoke the event which is
/// not directly allowed.
///
/// The invoker of the event.
/// The events arguments.
protected void InvokeOnUp(IAxisControl sender, EventArgs e)
{
if (OnUp != null)
OnUp(sender, e);
}
///
/// Holds all the action handler delegates that should
/// be called when the the axis is moved.
///
Action MoveActionHandlers { get; set; }
///
/// Holds all the action handler delegates that should
/// be called when the the axis is pressed moved down.
///
Action DownActionHandlers { get; set; }
///
/// Holds all the action handler delegates that should
/// be called when the the axis is moved up.
///
Action UpActionHandlers { get; set; }
}
}