using System;
using System.Runtime.Serialization;
using Microsoft.Xna.Framework.Input;
namespace MLEM.Input {
///
/// A generic input represents any kind of input key.
/// This includes for keyboard keys, for mouse buttons and for gamepad buttons.
/// For creating and extracting inputs from a generic input, the implicit operators and can additionally be used.
/// Note that this type is serializable using .
///
[DataContract]
public readonly struct GenericInput : IEquatable {
///
/// The of this generic input's current .
///
[DataMember]
public readonly InputType Type;
[DataMember]
private readonly int value;
///
/// Returns this generic input's .
///
/// If this generic input's is not or .
public Keys Key => this.Type == InputType.None ? 0 : this.Type == InputType.Keyboard ? (Keys) this.value : throw new InvalidOperationException();
///
/// Returns this generic input's .
///
/// If this generic input's is not .
public MouseButton MouseButton => this.Type == InputType.Mouse ? (MouseButton) this.value : throw new InvalidOperationException();
///
/// Returns this generic input's .
///
/// If this generic input's is not or .
public Buttons Button => this.Type == InputType.None ? 0 : this.Type == InputType.Gamepad ? (Buttons) this.value : throw new InvalidOperationException();
///
/// Creates a new generic input from the given keyboard .
///
/// The key to convert.
public GenericInput(Keys key) : this(InputType.Keyboard, (int) key) {}
///
/// Creates a new generic input from the given .
///
/// The button to convert.
public GenericInput(MouseButton button) : this(InputType.Mouse, (int) button) {}
///
/// Creates a new generic input from the given gamepad .
///
/// The button to convert.
public GenericInput(Buttons button) : this(InputType.Gamepad, (int) button) {}
///
/// Creates a new generic input from the given value.
/// If the value is a , or , the appropriate and value will be set. Otherwise, the will be set to .
///
/// The value to convert.
public GenericInput(Enum value) {
this.Type = value is MouseButton ? InputType.Mouse : value is Keys ? InputType.Keyboard : value is Buttons ? InputType.Gamepad : InputType.None;
this.value = Convert.ToInt32(value);
}
private GenericInput(InputType type, int value) {
this.Type = type;
this.value = value;
}
/// Returns this generic input, converted to a string.
/// This generic input, converted to a string.
public override string ToString() {
switch (this.Type) {
case InputType.Mouse:
return $"Mouse{(MouseButton) this}";
case InputType.Keyboard:
return ((Keys) this).ToString();
case InputType.Gamepad:
return $"Gamepad{(Buttons) this}";
default:
return this.Type.ToString();
}
}
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the other parameter; otherwise, false.
public bool Equals(GenericInput other) {
return this.Type == other.Type && this.value == other.value;
}
/// Indicates whether this instance and a specified object are equal.
/// The object to compare with the current instance.
/// true if obj and this instance are the same type and represent the same value; otherwise, false.
public override bool Equals(object obj) {
return obj is GenericInput other && this.Equals(other);
}
/// Returns the hash code for this instance.
/// A 32-bit signed integer that is the hash code for this instance.
public override int GetHashCode() {
return (int) this.Type * 397 ^ this.value;
}
///
/// Compares the two generic input instances for equality using
///
/// The left input
/// The right input
/// Whether the two generic inputs are equal
public static bool operator ==(GenericInput left, GenericInput right) {
return left.Equals(right);
}
///
/// Compares the two generic input instances for inequality using
///
/// The left input
/// The right input
/// Whether the two generic inputs are not equal
public static bool operator !=(GenericInput left, GenericInput right) {
return !left.Equals(right);
}
///
/// Converts a to a generic input.
///
/// The keys to convert
/// The resulting generic input
public static implicit operator GenericInput(Keys key) {
return new GenericInput(key);
}
///
/// Converts a to a generic input.
///
/// The button to convert
/// The resulting generic input
public static implicit operator GenericInput(MouseButton button) {
return new GenericInput(button);
}
///
/// Converts a to a generic input.
///
/// The buttons to convert
/// The resulting generic input
public static implicit operator GenericInput(Buttons button) {
return new GenericInput(button);
}
///
/// Converts a generic input to a .
///
/// The input to convert
/// The resulting keys
/// If the given generic input's is not or
public static implicit operator Keys(GenericInput input) {
return input.Key;
}
///
/// Converts a generic input to a .
///
/// The input to convert
/// The resulting button
/// If the given generic input's is not
public static implicit operator MouseButton(GenericInput input) {
return input.MouseButton;
}
///
/// Converts a generic input to a .
///
/// The input to convert
/// The resulting buttons
/// If the given generic input's is not
public static implicit operator Buttons(GenericInput input) {
return input.Button;
}
///
/// A type of input button.
///
[DataContract]
public enum InputType {
///
/// A type representing no value
///
[EnumMember]
None,
///
/// A type representing
///
[EnumMember]
Mouse,
///
/// A type representing
///
[EnumMember]
Keyboard,
///
/// A type representing
///
[EnumMember]
Gamepad
}
}
}