mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-26 03:14:47 +00:00
197 lines
5.4 KiB
C#
197 lines
5.4 KiB
C#
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
|
|
{
|
|
|
|
/// <summary>
|
|
/// Json的输入类
|
|
/// </summary>
|
|
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
|
|
{
|
|
|
|
/// <summary>
|
|
/// 编码
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte[] Encoder();
|
|
|
|
/// <summary>
|
|
/// 解码
|
|
/// </summary>
|
|
public object Decoder(byte[] bytes);
|
|
|
|
}
|
|
|
|
public abstract class JNInputSystem : SLogicSystem
|
|
{
|
|
|
|
protected abstract KeyValue<Type, int> TClass { get; }
|
|
protected Dictionary<Type, JNInputBase> TNewClass = new ();
|
|
protected readonly Dictionary<int, JNInputBase> UIInputs = new ();
|
|
protected readonly Dictionary<int, Dictionary<int,JNInputBase>> SInputs = new ();
|
|
|
|
protected Dictionary<int,List<JNFrameInput>> frame = new();
|
|
|
|
/// <summary>
|
|
/// 移入数据
|
|
/// </summary>
|
|
public void Enqueue(JNFrameInput input)
|
|
{
|
|
if (!frame.ContainsKey(input.NId))
|
|
{
|
|
frame[input.NId] = new List<JNFrameInput>();
|
|
}
|
|
frame[input.NId].Add(input);
|
|
}
|
|
|
|
protected JNInputSystem()
|
|
{
|
|
OnInit();
|
|
OnApply();
|
|
}
|
|
|
|
protected virtual void OnInit(){}
|
|
|
|
/// <summary>
|
|
/// 应用
|
|
/// </summary>
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取同步输入(逻辑中获取 不可修改)
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public JNInputBase SInput<T>(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<int,JNInputBase> SInput<T>() where T : JNInputBase, new()
|
|
{
|
|
var key = TClass.Key2Value(typeof(T));
|
|
if (SInputs.TryGetValue(key, out var inputs))
|
|
{
|
|
return inputs;
|
|
}
|
|
return new();
|
|
}
|
|
public JNInputBase SInputOne<T>() 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取输入 (禁止在逻辑中获取 只允许在UI层调用)
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public T Input<T>() where T : JNInputBase,new()
|
|
{
|
|
lock (UIInputs)
|
|
{
|
|
if (!(UIInputs.TryGetValue(TClass.Key2Value(typeof(T)),out var input)))
|
|
{
|
|
UIInputs[TClass.Key2Value(typeof(T))] = input = new T();
|
|
}
|
|
return (T)input;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移出输入
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public JNFrameInputs Dequeue()
|
|
{
|
|
lock (UIInputs)
|
|
{
|
|
JNFrameInputs inputs = new JNFrameInputs();
|
|
foreach (var key in UIInputs.Keys)
|
|
{
|
|
var input = new JNFrameInput();
|
|
var info = UIInputs[key];
|
|
input.NId = key;
|
|
input.Input = ByteString.CopyFrom(info.Encoder());
|
|
inputs.Inputs.Add(input);
|
|
}
|
|
UIInputs.Clear();
|
|
return inputs;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移入输入
|
|
/// </summary>
|
|
public void UpdateSInputs()
|
|
{
|
|
|
|
SInputs.Clear();
|
|
//解析输入
|
|
foreach (var kInput in frame)
|
|
{
|
|
foreach (var input in kInput.Value)
|
|
{
|
|
var tClass = TClass.Value2Key(input.NId);
|
|
|
|
if (!(SInputs.TryGetValue(input.NId,out var inputs)))
|
|
{
|
|
SInputs.Add(input.NId, inputs = new Dictionary<int, JNInputBase>());
|
|
}
|
|
|
|
inputs[input.ClientId] = TNewClass[tClass].Decoder(input.Input.ToByteArray()) as JNInputBase;
|
|
}
|
|
kInput.Value.Clear();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} |