Skip to content

Commit

Permalink
AccessTools: Replace RWLockSlim with basic lock because it's not supp…
Browse files Browse the repository at this point in the history
…orted by Unity 5.x
  • Loading branch information
ghorsington committed Oct 3, 2020
1 parent 60e1905 commit 6b0b6ec
Showing 1 changed file with 31 additions and 35 deletions.
66 changes: 31 additions & 35 deletions Harmony/Tools/AccessTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,8 +1608,6 @@ public static object CreateInstance(Type type)
/// </summary>
static readonly Dictionary<Type, FastInvokeHandler> addHandlerCache = new Dictionary<Type, FastInvokeHandler>();

static readonly ReaderWriterLockSlim addHandlerCacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

/// <summary>Makes a deep copy of any object</summary>
/// <typeparam name="T">The type of the instance that should be created</typeparam>
/// <param name="source">The original object</param>
Expand Down Expand Up @@ -1641,6 +1639,18 @@ public static void MakeDeepCopy<T>(object source, out T result, Func<string, Tra
///
public static object MakeDeepCopy(object source, Type resultType, Func<string, Traverse, Traverse, object> processor = null, string pathRoot = "")
{
static bool TryGetHandler(Type resultType, out FastInvokeHandler handler)
{
lock (addHandlerCache)
return addHandlerCache.TryGetValue(resultType, out handler);
}

static void SetHandler(Type resultType, FastInvokeHandler handler)
{
lock (addHandlerCache)
addHandlerCache[resultType] = handler;
}

if (source is null || resultType is null)
return null;

Expand All @@ -1655,44 +1665,30 @@ public static object MakeDeepCopy(object source, Type resultType, Func<string, T

if (type.IsGenericType && resultType.IsGenericType)
{
addHandlerCacheLock.EnterUpgradeableReadLock();
try
if (!TryGetHandler(resultType, out var addInvoker))
{
if (!addHandlerCache.TryGetValue(resultType, out var addInvoker))
{
var addOperation = FirstMethod(resultType, m => m.Name == "Add" && m.GetParameters().Length == 1);
if (addOperation is object)
{
addInvoker = MethodInvoker.GetHandler(addOperation);
}
addHandlerCacheLock.EnterWriteLock();
try
{
addHandlerCache[resultType] = addInvoker;
}
finally
{
addHandlerCacheLock.ExitWriteLock();
}
}
if (addInvoker != null)
var addOperation = FirstMethod(resultType, m => m.Name == "Add" && m.GetParameters().Length == 1);
if (addOperation is object)
{
var addableResult = Activator.CreateInstance(resultType);
var newElementType = resultType.GetGenericArguments()[0];
var i = 0;
foreach (var element in source as IEnumerable)
{
var iStr = (i++).ToString();
var path = pathRoot.Length > 0 ? pathRoot + "." + iStr : iStr;
var newElement = MakeDeepCopy(element, newElementType, processor, path);
_ = addInvoker(addableResult, new object[] { newElement });
}
return addableResult;
addInvoker = MethodInvoker.GetHandler(addOperation);
}

SetHandler(resultType, addInvoker);
}
finally

if (addInvoker != null)
{
addHandlerCacheLock.ExitUpgradeableReadLock();
var addableResult = Activator.CreateInstance(resultType);
var newElementType = resultType.GetGenericArguments()[0];
var i = 0;
foreach (var element in source as IEnumerable)
{
var iStr = (i++).ToString();
var path = pathRoot.Length > 0 ? pathRoot + "." + iStr : iStr;
var newElement = MakeDeepCopy(element, newElementType, processor, path);
_ = addInvoker(addableResult, new object[] {newElement});
}
return addableResult;
}
}

Expand Down

0 comments on commit 6b0b6ec

Please sign in to comment.