Code structure cleanup. (2)
This commit is contained in:
159
Assets/Cryville/Crtr/Config/UI/InputConfigPanel.cs
Normal file
159
Assets/Cryville/Crtr/Config/UI/InputConfigPanel.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
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<Identifier, InputConfigPanelEntry> _entries = new Dictionary<Identifier, InputConfigPanelEntry>();
|
||||
|
||||
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<InputConfigPanelEntry>();
|
||||
_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<InputSource?> _recvsrcs = new List<InputSource?>();
|
||||
void Update() {
|
||||
if (m_inputDialog.activeSelf) {
|
||||
_consumer.EnumerateEvents(_d_HandleInputEvent);
|
||||
}
|
||||
}
|
||||
|
||||
Action<InputEvent> _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.text = src == null ? "(None)" : src.Value.Handler.GetTypeName(src.Value.Type);
|
||||
var btn = obj.GetComponent<Button>();
|
||||
if (src != null) {
|
||||
var tsrc = src.Value;
|
||||
bool flag = false;
|
||||
if (proxy.IsUsed(tsrc)) {
|
||||
text.text += " <size=9>(Used)</size>";
|
||||
}
|
||||
else if (tsrc.Handler.Dimension < _targetDim) {
|
||||
text.text += " <size=9>(Not Applicable)</size>";
|
||||
}
|
||||
else if (_targetPDim != null && tsrc.Handler.ReferenceCue.PhysicalDimension != _targetPDim) {
|
||||
text.text += " <size=9>(Not Applicable)</size>";
|
||||
}
|
||||
else if (!_targetNotNull && !tsrc.Handler.IsNullable) {
|
||||
text.text += " <size=9>(Not Applicable)</size>";
|
||||
}
|
||||
else flag = true;
|
||||
btn.interactable = flag;
|
||||
obj.transform.SetSiblingIndex(flag ? _applicableEntries++ : m_deviceList.childCount - 1);
|
||||
}
|
||||
else {
|
||||
obj.transform.SetSiblingIndex(0);
|
||||
}
|
||||
btn.onClick.AddListener(() => {
|
||||
CloseDialog(src);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user