using System; using System.Collections.Generic; using System.Reflection; namespace Cryville.Common.Unity.Input { /*public class InputManager { int newId = 0; int GetNewId() { newId++; return newId; } PointerHandler ptrHandler; readonly Queue ptrEv = new Queue(); readonly Dictionary ptr = new Dictionary(); double originTime; void Callback(int id, PointerInfo info) { /*if (info.Phase != PointerPhase.Update) Logger.Log( "main", 0, "Input", "[{0}, p{1}] {2} {3} {4} at {5} (cs:{6}, ori:{7}, prs:{8})", info.EventTime, info.ProcessTime, info.Type, id, info.Phase, info.Position, info.ContactSize, info.Orientation, info.Pressure );* lock (ptrEv) { ptrEv.Enqueue(info); ptr[id] = info; } } public void Init() { try { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { if (WindowsPointerHandler.IsSupported()) { ptrHandler = new WindowsPointerHandler(true, GetNewId, Callback); Logger.Log("main", 1, "Input", "Initialized windows pointer handler"); } else if (UnityTouchHandler.IsSupported()) { ptrHandler = new UnityTouchHandler(GetNewId, Callback); Logger.Log("main", 1, "Input", "Initialized multi-platform pointer handler"); } } else if (Application.platform == RuntimePlatform.Android) { /*if (AndroidTouchHandler.IsSupported()) { } else* if (UnityTouchHandler.IsSupported()) { ptrHandler = new UnityTouchHandler(GetNewId, Callback); Logger.Log("main", 1, "Input", "Initialized multi-platform pointer handler"); } } else { /*if (UnityPointerHandler.IsSupported()) { enableUnityTouch(); }* } } catch (Exception ex) { Logger.Log("main", 4, "Input", "An error occured while initializing pointer handler:\n{0}", ex); } if (ptrHandler == null) Logger.Log("main", 3, "Input", "Pointer input is not supported on this device"); } public void Activate() { if (ptrHandler != null) ptrHandler.Activate(); } public void Deactivate() { if (ptrHandler != null) ptrHandler.Deactivate(); ptr.Clear(); ptrEv.Clear(); } public void Dispose() { ptrHandler.Dispose(); } public void EnumeratePtrEvents(Action callback) { lock (ptrEv) { while (ptrEv.Count > 0) { var raw = ptrEv.Dequeue(); raw.OffsetTime(originTime); callback(raw); } } } public void EnumeratePointers(Action callback) { lock (ptrEv) { var upid = new List(); var rmid = new List(); foreach (var p in ptr) { var raw = p.Value; if (raw.Phase == PointerPhase.Stationary) raw.EventTime = raw.ProcessTime = Time; else raw.OffsetTime(originTime); callback(raw); if (raw.Phase == PointerPhase.Begin || raw.Phase == PointerPhase.Update) upid.Add(p.Key); if (raw.Phase == PointerPhase.End || raw.Phase == PointerPhase.Cancel) rmid.Add(p.Key); } foreach (var i in upid) { var p = ptr[i]; p.Phase = PointerPhase.Stationary; ptr[i] = p; } foreach (var i in rmid) ptr.Remove(i); // Logger.Log("main", 0, "Input", "Ptr count {0}", ptr.Count); } } public double Time { get { if (ptrHandler != null) return ptrHandler.GetCurrentTimestamp() - originTime; else return 0; } } public void SyncTime(double t) { if (ptrHandler != null) { originTime = ptrHandler.GetCurrentTimestamp() - t; Logger.Log("main", 0, "Input", "Sync time {0}", originTime); } } }*/ public class InputManager { static readonly List HandlerRegistries = new List { typeof(WindowsPointerHandler), typeof(UnityKeyHandler), typeof(UnityKeyHandler), typeof(UnityMouseHandler), typeof(UnityTouchHandler), }; readonly List _handlers = new List(); readonly Dictionary _timeOrigins = new Dictionary(); readonly object _lock = new object(); readonly Dictionary _vectors = new Dictionary(); readonly List _events = new List(); public InputManager() { var cb = new InputEventDelegate(Callback); foreach (var t in HandlerRegistries) { try { if (!typeof(InputHandler).IsAssignableFrom(t)) continue; var h = (InputHandler)ReflectionHelper.InvokeEmptyConstructor(t); h.Callback = Callback; _handlers.Add(h); _timeOrigins.Add(h, 0); Logger.Log("main", 1, "Input", "Initialized {0}", ReflectionHelper.GetSimpleName(t)); } catch (TargetInvocationException ex) { Logger.Log("main", 1, "Input", "Cannot initialize {0}: {1}", ReflectionHelper.GetSimpleName(t), ex.InnerException.Message); } } } public void Activate() { lock (_lock) { _events.Clear(); } foreach (var h in _handlers) h.Activate(); } public void SyncTime(double time) { foreach (var h in _handlers) { _timeOrigins[h] = time - h.GetCurrentTimestamp(); } } public void Deactivate() { foreach (var h in _handlers) h.Deactivate(); } void Callback(InputIdentifier id, InputVector vec) { lock (_lock) { double timeOrigin = _timeOrigins[id.Source.Handler]; vec.Time += timeOrigin; InputVector vec0; if (_vectors.TryGetValue(id, out vec0)) { _events.Add(new InputEvent { Id = id, From = vec0, To = vec, }); if (vec.IsNull) _vectors.Remove(id); else _vectors[id] = vec; } else { _events.Add(new InputEvent { Id = id, From = new InputVector(vec.Time), To = vec, }); _vectors.Add(id, vec); } } } public void EnumerateEvents(Action cb) { lock (_lock) { foreach (var ev in _events) cb(ev); _events.Clear(); } } } }