Tidy Sync.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
@@ -29,12 +30,29 @@ namespace OpenRA
|
||||
return hashFuncCache[obj.GetType()](obj);
|
||||
}
|
||||
|
||||
static Dictionary<Type, MethodInfo> hashFunctions = new Dictionary<Type, MethodInfo>()
|
||||
{
|
||||
{typeof(int2), ((Func<int2, int>)hash_int2).Method},
|
||||
{typeof(CPos), ((Func<CPos, int>)hash_CPos).Method},
|
||||
{typeof(CVec), ((Func<CVec, int>)hash_CVec).Method},
|
||||
{typeof(PPos), ((Func<PPos, int>)hash_PPos).Method},
|
||||
{typeof(PVecInt), ((Func<PVecInt, int>)hash_PVecInt).Method},
|
||||
{typeof(PSubPos), ((Func<PSubPos, int>)hash_PSubPos).Method},
|
||||
{typeof(PSubVec), ((Func<PSubVec, int>)hash_PSubVec).Method},
|
||||
{typeof(WRange), ((Func<WRange, int>)hash<WRange>).Method},
|
||||
{typeof(WPos), ((Func<WPos, int>)hash<WPos>).Method},
|
||||
{typeof(WVec), ((Func<WVec, int>)hash<WVec>).Method},
|
||||
{typeof(WAngle), ((Func<WAngle, int>)hash<WAngle>).Method},
|
||||
{typeof(WRot), ((Func<WRot, int>)hash<WRot>).Method},
|
||||
{typeof(TypeDictionary), ((Func<TypeDictionary, int>)hash_tdict).Method},
|
||||
{typeof(Actor), ((Func<Actor, int>)hash_actor).Method},
|
||||
{typeof(Player), ((Func<Player, int>)hash_player).Method},
|
||||
};
|
||||
|
||||
static void EmitSyncOpcodes(Type type, ILGenerator il)
|
||||
{
|
||||
if (type == typeof(int))
|
||||
{
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
if (hashFunctions.ContainsKey(type))
|
||||
il.EmitCall(OpCodes.Call, hashFunctions[type], null);
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
var l = il.DefineLabel();
|
||||
@@ -43,90 +61,13 @@ namespace OpenRA
|
||||
il.Emit(OpCodes.Pop);
|
||||
il.Emit(OpCodes.Ldc_I4, 0x555);
|
||||
il.MarkLabel(l);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(int2))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<int2, int>)hash_int2).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(CPos))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<CPos, int>)hash_CPos).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(CVec))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<CVec, int>)hash_CVec).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(PPos))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<PPos, int>)hash_PPos).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(PVecInt))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<PVecInt, int>)hash_PVecInt).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(PSubPos))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<PSubPos, int>)hash_PSubPos).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(PSubVec))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<PSubVec, int>)hash_PSubVec).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(WRange))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<WRange, int>)hash<WRange>).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(WPos))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<WPos, int>)hash<WPos>).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(WVec))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<WVec, int>)hash<WVec>).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(WAngle))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<WAngle, int>)hash<WAngle>).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(WRot))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<WRot, int>)hash<WRot>).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(TypeDictionary))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<TypeDictionary, int>)hash_tdict).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(Actor))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<Actor, int>)hash_actor).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type == typeof(Player))
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<Player, int>)hash_player).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else if (type.HasAttribute<SyncAttribute>())
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ((Func<object, int>)CalculateSyncHash).Method, null);
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
else
|
||||
else if (type != typeof(int))
|
||||
throw new NotImplementedException("SyncAttribute on member of unhashable type: {0}".F(type.FullName));
|
||||
|
||||
il.Emit(OpCodes.Xor);
|
||||
}
|
||||
|
||||
public static Func<object, int> GenerateHashFunc(Type t)
|
||||
@@ -231,7 +172,9 @@ namespace OpenRA
|
||||
|
||||
public static T CheckSyncUnchanged<T>(World world, Func<T> fn)
|
||||
{
|
||||
if( world == null ) return fn();
|
||||
if (world == null)
|
||||
return fn();
|
||||
|
||||
var shouldCheckSync = Game.Settings.Debug.SanityCheckUnsyncedCode;
|
||||
int sync = shouldCheckSync ? world.SyncHash() : 0;
|
||||
bool prevInUnsyncedCode = inUnsyncedCode;
|
||||
|
||||
Reference in New Issue
Block a user