using System; using UnityEngine; namespace Cryville.Common.Unity.Input { public delegate void InputEventDelegate(InputIdentifier id, InputVector vec); public abstract class InputHandler : IDisposable { InputEventDelegate m_onInput; public event InputEventDelegate OnInput { add { if (m_onInput == null) Activate(); m_onInput -= value; m_onInput += value; } remove { if (m_onInput == null) return; m_onInput -= value; if (m_onInput == null) Deactivate(); } } ~InputHandler() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected abstract void Activate(); protected abstract void Deactivate(); 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 = m_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); } } }