using System; using System.Collections.Generic; using System.Linq; using System.Text; using Google.Protobuf; using JNGame.Util.Types; using Newtonsoft.Json; namespace JNGame.Sync.System.View { /// /// Json的输入类 /// public class JNInputJson : JNInputBase { public byte[] Encoder() { return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this)); } public virtual object Decoder(byte[] bytes) { return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes),this.GetType()); } } public interface JNInputBase { /// /// 编码 /// /// public byte[] Encoder(); /// /// 解码 /// public object Decoder(byte[] bytes); } public abstract class JNInputSystem : SLogicSystem { protected abstract KeyValue TClass { get; } protected Dictionary TNewClass = new (); protected readonly Dictionary Inputs = new (); protected readonly Dictionary> SInputs = new (); protected Dictionary frame = new(); /// /// 移入数据 /// public void Enqueue(JNFrameInput input) { frame[input.NId] = input; } protected JNInputSystem() { OnInit(); OnApply(); } protected virtual void OnInit(){} /// /// 应用 /// protected virtual void OnApply() { TNewClass.Clear(); foreach (var key in TClass.Keys) { TNewClass.Add(key,Activator.CreateInstance(key) as JNInputBase); } } public override void OnSyncUpdate(int dt) { base.OnSyncUpdate(dt); UpdateSInputs(); } /// /// 获取同步输入(逻辑中获取 不可修改) /// /// /// public JNInputBase SInput(int clientId) where T : JNInputBase, new() { var key = TClass.Key2Value(typeof(T)); if (SInputs.TryGetValue(key, out var inputs)) { inputs.TryGetValue(clientId,out var input); return input; } return null; } public Dictionary SInput() where T : JNInputBase, new() { var key = TClass.Key2Value(typeof(T)); if (SInputs.TryGetValue(key, out var inputs)) { return inputs; } return new(); } public JNInputBase SInputOne() where T : JNInputBase, new() { var key = TClass.Key2Value(typeof(T)); if (SInputs.TryGetValue(key, out var inputs)) { if (inputs.Count > 0) { return inputs.Values.First(); } return null; } return null; } /// /// 获取输入 (禁止在逻辑中获取 只允许在UI层调用) /// /// /// public T Input() where T : JNInputBase,new() { if (!(Inputs.TryGetValue(TClass.Key2Value(typeof(T)),out var input))) { Inputs[TClass.Key2Value(typeof(T))] = input = new T(); } return (T)input; } /// /// 移出输入 /// /// public JNFrameInputs Dequeue() { JNFrameInputs inputs = new JNFrameInputs(); foreach (var key in Inputs.Keys) { var input = new JNFrameInput(); var info = Inputs[key]; input.NId = key; input.Input = ByteString.CopyFrom(info.Encoder()); inputs.Inputs.Add(input); } Inputs.Clear(); return inputs; } /// /// 移入输入 /// public void UpdateSInputs() { SInputs.Clear(); //解析输入 foreach (var kInput in frame) { var input = kInput.Value; var tClass = TClass.Value2Key(input.NId); if (!(SInputs.TryGetValue(input.NId,out var inputs))) { SInputs.Add(input.NId, inputs = new Dictionary()); } inputs.Add(input.ClientId,TNewClass[tClass].Decoder(input.Input.ToByteArray()) as JNInputBase); } frame.Clear(); } } }