using Cryville.Common; using Cryville.Common.Unity; using Cryville.Crtr.Ruleset; using Cryville.Input; using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace Cryville.Crtr.Config.UI { public class InputConfigPanel : MonoBehaviour { [SerializeField] ConfigPanelMaster m_configScene; [SerializeField] GameObject m_inputDialog; [SerializeField] Transform m_deviceList; [SerializeField] GameObject m_prefabListItem; [SerializeField] Transform m_entryList; [SerializeField] GameObject m_prefabInputConfigEntry; SimpleInputConsumer _consumer; public InputProxy proxy; readonly Dictionary _entries = new Dictionary(); int _applicableEntries; Identifier _sel; int _targetDim; PhysicalDimension? _targetPDim; bool _targetNotNull; public void OpenDialog(Identifier entry) { _sel = entry; var def = m_configScene.ruleset.Root.inputs[_sel]; _targetDim = def.dim; if (def.pdim != null) _targetPDim = ParsePhysicalDimension(def.pdim); else _targetPDim = null; _targetNotNull = def.notnull; m_inputDialog.SetActive(true); CallHelper.Purge(m_deviceList); _consumer.EnumerateEvents(ev => { }); _recvsrcs.Clear(); _applicableEntries = 1; AddSourceItem(null); } static PhysicalDimension ParsePhysicalDimension(string str) { var comps = str.Split(' ', StringSplitOptions.RemoveEmptyEntries); var result = new PhysicalDimension(); foreach (var comp in comps) { int dim = 1; if (comp.Length > 1) dim = int.Parse(comp.Substring(1)); switch (comp[0]) { case 'T': result.Time += dim; break; case 'L': result.Length += dim; break; case 'M': result.Mass += dim; break; case 'I': result.ElectricCurrent += dim; break; case '\x0398': case 'H': result.ThermodynamicTemperature += dim; break; case 'N': result.AmountOfSubstance += dim; break; case 'J': result.LuminousIntensity += dim; break; default: throw new ArgumentException(string.Format("Invalid dimension symbol {0}", comp[0])); } } return result; } public void CloseDialog() { m_inputDialog.SetActive(false); } public void CloseDialog(InputSource? src) { proxy.Set(new InputProxyEntry { Target = _sel, Source = src, }); CloseDialog(); } public void OnConfigEnable() { CallHelper.Purge(m_entryList); _entries.Clear(); _consumer = new SimpleInputConsumer(Game.InputManager); _consumer.Activate(); foreach (var i in m_configScene.ruleset.Root.inputs) { var e = GameObject.Instantiate(m_prefabInputConfigEntry, m_entryList.transform).GetComponent(); _entries.Add(i.Key, e); e.SetKey(this, i.Key); OnProxyChanged(this, proxy[i.Key]); } proxy.ProxyChanged += OnProxyChanged; } public void OnConfigDisable() { _consumer.Deactivate(); } void OnProxyChanged(object sender, ProxyChangedEventArgs e) { _entries[e.Name].OnProxyChanged(e); } void Start() { _d_HandleInputEvent = HandleInputEvent; } readonly List _recvsrcs = new List(); void Update() { if (m_inputDialog.activeSelf) { _consumer.EnumerateEvents(_d_HandleInputEvent); } } Action _d_HandleInputEvent; void HandleInputEvent(InputEvent ev) { AddSourceItem(ev.Identifier.Source); } void AddSourceItem(InputSource? src) { if (_recvsrcs.Contains(src)) return; _recvsrcs.Add(src); var obj = Instantiate(m_prefabListItem, m_deviceList); var text = obj.transform.Find("Text").GetComponent(); text.text = src == null ? "(None)" : src.Value.Handler.GetTypeName(src.Value.Type); var btn = obj.GetComponent