Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Thick-Common
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
潘栩锋
Thick-Common
Commits
8778f464
Commit
8778f464
authored
Jun 10, 2020
by
潘栩锋
🚴
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加 FObjBase.Reflect
parent
9c59bf6a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
925 additions
and
0 deletions
+925
-0
CallAttribute.cs
Project.FLY.FObjSys/FObjBaseReflect/CallAttribute.cs
+54
-0
FObjBase.Reflect.csproj
Project.FLY.FObjSys/FObjBaseReflect/FObjBase.Reflect.csproj
+66
-0
AssemblyInfo.cs
...ct.FLY.FObjSys/FObjBaseReflect/Properties/AssemblyInfo.cs
+36
-0
Reflect_OBJ_INTERFACE.cs
Project.FLY.FObjSys/FObjBaseReflect/Reflect_OBJ_INTERFACE.cs
+28
-0
Reflect_Proxy.cs
Project.FLY.FObjSys/FObjBaseReflect/Reflect_Proxy.cs
+342
-0
Reflect_SeviceClient.cs
Project.FLY.FObjSys/FObjBaseReflect/Reflect_SeviceClient.cs
+399
-0
No files found.
Project.FLY.FObjSys/FObjBaseReflect/CallAttribute.cs
0 → 100644
View file @
8778f464
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
{
}
}
Project.FLY.FObjSys/FObjBaseReflect/FObjBase.Reflect.csproj
0 → 100644
View file @
8778f464
<?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
Project.FLY.FObjSys/FObjBaseReflect/Properties/AssemblyInfo.cs
0 → 100644
View file @
8778f464
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")]
Project.FLY.FObjSys/FObjBaseReflect/Reflect_OBJ_INTERFACE.cs
0 → 100644
View file @
8778f464
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
;
}
}
}
Project.FLY.FObjSys/FObjBaseReflect/Reflect_Proxy.cs
0 → 100644
View file @
8778f464
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
;
}
}
}
Project.FLY.FObjSys/FObjBaseReflect/Reflect_SeviceClient.cs
0 → 100644
View file @
8778f464
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
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment