You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
9.7 KiB
327 lines
9.7 KiB
using System; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using QFrameworkCP; |
|
using UnityEngine; |
|
using UnityEngine.Events; |
|
using LitJson; |
|
|
|
|
|
namespace JXSoft { |
|
//任何通讯类围绕DataEventModel进行 |
|
public abstract class DataEventModel : AbstractModel |
|
{ |
|
//管理消息收发响应控制 |
|
public IOCContainer mCommandContainer = new IOCContainer(); |
|
//消息接收响应 |
|
public UnityStringEvent onDataRecived = new UnityStringEvent(); |
|
//存放颜色信息(打印结果用) |
|
public Color printColor = Color.white; |
|
|
|
#region ReceiveFunctions |
|
public void receiveResponse<T>(string protocolData) where T : IResponse, new() |
|
{ |
|
//如果找不到对应命令,则添加命令 |
|
if (mCommandContainer.Get<ExcuteResponseCommand<T>>() == null) |
|
{ |
|
mCommandContainer.Register(new ExcuteResponseCommand<T>(new T())); |
|
} |
|
//找到命令后添加命令 |
|
mCommandContainer.Get<ExcuteResponseCommand<T>>().setProtocolData(protocolData); |
|
mCommandContainer.Get<ExcuteResponseCommand<T>>().setSender(getSender()); |
|
this.SendCommand(mCommandContainer.Get<ExcuteResponseCommand<T>>()); |
|
} |
|
/// <summary> |
|
/// 开启接收指定数据 |
|
/// </summary> |
|
/// <typeparam name="T">数据格式类型</typeparam> |
|
public void onReceive<T>() where T : IResponse, new() |
|
{ |
|
onDataRecived.AddListener(receiveResponse<T>); |
|
} |
|
/// <summary> |
|
/// 关闭接收指定数据 |
|
/// </summary> |
|
/// <typeparam name="T">数据格式类型</typeparam> |
|
public void offReceive<T>() where T : IResponse, new() |
|
{ |
|
onDataRecived.RemoveListener(receiveResponse<T>); |
|
} |
|
#endregion |
|
|
|
#region RequestFunctions |
|
/// <summary> |
|
/// sendDataRequest,data must be implements IRequest |
|
/// </summary> |
|
/// <typeparam name="T">RequestType</typeparam> |
|
/// <param name="request">Data</param> |
|
public void sendRequest<T>(T request) where T : IRequest |
|
{ |
|
if (mCommandContainer.Get<SendRequestCommand<T>>() == null) |
|
{ |
|
mCommandContainer.Register(new SendRequestCommand<T>(request,getSender())); |
|
} |
|
mCommandContainer.Get<SendRequestCommand<T>>().setRequest(request,getSender()); |
|
this.SendCommand(mCommandContainer.Get<SendRequestCommand<T>>()); |
|
} |
|
#endregion |
|
|
|
#region LinkStatusManage |
|
public abstract void setLinkState(int linkState); |
|
public abstract int getLinkState(); |
|
|
|
/// <summary> |
|
/// Start a link & server, you can override by you own fucntions |
|
/// </summary> |
|
/// <returns>is link success & server start success</returns> |
|
public virtual bool Start() { |
|
setLinkState((int)LinkStateDefault.Open); |
|
return true; |
|
} |
|
public virtual bool Close() { |
|
setLinkState((int)LinkStateDefault.Close); |
|
return true; |
|
} |
|
|
|
public virtual string getSender() { |
|
return "default"; |
|
} |
|
#endregion |
|
} |
|
|
|
public enum LinkStateDefault |
|
{ |
|
Close = 0, |
|
Open = 1 |
|
} |
|
|
|
#region Command |
|
/// <summary> |
|
/// 处理响应数据,添加对应的Command进行处理,需要提前生成命令池 |
|
/// </summary> |
|
/// <typeparam name="TResponse">响应数据格式</typeparam> |
|
public class ExcuteResponseCommand<TResponse> : AbstractCommand where TResponse : IResponse |
|
{ |
|
public string protocolData; |
|
public string sender; |
|
private TResponse response; |
|
private Color printColor = Color.white; |
|
public ExcuteResponseCommand(TResponse response) |
|
{ |
|
if (this.response == null) |
|
{ |
|
this.response = response; |
|
} |
|
} |
|
protected override void OnExecute() |
|
{ |
|
bool isSet = response.trySetData(protocolData); |
|
if (isSet) |
|
{ |
|
if (response.toProtocolData() != "") { |
|
Debug.Log("Received:" + response.toProtocolData() + response.GetType()); |
|
} |
|
this.SendEvent(new ResponseMsgEvent(response, sender)); |
|
} |
|
} |
|
public void setProtocolData(string protocolData) |
|
{ |
|
this.protocolData = protocolData; |
|
} |
|
public void setSender(string sender) { |
|
this.sender = sender; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 发送数据 |
|
/// </summary> |
|
/// <typeparam name="TRequest">发送数据格式</typeparam> |
|
public class SendRequestCommand<TRequest> : AbstractCommand where TRequest : IRequest |
|
{ |
|
public TRequest request; |
|
public string sender; |
|
public SendRequestCommand(TRequest request,string sender) |
|
{ |
|
this.request = request; |
|
this.sender = sender; |
|
} |
|
protected override void OnExecute() |
|
{ |
|
this.SendEvent(new RequestMsgEvent(request,sender)); |
|
} |
|
public void setRequest(TRequest request,string sender) |
|
{ |
|
this.request = request; |
|
this.sender = sender; |
|
} |
|
} |
|
#endregion |
|
|
|
#region interface |
|
public interface IResponse |
|
{ |
|
/// <summary> |
|
/// 可以用于打印调试信息 |
|
/// </summary> |
|
/// <returns></returns> |
|
string toProtocolData(); |
|
/// <summary> |
|
/// 尝试填充数据,如果不符合相关协议规则,建议返回false,如果此处返回为false,则忽略该条数据响应。 |
|
/// </summary> |
|
/// <param name="protocolData">协议数据格式</param> |
|
/// <returns></returns> |
|
bool trySetData(string protocolData); |
|
} |
|
|
|
public interface IRequest |
|
{ |
|
//按照协议定义发送格式,转换为字符串发送 |
|
string toProtocolData(); |
|
} |
|
|
|
#endregion |
|
|
|
#region AbstractClass |
|
/// <summary> |
|
/// 使用抽象类时,必须满足可序列化 |
|
/// </summary> |
|
[Serializable] |
|
public abstract class AbstractJsonResponse : IResponse |
|
{ |
|
private string exceptionMsg; |
|
|
|
public virtual string toProtocolData() |
|
{ |
|
return ""; |
|
} |
|
public virtual bool trySetData(string json) |
|
{ |
|
try |
|
{ |
|
JsonUtility.FromJsonOverwrite(json,this); |
|
return true; |
|
} |
|
catch (Exception e) |
|
{ |
|
exceptionMsg = e.ToString(); |
|
Debug.Log(exceptionMsg); |
|
return false; |
|
} |
|
} |
|
} |
|
|
|
public abstract class AbstractJsonRequest : IRequest{ |
|
public string toProtocolData() |
|
{ |
|
return JsonMapper.ToJson(this); |
|
} |
|
} |
|
public class StringRequest : IRequest |
|
{ |
|
public string requestStr; |
|
public StringRequest() { |
|
requestStr = "No message"; |
|
} |
|
public StringRequest(string str) { |
|
requestStr = str; |
|
} |
|
public string toProtocolData() |
|
{ |
|
return requestStr; |
|
} |
|
} |
|
#endregion |
|
|
|
#region Extention |
|
public static class CanRegistMessageExtention { |
|
public static IUnRegister RegisterMessageEvent<TResponse>(this ICanRegisterEvent self, Action<TResponse> onEvent)where TResponse : IResponse |
|
{ |
|
return self.GetArchitecture().RegisterEvent<ResponseMsgEvent>(e=> { |
|
if (e.res.GetType() == typeof(TResponse)) { |
|
onEvent.Invoke((TResponse)e.res); |
|
} |
|
}); |
|
} |
|
} |
|
public static class CanRegistLinkStateExtention |
|
{ |
|
public static IUnRegister RegisterLinkStateEvent(this ICanRegisterEvent self,int linkState, Action onEvent) |
|
{ |
|
return self.GetArchitecture().RegisterEvent<LinkStateChangedEvent>(e => { |
|
if (e.linkState == linkState) |
|
{ |
|
onEvent.Invoke(); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 用于扩展类型结构 |
|
/// </summary> |
|
public static class IResponseExtention { |
|
|
|
public static bool isTypeOfJson(this IResponse self, string json) |
|
{ |
|
JsonData protocolData = new JsonData(); |
|
try |
|
{ |
|
protocolData = JsonMapper.ToObject(json); |
|
} |
|
catch { |
|
return false; |
|
} |
|
|
|
JsonData classData = JsonMapper.ToObject(JsonMapper.ToJson(self)); |
|
if (protocolData.Keys.Count != classData.Keys.Count) |
|
{ |
|
return false; |
|
} |
|
foreach (string key in classData.Keys) |
|
{ |
|
if (!protocolData.ContainsKey(key)) |
|
{ |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
} |
|
#endregion |
|
|
|
#region event |
|
public struct ResponseMsgEvent |
|
{ |
|
public IResponse res; |
|
public string sender; |
|
public ResponseMsgEvent(IResponse res_,string sender_) |
|
{ |
|
res = res_; |
|
sender = sender_; |
|
} |
|
}; |
|
public struct RequestMsgEvent |
|
{ |
|
public IRequest req; |
|
public string sender; |
|
public RequestMsgEvent(IRequest req_ ,string sender_) |
|
{ |
|
req = req_; |
|
sender = sender_; |
|
} |
|
} |
|
public struct LinkStateChangedEvent { |
|
public int linkState; |
|
public LinkStateChangedEvent(int linkState_) { |
|
linkState = linkState_; |
|
} |
|
} |
|
#endregion |
|
|
|
[Serializable] |
|
public class UnityStringEvent : UnityEvent<string> |
|
{ |
|
|
|
} |
|
} |