From f311eb5e8df069c2e7d4192b6c4ff740c5447192 Mon Sep 17 00:00:00 2001 From: PopSlime Date: Mon, 7 Nov 2022 12:21:50 +0800 Subject: [PATCH] Implement InputProxy. --- .../Common/Unity/Input/InputManager.cs | 3 +- Assets/Cryville/Crtr/ChartPlayer.cs | 25 +++- Assets/Cryville/Crtr/Config/InputConfig.cs | 2 +- Assets/Cryville/Crtr/InputProxy.cs | 107 +++++++++++++----- Assets/Cryville/Crtr/Judge.cs | 2 + Assets/Cryville/Crtr/PropSrc.cs | 6 +- 6 files changed, 109 insertions(+), 36 deletions(-) diff --git a/Assets/Cryville/Common/Unity/Input/InputManager.cs b/Assets/Cryville/Common/Unity/Input/InputManager.cs index 2e6f272..9de48a9 100644 --- a/Assets/Cryville/Common/Unity/Input/InputManager.cs +++ b/Assets/Cryville/Common/Unity/Input/InputManager.cs @@ -11,7 +11,8 @@ namespace Cryville.Common.Unity.Input { typeof(UnityMouseHandler), typeof(UnityTouchHandler), }; - readonly List _handlers = new List(); + // TODO set private + public readonly List _handlers = new List(); readonly Dictionary _timeOrigins = new Dictionary(); readonly object _lock = new object(); readonly Dictionary _vectors = new Dictionary(); diff --git a/Assets/Cryville/Crtr/ChartPlayer.cs b/Assets/Cryville/Crtr/ChartPlayer.cs index 9913330..56a1558 100644 --- a/Assets/Cryville/Crtr/ChartPlayer.cs +++ b/Assets/Cryville/Crtr/ChartPlayer.cs @@ -3,6 +3,7 @@ using Cryville.Common; using Cryville.Common.Plist; +using Cryville.Common.Unity.Input; using Cryville.Crtr.Event; using Newtonsoft.Json; using System; @@ -65,6 +66,8 @@ namespace Cryville.Crtr { public static Dictionary motionRegistry = new Dictionary(); public static PdtEvaluator etor; + + InputProxy inputProxy; ~ChartPlayer() { Dispose(); @@ -381,7 +384,23 @@ namespace Cryville.Crtr { } Logger.Log("main", 0, "Load/Prehandle", "Initializing states"); cbus.BroadcastInit(); - Game.InputManager.Activate(); + + inputProxy = new InputProxy(pruleset, judge); + foreach (var i in Game.InputManager._handlers) { + /*if (i is UnityKeyHandler) { + inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.Z }, Target = "track0" }); + inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.X }, Target = "track1" }); + inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.Comma }, Target = "track2" }); + inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.Period }, Target = "track3" }); + break; + }*/ + if (i is UnityMouseHandler) { + inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = 0 }, Target = "screen_x" }); + break; + } + } + inputProxy.Activate(); + if (logEnabled) ToggleLogs(); Logger.Log("main", 0, "Load/Prehandle", "Cleaning up"); GC.Collect(); @@ -390,7 +409,7 @@ namespace Cryville.Crtr { Logger.Log("main", 1, "Load/Prehandle", "Prehandling done ({0}ms)", timer.Elapsed.TotalMilliseconds); Game.AudioSequencer.Playing = true; Thread.Sleep((int)(Game.AudioClient.BufferPosition - Game.AudioClient.Position)); - Game.InputManager.SyncTime(cbus.Time); + // TODO SyncTime(cbus.Time); started = true; } catch (Exception ex) { @@ -408,7 +427,7 @@ namespace Cryville.Crtr { if (bbus != null) bbus.Dispose(); if (tbus != null) tbus.Dispose(); if (nbus != null) nbus.Dispose(); - // Game.InputManager.Deactivate(); + inputProxy.Deactivate(); foreach (var t in texs) Texture.Destroy(t.Value); Logger.Log("main", 1, "Game", "Stopped"); } diff --git a/Assets/Cryville/Crtr/Config/InputConfig.cs b/Assets/Cryville/Crtr/Config/InputConfig.cs index ed9d02d..6900008 100644 --- a/Assets/Cryville/Crtr/Config/InputConfig.cs +++ b/Assets/Cryville/Crtr/Config/InputConfig.cs @@ -64,7 +64,7 @@ namespace Cryville.Crtr.Config { }); if (ruleset.format != 1) throw new FormatException("Invalid ruleset file version"); ruleset.LoadPdt(dir); - _proxy = new InputProxy(ruleset.Root); + _proxy = new InputProxy(ruleset.Root, null); foreach (var i in ruleset.Root.inputs) { var e = GameObject.Instantiate(m_prefabInputConfigEntry).GetComponent(); e.transform.SetParent(m_entryList.transform); diff --git a/Assets/Cryville/Crtr/InputProxy.cs b/Assets/Cryville/Crtr/InputProxy.cs index 64173c2..65b677a 100644 --- a/Assets/Cryville/Crtr/InputProxy.cs +++ b/Assets/Cryville/Crtr/InputProxy.cs @@ -4,19 +4,13 @@ using Cryville.Common.Unity.Input; using System; using System.Collections.Generic; using UnityEngine; -using Logger = Cryville.Common.Logger; namespace Cryville.Crtr { public class InputProxy { readonly PdtEvaluator _etor; readonly PdtRuleset _ruleset; - readonly Dictionary _tproxies = new Dictionary(); - readonly Dictionary _sproxies = new Dictionary(); - readonly Dictionary _use = new Dictionary(); - readonly Dictionary> _rev = new Dictionary>(); - readonly Dictionary _vecs = new Dictionary(); - public event EventHandler ProxyChanged; - public InputProxy(PdtRuleset ruleset) { + readonly Judge _judge; + public InputProxy(PdtRuleset ruleset, Judge judge) { unsafe { fixed (byte* ptr = _vecbuf) { *(int*)(ptr + 3 * sizeof(float)) = PdtInternalType.Number; @@ -24,6 +18,7 @@ namespace Cryville.Crtr { } _etor = ChartPlayer.etor; _ruleset = ruleset; + _judge = judge; foreach (var i in ruleset.inputs) { _use.Add(i.Key, 0); _rev.Add(i.Key, new List()); @@ -36,6 +31,11 @@ namespace Cryville.Crtr { } } #region Settings + readonly Dictionary _tproxies = new Dictionary(); + readonly Dictionary _sproxies = new Dictionary(); + readonly Dictionary _use = new Dictionary(); + readonly Dictionary> _rev = new Dictionary>(); + public event EventHandler ProxyChanged; public void Set(InputProxyEntry proxy) { var name = proxy.Target; if (_tproxies.ContainsKey(name)) Remove(proxy); @@ -103,32 +103,49 @@ namespace Cryville.Crtr { #region Handling public void Activate() { foreach (var src in _sproxies.Keys) src.Handler.Activate(); } public void Deactivate() { foreach (var src in _sproxies.Keys) src.Handler.Deactivate(); } + readonly object _lock = new object(); - void OnInput(InputIdentifier id, InputVector vec) { + static readonly int _var_value = IdentifierManager.SharedInstance.Request("value"); + static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft"); + static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt"); + static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary(); + readonly byte[] _numbuf = new byte[sizeof(float)]; + readonly byte[] _numbuf2 = new byte[sizeof(float)]; + readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)]; + readonly Dictionary _vect = new Dictionary(); + readonly Dictionary _vecs = new Dictionary(); + unsafe void LoadNum(float value) { + fixed (byte* ptr = _numbuf) *(float*)ptr = value; + } + unsafe void LoadNum2(float value) { + fixed (byte* ptr = _numbuf2) *(float*)ptr = value; + } + unsafe void OnInput(InputIdentifier id, InputVector vec) { lock (_lock) { InputProxyEntry proxy; if (_sproxies.TryGetValue(id.Source, out proxy)) { - OnInput(id, vec, proxy.Target); + _etor.ContextCascadeInsert(); + float ft, tt = (float)vec.Time; + if (!_vect.TryGetValue(id, out ft)) ft = tt; + LoadNum(ft); _etor.ContextCascadeUpdate(_var_ft, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf)); + LoadNum2(tt); _etor.ContextCascadeUpdate(_var_tt, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf2)); + _vect[id] = tt; + if (vec.IsNull) { + _etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Null, new byte[0])); + } + else { + fixed (byte* ptr = _vecbuf) { + *(Vector3*)ptr = vec.Vector; + } + _etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf)); + } + OnInput(id, proxy.Target); + _etor.ContextCascadeDiscard(); } } } - static readonly int _var_value = IdentifierManager.SharedInstance.Request("value"); - static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary(); - readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)]; - unsafe void OnInput(InputIdentifier id, InputVector vec, string target) { - _etor.ContextCascadeInsert(); - if (vec.IsNull) { - _etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Null, new byte[0])); - } - else { - fixed (byte* ptr = _vecbuf) { - *(Vector3*)ptr = vec.Vector; - } - _etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf)); - } - OnInput(id, target); - _etor.ContextCascadeDiscard(); - } + static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv"); + static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv"); unsafe void OnInput(InputIdentifier id, string target) { var def = _ruleset.inputs[target]; if (def.pass != null) { @@ -141,7 +158,17 @@ namespace Cryville.Crtr { } } else { - Logger.Log("main", 0, "Input/Proxy", "input recv {0}", target); + var pid = new ProxiedInputIdentifier { Source = id, Target = target }; + PropSrc.Arbitrary fv, tv = _etor.ContextCascadeLookup(_var_value); + if (!_vecs.TryGetValue(pid, out fv)) fv = new PropSrc.Arbitrary(PdtInternalType.Null, new byte[0]); + if (fv.Type != PdtInternalType.Null || tv.Type != PdtInternalType.Null) { + _etor.ContextCascadeInsert(); + _etor.ContextCascadeUpdate(_var_tv, tv); + _etor.ContextCascadeUpdate(_var_fv, fv); + _judge.Feed(target); + _etor.ContextCascadeDiscard(); + } + _vecs[pid] = tv; } } #endregion @@ -163,4 +190,28 @@ namespace Cryville.Crtr { public string Target { get; set; } public byte[] Mapping { get; private set; } } + + public struct ProxiedInputIdentifier : IEquatable { + public InputIdentifier Source { get; set; } + public string Target { get; set; } + public override bool Equals(object obj) { + if (obj == null || !(obj is ProxiedInputIdentifier)) return false; + return Equals((ProxiedInputIdentifier)obj); + } + public bool Equals(ProxiedInputIdentifier other) { + return Source == other.Source && Target == other.Target; + } + public override int GetHashCode() { + return Source.GetHashCode() ^ Target.GetHashCode(); + } + public override string ToString() { + return string.Format("{0}->{1}", Source, Target); + } + public static bool operator ==(ProxiedInputIdentifier lhs, ProxiedInputIdentifier rhs) { + return lhs.Equals(rhs); + } + public static bool operator !=(ProxiedInputIdentifier lhs, ProxiedInputIdentifier rhs) { + return !lhs.Equals(rhs); + } + } } diff --git a/Assets/Cryville/Crtr/Judge.cs b/Assets/Cryville/Crtr/Judge.cs index 76a8311..dffe702 100644 --- a/Assets/Cryville/Crtr/Judge.cs +++ b/Assets/Cryville/Crtr/Judge.cs @@ -14,6 +14,8 @@ namespace Cryville.Crtr { scores.Add(name, s.Value.init); } } + public void Feed(string target) { + } public void Feed(InputEvent ev) { } diff --git a/Assets/Cryville/Crtr/PropSrc.cs b/Assets/Cryville/Crtr/PropSrc.cs index 5424cd0..2515eeb 100644 --- a/Assets/Cryville/Crtr/PropSrc.cs +++ b/Assets/Cryville/Crtr/PropSrc.cs @@ -13,14 +13,14 @@ namespace Cryville.Crtr { } protected abstract void InternalGet(out int type, out byte[] value); public class Arbitrary : PropSrc { - readonly new int _type; + public int Type { get; private set; } readonly byte[] _value; public Arbitrary(int type, byte[] value) { - _type = type; + Type = type; _value = value; } protected override void InternalGet(out int type, out byte[] value) { - type = _type; + type = Type; value = _value; } }