Commit 8778f464 authored by 潘栩锋's avatar 潘栩锋 🚴

添加 FObjBase.Reflect

parent 9c59bf6a
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FObjBase.Reflect
{
/// <summary>
/// 注册 event 返回类型;
/// 客户端,默认使用 Trigger_xxxx(xxxx为event名称),作为触发事件的函数,该函数的参数类型就是EventArgsType;
/// </summary>
public class PushAttribute : Attribute
{
public Type EventArgsType;
public string TriggerName;
public PushAttribute(Type eventArgsType)
{
EventArgsType = eventArgsType;
}
public PushAttribute(Type eventArgsType, string triggerName)
{
EventArgsType = eventArgsType;
TriggerName = triggerName;
}
}
/// <summary>
/// 注册远程调用返回类型
/// </summary>
public class CallAttribute : Attribute
{
public Type ReponseType;
public CallAttribute()
{
}
public CallAttribute(Type reponseType)
{
ReponseType = reponseType;
}
}
/// <summary>
/// 注册 它的PropertyChanged 事件,且枚举它的子属性,
/// 找到[PropertyPush] 递归 注册下去
/// </summary>
public class PropertyPushAttribute : Attribute
{
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{15F40C32-D546-4B2A-8D80-B3DDBCDAA690}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FObjBase.Reflect</RootNamespace>
<AssemblyName>FObjBase.Reflect</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CallAttribute.cs" />
<Compile Include="Reflect_OBJ_INTERFACE.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Reflect_Proxy.cs" />
<Compile Include="Reflect_SeviceClient.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FObjSys\FObjBase.csproj">
<Project>{abfe87d4-b692-4ae9-a8c0-1f470b8acbb8}</Project>
<Name>FObjBase</Name>
</ProjectReference>
<ProjectReference Include="..\..\Project.FLY.Misc\MISC\Misc.csproj">
<Project>{5ee61ac6-5269-4f0f-b8fa-4334fe4a678f}</Project>
<Name>Misc</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("FObjBaseReflect")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FObjBaseReflect")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("15f40c32-d546-4b2a-8d80-b3ddbcdaa690")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FObjBase.Reflect
{
public class Reflect_OBJ_INTERFACE
{
#region Push
public const UInt16 PUSH_Event = 101;
public const UInt16 PUSH_PropertyChanged = 102;
#endregion
#region CallFunction
public const UInt16 CALL_GetAllProperties = 100;
public const UInt16 CALL_SetProperty = 101;
public const UInt16 CALL_MethodInvoke = 102;
#endregion
public class ReflectData
{
public string name;
public JToken data;
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.ServiceModel.Security;
using System.Text;
using System.Threading.Tasks;
namespace FObjBase.Reflect
{
public class Reflect_Proxy : FObj
{
Type interfaceType;
object obj;
public bool ignoreSet = false;
List<AnyEvent> anyEvents = new List<AnyEvent>();
Dictionary<object, string> subProperties = new Dictionary<object, string>();
List<string> properties = new List<string>();
public Reflect_Proxy(int objsys_idx, UInt32 id, Type interfaceType, object obj) : base(objsys_idx)
{
ID = id;
this.interfaceType = interfaceType;
this.obj = obj;
InitPropertyChanged();
//处理[PropertyPush]
InitPropertyPush();
//处理[Push]
InitEventPush();
}
void InitPropertyChanged()
{
if (!typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
return;
//继承了INotifyPropertyChanged
((INotifyPropertyChanged)(this.obj)).PropertyChanged += Obj_PropertyChanged;
var interfaceTypes = new List<Type>();
interfaceTypes.Add(this.interfaceType);
interfaceTypes.AddRange(this.interfaceType.GetInterfaces());
var propertyInfos = new List<PropertyInfo>();
foreach (var ifaceType in interfaceTypes)
{
propertyInfos.AddRange(ifaceType.GetProperties());
}
foreach (var propertyInfo in propertyInfos) {
if (propertyInfo.GetCustomAttribute<JsonIgnoreAttribute>() != null)
continue;//这个不需要推送
if (properties.Contains(propertyInfo.Name))
continue;
properties.Add(propertyInfo.Name);
}
}
void InitEventPush()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(this.interfaceType);
interfaceTypes.AddRange(this.interfaceType.GetInterfaces());
var eventInfos = new List<EventInfo>();
foreach (var ifaceType in interfaceTypes) {
eventInfos.AddRange(ifaceType.GetEvents());
}
foreach (var eventInfo in eventInfos)
{
var pushAttribute = eventInfo.GetCustomAttribute<PushAttribute>();
if (pushAttribute == null)
continue;
if (anyEvents.Any(ae => ae.eventName == eventInfo.Name))
continue;//已经添加了
var anyEvent = new AnyEvent()
{
eventName = eventInfo.Name,
PushObjInfoEx = (msg) => {
var buf = Misc.Converter.StringToBytes(msg);
CurrObjSys.PushObjInfoEx(
this, Reflect_OBJ_INTERFACE.PUSH_Event,
buf);
}
};
//这个事件需要推送
eventInfo.AddEventHandler(obj, anyEvent.eventHandler);
anyEvents.Add(anyEvent);
}
}
void InitPropertyPush() {
//处理[PropertyPush]
var interfaceTypes = new List<Type>();
interfaceTypes.Add(this.interfaceType);
interfaceTypes.AddRange(this.interfaceType.GetInterfaces());
var propertyInfos = new List<PropertyInfo>();
foreach (var ifaceType in interfaceTypes)
propertyInfos.AddRange(ifaceType.GetProperties());
foreach (var propertyInfo in propertyInfos)
{
if (!IsPropertyPush(propertyInfo))
continue;
if (!properties.Contains(propertyInfo.Name)) {
properties.Add(propertyInfo.Name);
}
InitSubPropertyPush(this.obj.GetType().GetProperty(propertyInfo.Name), this.obj, null);
}
}
bool IsPropertyPush(PropertyInfo propertyInfo) {
if (propertyInfo.GetCustomAttribute<PropertyPushAttribute>() == null)
return false;//必须是[PropertyPush]
if (propertyInfo.CanWrite)
return false;//它只能是get,不能有set
if (!typeof(INotifyPropertyChanged).IsAssignableFrom(propertyInfo.PropertyType))
return false;//必须是从INotifyPropertyChanged派生的
return true;
}
void InitSubPropertyPush(PropertyInfo propertyInfo, object obj, string parentName)
{
//下级推送!!!!
var propertyValue = propertyInfo.GetValue(obj);
string path = parentName == null ? propertyInfo.Name : $"{parentName}.{propertyInfo.Name}";
subProperties.Add(propertyValue, path);
((INotifyPropertyChanged)(propertyValue)).PropertyChanged += Sub_PropertyChanged;
//继续向下找
var subPropertyInfos = propertyInfo.PropertyType.GetProperties();
foreach (var subPropertyInfo in subPropertyInfos)
{
if (!IsPropertyPush(subPropertyInfo))
continue;//必须是[PropertyPush]
InitSubPropertyPush(subPropertyInfo, propertyValue, path);
}
}
class AnyEvent
{
public string eventName;
public Action<string> PushObjInfoEx;
public EventHandler eventHandler;
public AnyEvent()
{
eventHandler = new EventHandler(Obj_AnyEvent);
}
void Obj_AnyEvent(object sender, EventArgs e)
{
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
{
name = eventName,
data = JObject.FromObject(e)
};
string reponse = JsonConvert.SerializeObject(rData);
PushObjInfoEx?.Invoke(reponse);
}
}
private void Obj_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
return;
if (interfaceType == null)
return;
if (!properties.Contains(e.PropertyName))
return;//这个不需要推送
var v = this.obj.GetType().GetProperty(e.PropertyName).GetValue(sender);
var jObject = new JObject();
if(v == null)
jObject.Add(e.PropertyName, null);
else
jObject.Add(e.PropertyName, JToken.FromObject(v));
string json = jObject.ToString(Formatting.None);
var buf = Misc.Converter.StringToBytes(json);
CurrObjSys.PushObjInfoEx(
this, Reflect_OBJ_INTERFACE.PUSH_PropertyChanged,
buf);
}
private void Sub_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
return;
if (!subProperties.ContainsKey(sender))
return;//异常, 不是子property
var type = sender.GetType();
var propertyInfo = type.GetProperty(e.PropertyName);
if (propertyInfo == null)
return;//获取失败!!!
if (propertyInfo.GetCustomAttribute<JsonIgnoreAttribute>() != null)
return;//这个不需要推送
string path = subProperties[sender];
string[] parentNames = path.Split('.');
if (parentNames.Count() == 0)
return;//分解出错
var v = propertyInfo.GetValue(sender);
var jObject = new JObject();
if(v == null)
jObject.Add(propertyInfo.Name, null);
else
jObject.Add(propertyInfo.Name, JToken.FromObject(v));
JObject jObject_parent = null;
for (int i = 0; i < parentNames.Count(); i++) {
int idx = parentNames.Count() - 1 - i;
jObject_parent = new JObject();
jObject_parent.Add(parentNames[idx], jObject);
jObject = jObject_parent;
}
string json = jObject_parent.ToString(Formatting.None);
CurrObjSys.PushObjInfoEx( this,
Reflect_OBJ_INTERFACE.PUSH_PropertyChanged,
Misc.Converter.StringToBytes(json));
}
public override void CallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] infodata)
{
switch (funcid)
{
case Reflect_OBJ_INTERFACE.CALL_GetAllProperties:
{
var jObject = new JObject();
var type = obj.GetType();
foreach (var propertyName in properties)
{
var propertyInfo = type.GetProperty(propertyName);
var v = propertyInfo.GetValue(obj);
if(v == null)
jObject.Add(propertyInfo.Name, null);
else
jObject.Add(propertyInfo.Name, JToken.FromObject(v));
}
string json = jObject.ToString(Formatting.None);
CurrObjSys.PushCallFunctionEx(from, srcid, ID, magic, funcid, Misc.Converter.StringToBytes(json));
}
break;
case Reflect_OBJ_INTERFACE.CALL_SetProperty:
{
string json = Misc.Converter.BytesToString(infodata);
ignoreSet = true;
JsonConvert.PopulateObject(json, obj);
ignoreSet = false;
}
break;
case Reflect_OBJ_INTERFACE.CALL_MethodInvoke:
{
string json = Misc.Converter.BytesToString(infodata);
var rData = JsonConvert.DeserializeObject<Reflect_OBJ_INTERFACE.ReflectData>(json);
var type = obj.GetType();
var methodInfo = type.GetMethod(rData.name);
var parameterInfos = methodInfo.GetParameters();
object[] parameters = new object[parameterInfos.Count()];
for (int i = 0; i < parameters.Count(); i++)
{
var ptype = parameterInfos[i].ParameterType;
var pname = parameterInfos[i].Name;
if (string.Compare(pname,"asyncDelegate",true)==0)
{
parameters[i] = new AsyncCBHandler(asyncDelegate);
}
else if (string.Compare(pname, "asyncContext", true) == 0)
{
parameters[i] = new CC { from = from, srcid = srcid, magic = magic, methodName = rData.name };
}
else
{
parameters[i] = rData.data[pname].ToObject(ptype);
}
}
methodInfo.Invoke(obj, parameters);
}
break;
}
}
void asyncDelegate(object asyncContext, object retData)
{
var cc = (CC)asyncContext;
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
{
name = cc.methodName,
data = JToken.FromObject(retData)
};
string json = JsonConvert.SerializeObject(rData);
CurrObjSys.PushCallFunctionEx(
cc.from,
cc.srcid,
ID,
cc.magic,
Reflect_OBJ_INTERFACE.CALL_MethodInvoke,
Misc.Converter.StringToBytes(json));
}
class CC
{
public IFConn from;
public UInt32 srcid;
public UInt32 magic;
public string methodName;
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace FObjBase.Reflect
{
public class Reflect_SeviceClient : FObjServiceClient
{
public bool ignoreSet;
protected virtual Type InterfaceType { get; }
List<AnyEvent> anyEvents = new List<AnyEvent>();
List<AnyCall> anyCalls = new List<AnyCall>();
class AnyEvent
{
public string name;
public string triggerName;
public Type retType;
}
class AnyCall
{
public string name;
public Type retType;
}
Dictionary<object,string> subProperties = new Dictionary<object, string>();
List<string> properties = new List<string>();
public Reflect_SeviceClient(UInt32 id) : base(id) {
init();
}
public Reflect_SeviceClient(UInt32 serviceId, string connName) : base(serviceId, connName) {
init();
}
void init() {
InitPropertyChanged();
InitPropertyPush();
InitEventPush();
InitCall();
}
void InitPropertyChanged()
{
if (!typeof(INotifyPropertyChanged).IsAssignableFrom(InterfaceType))
return;
//继承了INotifyPropertyChanged
this.PropertyChanged += Obj_PropertyChanged;
var interfaceTypes = new List<Type>();
interfaceTypes.Add(this.InterfaceType);
interfaceTypes.AddRange(this.InterfaceType.GetInterfaces());
var propertyInfos = new List<PropertyInfo>();
foreach (var ifaceType in interfaceTypes)
{
propertyInfos.AddRange(ifaceType.GetProperties());
}
foreach (var propertyInfo in propertyInfos)
{
if (propertyInfo.GetCustomAttribute<JsonIgnoreAttribute>() != null)
continue;//这个不需要推送
if (properties.Contains(propertyInfo.Name))
continue;
properties.Add(propertyInfo.Name);
}
}
void InitPropertyPush()
{
//处理[PropertyPush]
var interfaceTypes = new List<Type>();
interfaceTypes.Add(this.InterfaceType);
interfaceTypes.AddRange(this.InterfaceType.GetInterfaces());
var propertyInfos = new List<PropertyInfo>();
foreach (var ifaceType in interfaceTypes)
propertyInfos.AddRange(ifaceType.GetProperties());
foreach (var propertyInfo in propertyInfos)
{
if (!IsPropertyPush(propertyInfo))
continue;
InitSubPropertyPush(this.GetType().GetProperty(propertyInfo.Name), this, null);
}
}
bool IsPropertyPush(PropertyInfo propertyInfo)
{
if (propertyInfo.GetCustomAttribute<PropertyPushAttribute>() == null)
return false;//必须是[PropertyPush]
if (propertyInfo.CanWrite)
return false;//它只能是get,不能有set
if (!typeof(INotifyPropertyChanged).IsAssignableFrom(propertyInfo.PropertyType))
return false;//必须是从INotifyPropertyChanged派生的
return true;
}
void InitSubPropertyPush(PropertyInfo propertyInfo, object obj, string parentName)
{
//下级推送!!!!
var propertyValue = propertyInfo.GetValue(obj);
string path = parentName == null ? propertyInfo.Name : $"{parentName}.{propertyInfo.Name}";
subProperties.Add(propertyValue, path);
((INotifyPropertyChanged)(propertyValue)).PropertyChanged += Sub_PropertyChanged;
//继续向下找
var subPropertyInfos = propertyInfo.PropertyType.GetProperties();
foreach (var subPropertyInfo in subPropertyInfos)
{
if (!IsPropertyPush(subPropertyInfo))
continue;//必须是[PropertyPush]
InitSubPropertyPush(subPropertyInfo, propertyValue, path);
}
}
void InitEventPush()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(InterfaceType);
interfaceTypes.AddRange(InterfaceType.GetInterfaces());
var eventInfos = new List<EventInfo>();
foreach (var ifaceType in interfaceTypes)
{
eventInfos.AddRange(ifaceType.GetEvents());
}
foreach (var eventInfo in eventInfos)
{
var pushAttribute = eventInfo.GetCustomAttribute<PushAttribute>();
if (pushAttribute == null)
continue;
if (anyEvents.Any(ae => ae.name == eventInfo.Name))
continue;//已经添加了
string triggerName;
if (string.IsNullOrEmpty(pushAttribute.TriggerName))
{
triggerName = "Trigger_" + eventInfo.Name;
}
else {
triggerName = pushAttribute.TriggerName;
}
var anyEvent = new AnyEvent()
{
name = eventInfo.Name,
triggerName = triggerName,
retType = pushAttribute.EventArgsType
};
anyEvents.Add(anyEvent);
}
}
void InitCall()
{
var interfaceTypes = new List<Type>();
interfaceTypes.Add(InterfaceType);
interfaceTypes.AddRange(InterfaceType.GetInterfaces());
var methodInfos = new List<MethodInfo>();
foreach (var ifaceType in interfaceTypes)
{
methodInfos.AddRange(ifaceType.GetMethods());
}
foreach (var methodInfo in methodInfos)
{
var callAttribute = methodInfo.GetCustomAttribute<CallAttribute>();
if (callAttribute == null)
continue;
if (anyCalls.Any(ae => ae.name == methodInfo.Name))
continue;//已经添加了
var anyCall = new AnyCall()
{
name = methodInfo.Name,
retType = callAttribute.ReponseType
};
anyCalls.Add(anyCall);
}
}
private void Obj_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (!IsConnected)
return;
if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
return;
if (InterfaceType == null)
return;
if (!properties.Contains(e.PropertyName))
return;//这个不需要推送
var v = GetType().GetProperty(e.PropertyName).GetValue(sender);
var jObject = new JObject();
if(v == null)
jObject.Add(e.PropertyName, null);
else
jObject.Add(e.PropertyName, JToken.FromObject(v));
string json = jObject.ToString(Formatting.None);
CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
Reflect_OBJ_INTERFACE.CALL_SetProperty,
Misc.Converter.StringToBytes(json));
}
private void Sub_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (!IsConnected)
return;
if (ignoreSet)//从服务器接收的数据,不用再推送给服务器
return;
if (!subProperties.ContainsKey(sender))
return;//异常, 不是子property
var type = sender.GetType();
var propertyInfo = type.GetProperty(e.PropertyName);
if (propertyInfo == null)
return;//获取失败!!!
if (propertyInfo.GetCustomAttribute<JsonIgnoreAttribute>() != null)
return;//这个不需要推送
string path = subProperties[sender];
string[] parentNames = path.Split('.');
if (parentNames.Count() == 0)
return;
var v = propertyInfo.GetValue(sender);
var jObject = new JObject();
if(v == null)
jObject.Add(propertyInfo.Name, null);
else
jObject.Add(propertyInfo.Name, JToken.FromObject(v));
JObject jObject_parent = null;
for (int i = 0; i < parentNames.Count(); i++)
{
int idx = parentNames.Count() - 1 - i;
jObject_parent = new JObject();
jObject_parent.Add(parentNames[idx], jObject);
jObject = jObject_parent;
}
string json = jObject_parent.ToString(Formatting.None);
CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
Reflect_OBJ_INTERFACE.CALL_SetProperty,
Misc.Converter.StringToBytes(json));
}
#region FObj
public override void ConnectNotify(IFConn from)
{
base.ConnectNotify(from);
if (from.IsConnected)
{
//获取所有数据,设置推送
CurrObjSys.CallFunctionEx(
mConn, mServerID, ID,
Reflect_OBJ_INTERFACE.CALL_GetAllProperties, null);
CurrObjSys.SenseConfigEx(
mConn, mServerID, ID,
0xffffffff,
SENSE_CONFIG.ADD);
}
}
public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
{
switch (infoid)
{
case Reflect_OBJ_INTERFACE.PUSH_PropertyChanged:
{
string json = Misc.Converter.BytesToString(infodata);
ignoreSet = true;
JsonConvert.PopulateObject(json, this);
ignoreSet = false;
}
break;
case Reflect_OBJ_INTERFACE.PUSH_Event:
{
if (InterfaceType == null)
return;
string json = Misc.Converter.BytesToString(infodata);
var rData = JsonConvert.DeserializeObject<Reflect_OBJ_INTERFACE.ReflectData>(json);
var anyEvent = anyEvents.Find(ae => ae.name == rData.name);
if (anyEvent == null)
return;//异常!!!
//触发事件!!!
var methodInfo = GetType().GetMethod(anyEvent.triggerName);
var obj = rData.data.ToObject(anyEvent.retType);
//出错,就提示,肯定是客户端忘记写 "Trigger_XXXX"
methodInfo.Invoke(this, new object[] { obj });
}
break;
}
}
public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object asyncDelegate, object asyncContext)
{
switch (funcid)
{
case Reflect_OBJ_INTERFACE.CALL_GetAllProperties:
{
string json = Misc.Converter.BytesToString(retdata);
ignoreSet = true;
JsonConvert.PopulateObject(json, this);
ignoreSet = false;
}
break;
case Reflect_OBJ_INTERFACE.CALL_MethodInvoke:
{
if (InterfaceType == null)
return;
string json = Misc.Converter.BytesToString(retdata);
var reponse = JsonConvert.DeserializeObject<Reflect_OBJ_INTERFACE.ReflectData>(json);
var anyCall = anyCalls.Find(ac => ac.name == reponse.name);
if (anyCall == null)
{
//异常!!!应该有[Call]注明返回的类型
throw new Exception($"{reponse.name} 异常!!!应该有[Call]注明返回的类型");
}
var retData = reponse.data.ToObject(anyCall.retType);
((AsyncCBHandler)asyncDelegate).Invoke(asyncContext, retData);
}
break;
}
}
protected void Call(string methodName, object parameters, AsyncCBHandler asyncDelegate, object asyncContext)
{
var rData = new Reflect_OBJ_INTERFACE.ReflectData()
{
name = methodName,
data = parameters==null?null:JObject.FromObject(parameters)
};
string json = JsonConvert.SerializeObject(rData);
CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
Reflect_OBJ_INTERFACE.CALL_MethodInvoke,
Misc.Converter.StringToBytes(json),
asyncDelegate, asyncContext);
}
protected void Call(string methodName, object parameters) {
Call(methodName, parameters, null, null);
}
protected void Call(string methodName)
{
Call(methodName, null, null, null);
}
#endregion
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment