Merge pull request #7141 from RoosterDragon/sync-less-tostring
Generate sync reports faster
This commit is contained in:
@@ -17,7 +17,7 @@ using OpenRA.Primitives;
|
|||||||
|
|
||||||
namespace OpenRA.Network
|
namespace OpenRA.Network
|
||||||
{
|
{
|
||||||
using NamesValuesPair = Pair<string[], string[]>;
|
using NamesValuesPair = Pair<string[], object[]>;
|
||||||
|
|
||||||
class SyncReport
|
class SyncReport
|
||||||
{
|
{
|
||||||
@@ -35,10 +35,10 @@ namespace OpenRA.Network
|
|||||||
TypeInfo typeInfo;
|
TypeInfo typeInfo;
|
||||||
lock (typeInfoCache)
|
lock (typeInfoCache)
|
||||||
typeInfo = typeInfoCache[type];
|
typeInfo = typeInfoCache[type];
|
||||||
var values = new string[typeInfo.Names.Length];
|
var values = new object[typeInfo.Names.Length];
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
|
||||||
foreach (var func in typeInfo.MemberToStringFunctions)
|
foreach (var func in typeInfo.SerializableCopyOfMemberFunctions)
|
||||||
values[index++] = func(sync);
|
values[index++] = func(sync);
|
||||||
|
|
||||||
return Pair.New(typeInfo.Names, values);
|
return Pair.New(typeInfo.Names, values);
|
||||||
@@ -166,7 +166,7 @@ namespace OpenRA.Network
|
|||||||
static ParameterExpression syncParam = Expression.Parameter(typeof(ISync), "sync");
|
static ParameterExpression syncParam = Expression.Parameter(typeof(ISync), "sync");
|
||||||
static ConstantExpression nullString = Expression.Constant(null, typeof(string));
|
static ConstantExpression nullString = Expression.Constant(null, typeof(string));
|
||||||
|
|
||||||
public readonly Func<ISync, string>[] MemberToStringFunctions;
|
public readonly Func<ISync, object>[] SerializableCopyOfMemberFunctions;
|
||||||
public readonly string[] Names;
|
public readonly string[] Names;
|
||||||
|
|
||||||
public TypeInfo(Type type)
|
public TypeInfo(Type type)
|
||||||
@@ -182,14 +182,25 @@ namespace OpenRA.Network
|
|||||||
"Invalid Property: " + prop.DeclaringType.FullName + "." + prop.Name);
|
"Invalid Property: " + prop.DeclaringType.FullName + "." + prop.Name);
|
||||||
|
|
||||||
var sync = Expression.Convert(syncParam, type);
|
var sync = Expression.Convert(syncParam, type);
|
||||||
MemberToStringFunctions = fields
|
SerializableCopyOfMemberFunctions = fields
|
||||||
.Select(fi => MemberToString(Expression.Field(sync, fi), fi.FieldType, fi.Name))
|
.Select(fi => SerializableCopyOfMember(Expression.Field(sync, fi), fi.FieldType, fi.Name))
|
||||||
.Concat(properties.Select(pi => MemberToString(Expression.Property(sync, pi), pi.PropertyType, pi.Name)))
|
.Concat(properties.Select(pi => SerializableCopyOfMember(Expression.Property(sync, pi), pi.PropertyType, pi.Name)))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
Names = fields.Select(fi => fi.Name).Concat(properties.Select(pi => pi.Name)).ToArray();
|
Names = fields.Select(fi => fi.Name).Concat(properties.Select(pi => pi.Name)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Func<ISync, object> SerializableCopyOfMember(MemberExpression getMember, Type memberType, string name)
|
||||||
|
{
|
||||||
|
if (memberType.IsValueType)
|
||||||
|
{
|
||||||
|
// We can get a copy just by accessing the member since it is a value type.
|
||||||
|
var boxedCopy = Expression.Convert(getMember, typeof(object));
|
||||||
|
return Expression.Lambda<Func<ISync, object>>(boxedCopy, name, new[] { syncParam }).Compile();
|
||||||
|
}
|
||||||
|
return MemberToString(getMember, memberType, name);
|
||||||
|
}
|
||||||
|
|
||||||
static Func<ISync, string> MemberToString(MemberExpression getMember, Type memberType, string name)
|
static Func<ISync, string> MemberToString(MemberExpression getMember, Type memberType, string name)
|
||||||
{
|
{
|
||||||
// The lambda generated is shown below.
|
// The lambda generated is shown below.
|
||||||
@@ -197,10 +208,13 @@ namespace OpenRA.Network
|
|||||||
var toString = memberType.GetMethod("ToString", Type.EmptyTypes);
|
var toString = memberType.GetMethod("ToString", Type.EmptyTypes);
|
||||||
Expression getString;
|
Expression getString;
|
||||||
if (memberType.IsValueType)
|
if (memberType.IsValueType)
|
||||||
|
{
|
||||||
|
// (ISync sync) => { return ((TSync)sync).Foo.ToString(); }
|
||||||
getString = Expression.Call(getMember, toString);
|
getString = Expression.Call(getMember, toString);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// (ISync sync) => { var foo = ((TSync)sync).Foo; return foo == null ? null : foo.ToString()); }
|
// (ISync sync) => { var foo = ((TSync)sync).Foo; return foo == null ? null : foo.ToString(); }
|
||||||
var memberVariable = Expression.Variable(memberType, getMember.Member.Name);
|
var memberVariable = Expression.Variable(memberType, getMember.Member.Name);
|
||||||
var assignMemberVariable = Expression.Assign(memberVariable, getMember);
|
var assignMemberVariable = Expression.Assign(memberVariable, getMember);
|
||||||
var member = Expression.Block(new[] { memberVariable }, assignMemberVariable);
|
var member = Expression.Block(new[] { memberVariable }, assignMemberVariable);
|
||||||
|
|||||||
Reference in New Issue
Block a user