using Cryville.Common.Unity.Input; using System; using System.Collections.Generic; namespace Cryville.Crtr { public class InputProxy { readonly PdtRuleset _ruleset; readonly Dictionary _hash1 = new Dictionary(); readonly Dictionary _hash2 = new Dictionary(); readonly Dictionary _use = new Dictionary(); readonly Dictionary> _rev = new Dictionary>(); public event EventHandler ProxyChanged; public InputProxy(PdtRuleset ruleset) { _ruleset = ruleset; foreach (var i in ruleset.inputs) { _use.Add(i.Key, 0); _rev.Add(i.Key, new List()); } foreach (var i in ruleset.inputs) { if (i.Value.pass != null) { foreach (var p in i.Value.pass) _rev[p.Key].Add(i.Key); } } } public void Set(InputProxyEntry proxy) { var name = proxy.Target; if (_hash1.ContainsKey(name)) Remove(proxy); if (_use[proxy.Target] > 0) throw new InvalidOperationException("Input already assigned"); if (proxy.Source != null) { _hash1.Add(proxy.Target, proxy); _hash2.Add(proxy.Source.Value, proxy); IncrementUseRecursive(name); IncrementReversedUseRecursive(name); } } void Remove(InputProxyEntry proxy) { var name = proxy.Target; _hash2.Remove(_hash1[name].Source.Value); _hash1.Remove(name); DecrementUseRecursive(name); DecrementReversedUseRecursive(name); } public bool IsUsed(InputSource src) { return _hash2.ContainsKey(src); } void IncrementUseRecursive(string name) { BroadcastProxyChanged(name); var passes = _ruleset.inputs[name].pass; if (passes != null) { foreach (var p in _ruleset.inputs[name].pass) { _use[p.Key]++; IncrementUseRecursive(p.Key); } } } void IncrementReversedUseRecursive(string name) { foreach (var p in _rev[name]) { _use[p]++; BroadcastProxyChanged(p); IncrementReversedUseRecursive(p); } } void DecrementUseRecursive(string name) { BroadcastProxyChanged(name); var passes = _ruleset.inputs[name].pass; if (passes != null) { foreach (var p in _ruleset.inputs[name].pass) { _use[p.Key]--; DecrementUseRecursive(p.Key); } } } void DecrementReversedUseRecursive(string name) { foreach (var p in _rev[name]) { _use[p]--; BroadcastProxyChanged(p); DecrementReversedUseRecursive(p); } } void BroadcastProxyChanged(string name) { ProxyChanged(this, new ProxyChangedEventArgs(name, _hash1.ContainsKey(name) ? _hash1[name].Source : null, _use[name] > 0)); } } public class ProxyChangedEventArgs : EventArgs { public string Name { get; private set; } public InputSource? Proxy { get; private set; } public bool Used { get; private set; } public ProxyChangedEventArgs(string name, InputSource? src, bool used) { Name = name; Proxy = src; Used = used; } } public class InputProxyEntry { public InputSource? Source { get; set; } public string Target { get; set; } public byte[] Mapping { get; private set; } } public sealed class InputProxyHandler : InputHandler { readonly InputDefinition _def; public InputProxyHandler(InputDefinition def, InputHandler src) : base() { _def = def; src.Callback = OnInput; } public override void Activate() { throw new NotImplementedException(); } public override void Deactivate() { throw new NotImplementedException(); } public override void Dispose(bool disposing) { throw new NotImplementedException(); } public override bool IsNullable(int type) { throw new NotImplementedException(); } public override byte GetDimension(int type) { throw new NotImplementedException(); } public override string GetTypeName(int type) { throw new NotImplementedException(); } public override double GetCurrentTimestamp() { throw new NotImplementedException(); } void OnInput(InputIdentifier id, InputVector vec) { } } }