diff --git a/IPA.Loader/Config/Stores/GeneratedStoreImpl.cs b/IPA.Loader/Config/Stores/GeneratedStoreImpl.cs
index 2416a903..57ee0c2f 100644
--- a/IPA.Loader/Config/Stores/GeneratedStoreImpl.cs
+++ b/IPA.Loader/Config/Stores/GeneratedStoreImpl.cs
@@ -15,12 +15,12 @@ using System.IO;
using Boolean = IPA.Config.Data.Boolean;
using System.Collections;
using IPA.Utilities;
-using System.ComponentModel;
+using System.ComponentModel;
#if NET3
using Net3_Proxy;
using Array = Net3_Proxy.Array;
#endif
-
+
[assembly: InternalsVisibleTo(IPA.Config.Stores.GeneratedStore.AssemblyVisibilityTarget)]
namespace IPA.Config.Stores
@@ -107,16 +107,16 @@ namespace IPA.Config.Stores
return ret;
}
- ///
- /// Creates a generated store outside of the context of the config system.
- ///
- ///
- /// See for more information about how it behaves.
- ///
- /// the type to wrap
+ ///
+ /// Creates a generated store outside of the context of the config system.
+ ///
+ ///
+ /// See for more information about how it behaves.
+ ///
+ /// the type to wrap
/// a generated instance of implementing functionality described by
///
- public static T Create() where T : class
+ public static T Create() where T : class
=> GeneratedStoreImpl.Create();
}
@@ -139,7 +139,7 @@ namespace IPA.Config.Stores
{
void CopyFrom(T source, bool useLock);
}
- internal interface IGeneratedPropertyChanged : INotifyPropertyChanged
+ internal interface IGeneratedPropertyChanged : INotifyPropertyChanged
{
PropertyChangedEventHandler PropertyChangedEvent { get; }
}
@@ -172,18 +172,18 @@ namespace IPA.Config.Stores
internal static MethodInfo ImplTakeReadMethod = typeof(Impl).GetMethod(nameof(ImplTakeRead));
public static void ImplTakeRead(IGeneratedStore s) => FindImpl(s).TakeRead();
- public void TakeRead()
+ public void TakeRead()
{
if (!WriteSyncObject.IsWriteLockHeld)
- WriteSyncObject.EnterReadLock();
+ WriteSyncObject.EnterReadLock();
}
internal static MethodInfo ImplReleaseReadMethod = typeof(Impl).GetMethod(nameof(ImplReleaseRead));
public static void ImplReleaseRead(IGeneratedStore s) => FindImpl(s).ReleaseRead();
- public void ReleaseRead()
+ public void ReleaseRead()
{
- if (!WriteSyncObject.IsWriteLockHeld)
- WriteSyncObject.ExitReadLock();
+ if (!WriteSyncObject.IsWriteLockHeld)
+ WriteSyncObject.ExitReadLock();
}
internal static MethodInfo ImplTakeWriteMethod = typeof(Impl).GetMethod(nameof(ImplTakeWrite));
@@ -200,57 +200,57 @@ namespace IPA.Config.Stores
public IDisposable ChangeTransaction(IDisposable nest, bool takeWrite = true)
=> GetFreeTransaction().InitWith(this, !inChangeTransaction, nest, takeWrite && !WriteSyncObject.IsWriteLockHeld);
- private ChangeTransactionObj GetFreeTransaction()
- => freeTransactionObjs.Count > 0 ? freeTransactionObjs.Pop()
+ private ChangeTransactionObj GetFreeTransaction()
+ => freeTransactionObjs.Count > 0 ? freeTransactionObjs.Pop()
: new ChangeTransactionObj();
// TODO: maybe sometimes clean this?
private static readonly Stack freeTransactionObjs = new Stack();
- private sealed class ChangeTransactionObj : IDisposable
- {
- private struct Data
- {
- public readonly Impl impl;
- public readonly bool owns;
- public readonly bool ownsWrite;
- public readonly IDisposable nested;
-
- public Data(Impl impl, bool owning, bool takeWrite, IDisposable nest)
- {
- this.impl = impl; owns = owning; ownsWrite = takeWrite; nested = nest;
- }
- }
- private Data data;
-
- public ChangeTransactionObj InitWith(Impl impl, bool owning, IDisposable nest, bool takeWrite)
- {
- data = new Data(impl, owning, takeWrite, nest);
-
- if (data.owns)
- impl.inChangeTransaction = true;
- if (data.ownsWrite)
- impl.TakeWrite();
-
- return this;
- }
-
- public void Dispose() => Dispose(true);
- private void Dispose(bool addToStore)
- {
- if (data.owns)
- {
- data.impl.inChangeTransaction = false;
- data.impl.InvokeChanged();
- }
- data.nested?.Dispose();
- if (data.ownsWrite)
- data.impl.ReleaseWrite();
-
- if (addToStore)
- freeTransactionObjs.Push(this);
- }
-
- ~ChangeTransactionObj() => Dispose(false);
+ private sealed class ChangeTransactionObj : IDisposable
+ {
+ private struct Data
+ {
+ public readonly Impl impl;
+ public readonly bool owns;
+ public readonly bool ownsWrite;
+ public readonly IDisposable nested;
+
+ public Data(Impl impl, bool owning, bool takeWrite, IDisposable nest)
+ {
+ this.impl = impl; owns = owning; ownsWrite = takeWrite; nested = nest;
+ }
+ }
+ private Data data;
+
+ public ChangeTransactionObj InitWith(Impl impl, bool owning, IDisposable nest, bool takeWrite)
+ {
+ data = new Data(impl, owning, takeWrite, nest);
+
+ if (data.owns)
+ impl.inChangeTransaction = true;
+ if (data.ownsWrite)
+ impl.TakeWrite();
+
+ return this;
+ }
+
+ public void Dispose() => Dispose(true);
+ private void Dispose(bool addToStore)
+ {
+ if (data.owns)
+ {
+ data.impl.inChangeTransaction = false;
+ data.impl.InvokeChanged();
+ }
+ data.nested?.Dispose();
+ if (data.ownsWrite)
+ data.impl.ReleaseWrite();
+
+ if (addToStore)
+ freeTransactionObjs.Push(this);
+ }
+
+ ~ChangeTransactionObj() => Dispose(false);
}
public static Impl FindImpl(IGeneratedStore store)
@@ -605,11 +605,11 @@ namespace IPA.Config.Stores
var GetLocal = MakeGetLocal(il);
foreach (var member in structure)
- {
- EmitStore(il, member, il =>
- {
- EmitLoad(il, member); // load the member
- EmitCorrectMember(il, member, false, true, GetLocal); // correct it
+ {
+ EmitStore(il, member, il =>
+ {
+ EmitLoad(il, member); // load the member
+ EmitCorrectMember(il, member, false, true, GetLocal); // correct it
});
}
@@ -623,144 +623,144 @@ namespace IPA.Config.Stores
const MethodAttributes propertyMethodAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
const MethodAttributes virtualPropertyMethodAttr = propertyMethodAttr | MethodAttributes.Virtual | MethodAttributes.Final;
const MethodAttributes virtualMemberMethod = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.Final;
-
- #region INotifyPropertyChanged
- MethodBuilder notifyChanged = null;
- if (isINotifyPropertyChanged || hasNotifyAttribute)
- {
- var INotifyPropertyChanged_t = typeof(INotifyPropertyChanged);
- typeBuilder.AddInterfaceImplementation(INotifyPropertyChanged_t);
-
- var INotifyPropertyChanged_PropertyChanged =
- INotifyPropertyChanged_t.GetEvent(nameof(INotifyPropertyChanged.PropertyChanged));
-
- var PropertyChangedEventHandler_t = typeof(PropertyChangedEventHandler);
- var PropertyChangedEventHander_Invoke = PropertyChangedEventHandler_t.GetMethod(nameof(PropertyChangedEventHandler.Invoke));
-
- var PropertyChangedEventArgs_t = typeof(PropertyChangedEventArgs);
- var PropertyChangedEventArgs_ctor = PropertyChangedEventArgs_t.GetConstructor(new[] { typeof(string) });
-
- var Delegate_t = typeof(Delegate);
- var Delegate_Combine = Delegate_t.GetMethod(nameof(Delegate.Combine), BindingFlags.Static | BindingFlags.Public, null,
- new[] { Delegate_t, Delegate_t }, Array.Empty());
- var Delegate_Remove = Delegate_t.GetMethod(nameof(Delegate.Remove), BindingFlags.Static | BindingFlags.Public, null,
- new[] { Delegate_t, Delegate_t }, Array.Empty());
-
- var CompareExchange = typeof(Interlocked).GetMethods()
- .Where(m => m.Name == nameof(Interlocked.CompareExchange))
- .Where(m => m.ContainsGenericParameters)
- .Where(m => m.GetParameters().Length == 3).First()
- .MakeGenericMethod(PropertyChangedEventHandler_t);
-
- var basePropChangedEvent = type.GetEvents()
- .Where(e => e.AddMethod.GetBaseDefinition().DeclaringType == INotifyPropertyChanged_t)
- .FirstOrDefault();
- var basePropChangedAdd = basePropChangedEvent?.AddMethod;
- var basePropChangedRemove = basePropChangedEvent?.RemoveMethod;
-
- var PropertyChanged_backing = typeBuilder.DefineField("PropertyChanged", PropertyChangedEventHandler_t, FieldAttributes.Private);
-
- var add_PropertyChanged = typeBuilder.DefineMethod("PropertyChanged",
- MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.Virtual,
- null, new[] { PropertyChangedEventHandler_t });
- typeBuilder.DefineMethodOverride(add_PropertyChanged, INotifyPropertyChanged_PropertyChanged.GetAddMethod());
- if (basePropChangedAdd != null)
- typeBuilder.DefineMethodOverride(add_PropertyChanged, basePropChangedAdd);
-
- {
- var il = add_PropertyChanged.GetILGenerator();
-
- var loopLabel = il.DefineLabel();
- var delTemp = il.DeclareLocal(PropertyChangedEventHandler_t);
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, PropertyChanged_backing);
-
- il.MarkLabel(loopLabel);
- il.Emit(OpCodes.Stloc, delTemp);
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldflda, PropertyChanged_backing);
-
- il.Emit(OpCodes.Ldloc, delTemp);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Call, Delegate_Combine);
- il.Emit(OpCodes.Castclass, PropertyChangedEventHandler_t);
-
- il.Emit(OpCodes.Ldloc, delTemp);
- il.Emit(OpCodes.Call, CompareExchange);
-
- il.Emit(OpCodes.Dup);
- il.Emit(OpCodes.Ldloc, delTemp);
- il.Emit(OpCodes.Bne_Un_S, loopLabel);
-
- il.Emit(OpCodes.Ret);
- }
-
- var remove_PropertyChanged = typeBuilder.DefineMethod("PropertyChanged",
- MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.Virtual,
- null, new[] { PropertyChangedEventHandler_t });
- typeBuilder.DefineMethodOverride(remove_PropertyChanged, INotifyPropertyChanged_PropertyChanged.GetRemoveMethod());
- if (basePropChangedRemove != null)
- typeBuilder.DefineMethodOverride(remove_PropertyChanged, basePropChangedRemove);
-
- {
- var il = remove_PropertyChanged.GetILGenerator();
-
- var loopLabel = il.DefineLabel();
- var delTemp = il.DeclareLocal(PropertyChangedEventHandler_t);
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, PropertyChanged_backing);
-
- il.MarkLabel(loopLabel);
- il.Emit(OpCodes.Stloc, delTemp);
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldflda, PropertyChanged_backing);
-
- il.Emit(OpCodes.Ldloc, delTemp);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Call, Delegate_Remove);
- il.Emit(OpCodes.Castclass, PropertyChangedEventHandler_t);
-
- il.Emit(OpCodes.Ldloc, delTemp);
- il.Emit(OpCodes.Call, CompareExchange);
-
- il.Emit(OpCodes.Dup);
- il.Emit(OpCodes.Ldloc, delTemp);
- il.Emit(OpCodes.Bne_Un_S, loopLabel);
-
- il.Emit(OpCodes.Ret);
- }
-
- var PropertyChanged_event = typeBuilder.DefineEvent(nameof(INotifyPropertyChanged.PropertyChanged), EventAttributes.None, PropertyChangedEventHandler_t);
- PropertyChanged_event.SetAddOnMethod(add_PropertyChanged);
- PropertyChanged_event.SetRemoveOnMethod(remove_PropertyChanged);
-
- notifyChanged = typeBuilder.DefineMethod("<>NotifyChanged",
- MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Final, null, new[] { typeof(string) });
-
- {
- var il = notifyChanged.GetILGenerator();
-
- var invokeNonNull = il.DefineLabel();
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, PropertyChanged_backing);
- il.Emit(OpCodes.Dup);
- il.Emit(OpCodes.Brtrue, invokeNonNull);
- il.Emit(OpCodes.Pop);
- il.Emit(OpCodes.Ret);
-
- il.MarkLabel(invokeNonNull);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Newobj, PropertyChangedEventArgs_ctor);
- il.Emit(OpCodes.Call, PropertyChangedEventHander_Invoke);
- il.Emit(OpCodes.Ret);
- }
- }
+
+ #region INotifyPropertyChanged
+ MethodBuilder notifyChanged = null;
+ if (isINotifyPropertyChanged || hasNotifyAttribute)
+ {
+ var INotifyPropertyChanged_t = typeof(INotifyPropertyChanged);
+ typeBuilder.AddInterfaceImplementation(INotifyPropertyChanged_t);
+
+ var INotifyPropertyChanged_PropertyChanged =
+ INotifyPropertyChanged_t.GetEvent(nameof(INotifyPropertyChanged.PropertyChanged));
+
+ var PropertyChangedEventHandler_t = typeof(PropertyChangedEventHandler);
+ var PropertyChangedEventHander_Invoke = PropertyChangedEventHandler_t.GetMethod(nameof(PropertyChangedEventHandler.Invoke));
+
+ var PropertyChangedEventArgs_t = typeof(PropertyChangedEventArgs);
+ var PropertyChangedEventArgs_ctor = PropertyChangedEventArgs_t.GetConstructor(new[] { typeof(string) });
+
+ var Delegate_t = typeof(Delegate);
+ var Delegate_Combine = Delegate_t.GetMethod(nameof(Delegate.Combine), BindingFlags.Static | BindingFlags.Public, null,
+ new[] { Delegate_t, Delegate_t }, Array.Empty());
+ var Delegate_Remove = Delegate_t.GetMethod(nameof(Delegate.Remove), BindingFlags.Static | BindingFlags.Public, null,
+ new[] { Delegate_t, Delegate_t }, Array.Empty());
+
+ var CompareExchange = typeof(Interlocked).GetMethods()
+ .Where(m => m.Name == nameof(Interlocked.CompareExchange))
+ .Where(m => m.ContainsGenericParameters)
+ .Where(m => m.GetParameters().Length == 3).First()
+ .MakeGenericMethod(PropertyChangedEventHandler_t);
+
+ var basePropChangedEvent = type.GetEvents()
+ .Where(e => e.GetAddMethod().GetBaseDefinition().DeclaringType == INotifyPropertyChanged_t)
+ .FirstOrDefault();
+ var basePropChangedAdd = basePropChangedEvent? .GetAddMethod();
+ var basePropChangedRemove = basePropChangedEvent?.GetRemoveMethod();
+
+ var PropertyChanged_backing = typeBuilder.DefineField("PropertyChanged", PropertyChangedEventHandler_t, FieldAttributes.Private);
+
+ var add_PropertyChanged = typeBuilder.DefineMethod("PropertyChanged",
+ MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.Virtual,
+ null, new[] { PropertyChangedEventHandler_t });
+ typeBuilder.DefineMethodOverride(add_PropertyChanged, INotifyPropertyChanged_PropertyChanged.GetAddMethod());
+ if (basePropChangedAdd != null)
+ typeBuilder.DefineMethodOverride(add_PropertyChanged, basePropChangedAdd);
+
+ {
+ var il = add_PropertyChanged.GetILGenerator();
+
+ var loopLabel = il.DefineLabel();
+ var delTemp = il.DeclareLocal(PropertyChangedEventHandler_t);
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, PropertyChanged_backing);
+
+ il.MarkLabel(loopLabel);
+ il.Emit(OpCodes.Stloc, delTemp);
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldflda, PropertyChanged_backing);
+
+ il.Emit(OpCodes.Ldloc, delTemp);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Call, Delegate_Combine);
+ il.Emit(OpCodes.Castclass, PropertyChangedEventHandler_t);
+
+ il.Emit(OpCodes.Ldloc, delTemp);
+ il.Emit(OpCodes.Call, CompareExchange);
+
+ il.Emit(OpCodes.Dup);
+ il.Emit(OpCodes.Ldloc, delTemp);
+ il.Emit(OpCodes.Bne_Un_S, loopLabel);
+
+ il.Emit(OpCodes.Ret);
+ }
+
+ var remove_PropertyChanged = typeBuilder.DefineMethod("PropertyChanged",
+ MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.Virtual,
+ null, new[] { PropertyChangedEventHandler_t });
+ typeBuilder.DefineMethodOverride(remove_PropertyChanged, INotifyPropertyChanged_PropertyChanged.GetRemoveMethod());
+ if (basePropChangedRemove != null)
+ typeBuilder.DefineMethodOverride(remove_PropertyChanged, basePropChangedRemove);
+
+ {
+ var il = remove_PropertyChanged.GetILGenerator();
+
+ var loopLabel = il.DefineLabel();
+ var delTemp = il.DeclareLocal(PropertyChangedEventHandler_t);
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, PropertyChanged_backing);
+
+ il.MarkLabel(loopLabel);
+ il.Emit(OpCodes.Stloc, delTemp);
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldflda, PropertyChanged_backing);
+
+ il.Emit(OpCodes.Ldloc, delTemp);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Call, Delegate_Remove);
+ il.Emit(OpCodes.Castclass, PropertyChangedEventHandler_t);
+
+ il.Emit(OpCodes.Ldloc, delTemp);
+ il.Emit(OpCodes.Call, CompareExchange);
+
+ il.Emit(OpCodes.Dup);
+ il.Emit(OpCodes.Ldloc, delTemp);
+ il.Emit(OpCodes.Bne_Un_S, loopLabel);
+
+ il.Emit(OpCodes.Ret);
+ }
+
+ var PropertyChanged_event = typeBuilder.DefineEvent(nameof(INotifyPropertyChanged.PropertyChanged), EventAttributes.None, PropertyChangedEventHandler_t);
+ PropertyChanged_event.SetAddOnMethod(add_PropertyChanged);
+ PropertyChanged_event.SetRemoveOnMethod(remove_PropertyChanged);
+
+ notifyChanged = typeBuilder.DefineMethod("<>NotifyChanged",
+ MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Final, null, new[] { typeof(string) });
+
+ {
+ var il = notifyChanged.GetILGenerator();
+
+ var invokeNonNull = il.DefineLabel();
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldfld, PropertyChanged_backing);
+ il.Emit(OpCodes.Dup);
+ il.Emit(OpCodes.Brtrue, invokeNonNull);
+ il.Emit(OpCodes.Pop);
+ il.Emit(OpCodes.Ret);
+
+ il.MarkLabel(invokeNonNull);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Newobj, PropertyChangedEventArgs_ctor);
+ il.Emit(OpCodes.Call, PropertyChangedEventHander_Invoke);
+ il.Emit(OpCodes.Ret);
+ }
+ }
#endregion
#region IGeneratedStore
@@ -930,18 +930,18 @@ namespace IPA.Config.Stores
EmitDeserializeMember(il, member, nextLabel, il => il.Emit(OpCodes.Ldloc_S, valueLocal), GetLocal);
}
- il.MarkLabel(nextLabel);
-
- if (notifyChanged != null)
- {
- foreach (var member in structure)
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldstr, member.Name);
- il.Emit(OpCodes.Call, notifyChanged);
- }
- }
-
+ il.MarkLabel(nextLabel);
+
+ if (notifyChanged != null)
+ {
+ foreach (var member in structure)
+ {
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldstr, member.Name);
+ il.Emit(OpCodes.Call, notifyChanged);
+ }
+ }
+
il.Emit(OpCodes.Ret);
}
#endregion
@@ -1021,51 +1021,51 @@ namespace IPA.Config.Stores
"<>Changed",
virtualMemberMethod,
null, Type.EmptyTypes);
- typeBuilder.DefineMethodOverride(coreChanged, IGeneratedStore_Changed);
- if (baseChanged != null)
+ typeBuilder.DefineMethodOverride(coreChanged, IGeneratedStore_Changed);
+ if (baseChanged != null)
typeBuilder.DefineMethodOverride(coreChanged, baseChanged);
{
var il = coreChanged.GetILGenerator();
- if (baseChanged != null)
+ if (baseChanged != null)
{
il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call, baseChanged); // call base
+ il.Emit(OpCodes.Call, baseChanged); // call base
}
- il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Tailcall);
il.Emit(OpCodes.Call, Impl.ImplSignalChangedMethod);
il.Emit(OpCodes.Ret); // simply call our impl's SignalChanged method and return
- }
+ }
#endregion
-
+
#region ChangeTransaction
- var coreChangeTransaction = typeBuilder.DefineMethod(
- "<>ChangeTransaction",
- virtualMemberMethod,
- typeof(IDisposable), Type.EmptyTypes);
- typeBuilder.DefineMethodOverride(coreChangeTransaction, IGeneratedStore_ChangeTransaction);
- if (baseChangeTransaction != null)
- typeBuilder.DefineMethodOverride(coreChangeTransaction, baseChangeTransaction);
-
- {
- var il = coreChangeTransaction.GetILGenerator();
-
- il.Emit(OpCodes.Ldarg_0);
- if (baseChangeTransaction != null)
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call, baseChangeTransaction);
- }
- else
- il.Emit(OpCodes.Ldnull);
-
- il.Emit(OpCodes.Tailcall);
- il.Emit(OpCodes.Call, Impl.ImplChangeTransactionMethod);
- il.Emit(OpCodes.Ret);
- }
+ var coreChangeTransaction = typeBuilder.DefineMethod(
+ "<>ChangeTransaction",
+ virtualMemberMethod,
+ typeof(IDisposable), Type.EmptyTypes);
+ typeBuilder.DefineMethodOverride(coreChangeTransaction, IGeneratedStore_ChangeTransaction);
+ if (baseChangeTransaction != null)
+ typeBuilder.DefineMethodOverride(coreChangeTransaction, baseChangeTransaction);
+
+ {
+ var il = coreChangeTransaction.GetILGenerator();
+
+ il.Emit(OpCodes.Ldarg_0);
+ if (baseChangeTransaction != null)
+ {
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Call, baseChangeTransaction);
+ }
+ else
+ il.Emit(OpCodes.Ldnull);
+
+ il.Emit(OpCodes.Tailcall);
+ il.Emit(OpCodes.Call, Impl.ImplChangeTransactionMethod);
+ il.Emit(OpCodes.Ret);
+ }
#endregion
#region IGeneratedStore
@@ -1085,9 +1085,9 @@ namespace IPA.Config.Stores
var startLock = il.DefineLabel();
il.Emit(OpCodes.Ldarg_2);
- il.Emit(OpCodes.Brfalse, startLock);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call, coreChangeTransaction); // take the write lock
+ il.Emit(OpCodes.Brfalse, startLock);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Call, coreChangeTransaction); // take the write lock
il.Emit(OpCodes.Stloc, transactionLocal);
il.MarkLabel(startLock);
@@ -1108,60 +1108,60 @@ namespace IPA.Config.Stores
EmitWarnException(il, $"Error while copying from member {member.Name}");
il.EndExceptionBlock();
- }
-
- if (notifyChanged != null)
- {
- foreach (var member in structure)
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldstr, member.Name);
- il.Emit(OpCodes.Call, notifyChanged);
- }
- }
-
+ }
+
+ if (notifyChanged != null)
+ {
+ foreach (var member in structure)
+ {
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldstr, member.Name);
+ il.Emit(OpCodes.Call, notifyChanged);
+ }
+ }
+
var endLock = il.DefineLabel();
il.Emit(OpCodes.Ldarg_2);
- il.Emit(OpCodes.Brfalse, endLock);
- il.Emit(OpCodes.Ldloc, transactionLocal);
+ il.Emit(OpCodes.Brfalse, endLock);
+ il.Emit(OpCodes.Ldloc, transactionLocal);
il.Emit(OpCodes.Callvirt, IDisposable_Dispose);
il.MarkLabel(endLock);
il.Emit(OpCodes.Ret);
}
#endregion
#endregion
-
- #region base.CopyFrom
- if (baseCopyFrom != null)
- {
- var pubCopyFrom = typeBuilder.DefineMethod(
- baseCopyFrom.Name,
- virtualMemberMethod,
- null, new[] { type });
- typeBuilder.DefineMethodOverride(pubCopyFrom, baseCopyFrom);
-
- {
- var il = pubCopyFrom.GetILGenerator();
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call, coreChangeTransaction);
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Ldc_I4_0);
- il.Emit(OpCodes.Call, copyFrom); // call internal
-
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldarg_1);
- il.Emit(OpCodes.Call, baseCopyFrom); // call base
-
- il.Emit(OpCodes.Tailcall);
- il.Emit(OpCodes.Callvirt, IDisposable_Dispose); // dispose transaction (which calls changed)
- il.Emit(OpCodes.Ret);
- }
- }
- #endregion
-
+
+ #region base.CopyFrom
+ if (baseCopyFrom != null)
+ {
+ var pubCopyFrom = typeBuilder.DefineMethod(
+ baseCopyFrom.Name,
+ virtualMemberMethod,
+ null, new[] { type });
+ typeBuilder.DefineMethodOverride(pubCopyFrom, baseCopyFrom);
+
+ {
+ var il = pubCopyFrom.GetILGenerator();
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Call, coreChangeTransaction);
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Ldc_I4_0);
+ il.Emit(OpCodes.Call, copyFrom); // call internal
+
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Call, baseCopyFrom); // call base
+
+ il.Emit(OpCodes.Tailcall);
+ il.Emit(OpCodes.Callvirt, IDisposable_Dispose); // dispose transaction (which calls changed)
+ il.Emit(OpCodes.Ret);
+ }
+ }
+ #endregion
+
#region Members
foreach (var member in structure.Where(m => m.IsVirtual))
{ // IsVirtual implies !IsField
@@ -1220,18 +1220,18 @@ namespace IPA.Config.Stores
EmitCorrectMember(il, member, false, false, GetLocal);
il.Emit(OpCodes.Call, set);
- il.BeginFinallyBlock();
-
+ il.BeginFinallyBlock();
+
il.Emit(OpCodes.Ldloc, transactionLocal);
il.Emit(OpCodes.Callvirt, IDisposable_Dispose);
il.EndExceptionBlock();
- if (notifyChanged != null)
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldstr, member.Name);
- il.Emit(OpCodes.Call, notifyChanged);
+ if (notifyChanged != null)
+ {
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldstr, member.Name);
+ il.Emit(OpCodes.Call, notifyChanged);
}
il.Emit(OpCodes.Ret);
}
@@ -1247,8 +1247,8 @@ namespace IPA.Config.Stores
).Compile();
return (creatorDel, genType);
- }
-
+ }
+
#region Logs
private static readonly MethodInfo LogErrorMethod = typeof(GeneratedStoreImpl).GetMethod(nameof(LogError), BindingFlags.NonPublic | BindingFlags.Static);
internal static void LogError(Type expected, Type found, string message)
@@ -1264,9 +1264,9 @@ namespace IPA.Config.Stores
internal static void LogWarningException(Exception exception)
{
Logger.config.Warn(exception);
- }
- #endregion
-
+ }
+ #endregion
+
#region Correction
private static bool NeedsCorrection(SerializedMemberInfo member)
{
@@ -1291,29 +1291,29 @@ namespace IPA.Config.Stores
il.Emit(OpCodes.Call, member.Nullable_HasValue.GetGetMethod());
il.Emit(OpCodes.Brfalse, endLabel);
il.Emit(OpCodes.Call, member.Nullable_Value.GetGetMethod());
- }
-
- // TODO: impl the rest of this
-
- // currently the only thing for this is where expect == Map, so do generate shit
+ }
+
+ // TODO: impl the rest of this
+
+ // currently the only thing for this is where expect == Map, so do generate shit
var copyFrom = typeof(IGeneratedStore<>).MakeGenericType(member.Type).GetMethod(nameof(IGeneratedStore.CopyFrom));
var noCreate = il.DefineLabel();
- var valLocal = GetLocal(member.Type);
-
- if (!alwaysNew)
- {
- il.Emit(OpCodes.Dup);
- il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
- il.Emit(OpCodes.Brtrue_S, endLabel); // our input is already something we like
+ var valLocal = GetLocal(member.Type);
+
+ if (!alwaysNew)
+ {
+ il.Emit(OpCodes.Dup);
+ il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
+ il.Emit(OpCodes.Brtrue_S, endLabel); // our input is already something we like
}
il.Emit(OpCodes.Stloc, valLocal);
- if (!alwaysNew)
- {
- EmitLoad(il, member, il => il.Emit(OpCodes.Ldarg_0));
- il.Emit(OpCodes.Dup);
- il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
- il.Emit(OpCodes.Brtrue_S, noCreate);
- il.Emit(OpCodes.Pop);
+ if (!alwaysNew)
+ {
+ EmitLoad(il, member, il => il.Emit(OpCodes.Ldarg_0));
+ il.Emit(OpCodes.Dup);
+ il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
+ il.Emit(OpCodes.Brtrue_S, noCreate);
+ il.Emit(OpCodes.Pop);
}
EmitCreateChildGenerated(il, member.Type);
il.MarkLabel(noCreate);
@@ -1329,11 +1329,11 @@ namespace IPA.Config.Stores
il.Emit(OpCodes.Newobj, member.Nullable_Construct);
il.MarkLabel(endLabel);
- }
+ }
#endregion
-
- #region Utility
-
+
+ #region Utility
+
private delegate LocalBuilder GetLocal(Type type, int idx = 0);
private static GetLocal MakeGetLocal(ILGenerator il)
@@ -1615,28 +1615,28 @@ namespace IPA.Config.Stores
// for now, we assume that its a generated type implementing IGeneratedStore
var IGeneratedStore_Serialize = typeof(IGeneratedStore).GetMethod(nameof(IGeneratedStore.Serialize));
- var IGeneratedStoreT_CopyFrom = typeof(IGeneratedStore<>).MakeGenericType(member.Type)
- .GetMethod(nameof(IGeneratedStore