using System; using UnityEngine; namespace Cryville.Common.Unity.Input { public delegate void InputEventDelegate(InputIdentifier id, InputVector vec); public abstract class InputHandler : IDisposable { public event InputEventDelegate OnInput; ~InputHandler() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public bool Activated { get; private set; } public void Activate() { if (Activated) return; Activated = true; ActivateImpl(); } protected abstract void ActivateImpl(); public void Deactivate() { if (!Activated) return; Activated = false; DeactivateImpl(); } protected abstract void DeactivateImpl(); public abstract void Dispose(bool disposing); public abstract bool IsNullable(int type); public abstract byte GetDimension(int type); public abstract string GetTypeName(int type); public abstract double GetCurrentTimestamp(); protected void Feed(int type, int id, InputVector vec) { var del = OnInput; if (del != null) del(new InputIdentifier { Source = new InputSource { Handler = this, Type = type }, Id = id }, vec); } } public struct InputSource : IEquatable { public InputHandler Handler { get; set; } public int Type { get; set; } public override bool Equals(object obj) { if (obj == null || !(obj is InputSource)) return false; return Equals((InputSource)obj); } public bool Equals(InputSource other) { return Handler == other.Handler && Type == other.Type; } public override int GetHashCode() { return Handler.GetHashCode() ^ Type; } public override string ToString() { return string.Format("{0}:{1}", ReflectionHelper.GetSimpleName(Handler.GetType()), Handler.GetTypeName(Type)); } public static bool operator ==(InputSource lhs, InputSource rhs) { return lhs.Equals(rhs); } public static bool operator !=(InputSource lhs, InputSource rhs) { return !lhs.Equals(rhs); } } public struct InputIdentifier : IEquatable { public InputSource Source { get; set; } public int Id { get; set; } public override bool Equals(object obj) { if (obj == null || !(obj is InputIdentifier)) return false; return Equals((InputIdentifier)obj); } public bool Equals(InputIdentifier other) { return Source == other.Source && Id == other.Id; } public override int GetHashCode() { return Source.GetHashCode() ^ ((Id << 16) | (Id >> 16)); } public override string ToString() { return string.Format("{0},{1}", Source, Id); } public static bool operator ==(InputIdentifier lhs, InputIdentifier rhs) { return lhs.Equals(rhs); } public static bool operator !=(InputIdentifier lhs, InputIdentifier rhs) { return !lhs.Equals(rhs); } } public struct InputVector { public double Time { get; set; } public bool IsNull { get; set; } public Vector3 Vector { get; set; } public InputVector(double time) { Time = time; IsNull = true; Vector = default(Vector3); } public InputVector(double time, Vector3 vector) { Time = time; IsNull = false; Vector = vector; } public override string ToString() { if (IsNull) return string.Format("null@{0}", Time); else return string.Format("{0}@{1}", Vector.ToString("G9"), Time); } } }