Browse Source

Fixed many small issues

4.0.0-beta
Anairkoen Schno 5 years ago
parent
commit
569338fc72
4 changed files with 53 additions and 24 deletions
  1. +1
    -0
      IPA.Loader/Config/Config.cs
  2. +23
    -8
      IPA.Loader/Config/ConfigRuntime.cs
  3. +1
    -0
      IPA.Loader/Config/SelfConfig.cs
  4. +28
    -16
      IPA.Loader/Config/Stores/GeneratedStore.cs

+ 1
- 0
IPA.Loader/Config/Config.cs View File

@ -150,6 +150,7 @@ namespace IPA.Config
if (Store != null) if (Store != null)
throw new InvalidOperationException($"{nameof(SetStore)} can only be called once"); throw new InvalidOperationException($"{nameof(SetStore)} can only be called once");
Store = store; Store = store;
ConfigRuntime.ConfigChanged();
} }
/// <summary> /// <summary>


+ 23
- 8
IPA.Loader/Config/ConfigRuntime.cs View File

@ -67,6 +67,11 @@ namespace IPA.Config
AddConfigToWatchers(cfg); AddConfigToWatchers(cfg);
} }
public static void ConfigChanged()
{
configsChangedWatcher.Set();
}
private static void AddConfigToWatchers(Config config) private static void AddConfigToWatchers(Config config)
{ {
var dir = config.File.Directory; var dir = config.File.Directory;
@ -173,14 +178,24 @@ namespace IPA.Config
{ {
while (true) while (true)
{ {
var configArr = configs.ToArray();
var waitHandles = configArr.Select(c => c.Store.SyncObject)
.Prepend(configsChangedWatcher)
.ToArray();
var index = WaitHandle.WaitAny(waitHandles);
if (index == 0)
{ // we got a signal that the configs collection changed, loop around
var configArr = configs.Where(c => c.Store != null).ToArray();
int index = -1;
try
{
var waitHandles = configArr.Select(c => c.Store.SyncObject)
.Prepend(configsChangedWatcher)
.ToArray();
index = WaitHandle.WaitAny(waitHandles);
}
catch (Exception e)
{
Logger.config.Error($"Error waiting for in-memory updates");
Logger.config.Error(e);
Thread.Sleep(TimeSpan.FromSeconds(1));
}
if (index <= 0)
{ // we got a signal that the configs collection changed, loop around, or errored
continue; continue;
} }


+ 1
- 0
IPA.Loader/Config/SelfConfig.cs View File

@ -20,6 +20,7 @@ namespace IPA.Config
{ {
LoaderConfig = Config.GetConfigFor(IPAName, "json"); LoaderConfig = Config.GetConfigFor(IPAName, "json");
Instance = LoaderConfig.Generated<SelfConfig>(); Instance = LoaderConfig.Generated<SelfConfig>();
GeneratedStore.DebugSaveAssembly("GeneratedAssembly.dll");
} }
public static void ReadCommandLine(string[] args) public static void ReadCommandLine(string[] args)


+ 28
- 16
IPA.Loader/Config/Stores/GeneratedStore.cs View File

@ -9,11 +9,15 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.IO;
#if NET3 #if NET3
using Net3_Proxy; using Net3_Proxy;
using Array = Net3_Proxy.Array; using Array = Net3_Proxy.Array;
#endif #endif
[assembly: InternalsVisibleTo(IPA.Config.Stores.GeneratedStore.GeneratedAssemblyName)]
namespace IPA.Config.Stores namespace IPA.Config.Stores
{ {
/// <summary> /// <summary>
@ -54,7 +58,7 @@ namespace IPA.Config.Stores
internal static class GeneratedStore internal static class GeneratedStore
{ {
private interface IGeneratedStore
internal interface IGeneratedStore
{ {
/// <summary> /// <summary>
/// serializes/deserializes to Value /// serializes/deserializes to Value
@ -65,7 +69,7 @@ namespace IPA.Config.Stores
Impl Impl { get; } Impl Impl { get; }
} }
private class Impl : IConfigStore
internal class Impl : IConfigStore
{ {
private IGeneratedStore generated; private IGeneratedStore generated;
@ -80,27 +84,27 @@ namespace IPA.Config.Stores
internal static MethodInfo WriteSyncObjectGetMethod = typeof(Impl).GetProperty(nameof(WriteSyncObject)).GetGetMethod(); internal static MethodInfo WriteSyncObjectGetMethod = typeof(Impl).GetProperty(nameof(WriteSyncObject)).GetGetMethod();
internal static MethodInfo ImplSignalChangedMethod = typeof(Impl).GetMethod(nameof(ImplSignalChanged)); internal static MethodInfo ImplSignalChangedMethod = typeof(Impl).GetMethod(nameof(ImplSignalChanged));
internal static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s).SignalChanged();
internal void SignalChanged() => resetEvent.Set();
public static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s).SignalChanged();
public void SignalChanged() => resetEvent.Set();
internal static MethodInfo ImplTakeReadMethod = typeof(Impl).GetMethod(nameof(ImplTakeRead)); internal static MethodInfo ImplTakeReadMethod = typeof(Impl).GetMethod(nameof(ImplTakeRead));
internal static void ImplTakeRead(IGeneratedStore s) => FindImpl(s).TakeRead();
internal void TakeRead() => WriteSyncObject.EnterReadLock();
public static void ImplTakeRead(IGeneratedStore s) => FindImpl(s).TakeRead();
public void TakeRead() => WriteSyncObject.EnterReadLock();
internal static MethodInfo ImplReleaseReadMethod = typeof(Impl).GetMethod(nameof(ImplReleaseRead)); internal static MethodInfo ImplReleaseReadMethod = typeof(Impl).GetMethod(nameof(ImplReleaseRead));
internal static void ImplReleaseRead(IGeneratedStore s) => FindImpl(s).ReleaseRead();
internal void ReleaseRead() => WriteSyncObject.ExitWriteLock();
public static void ImplReleaseRead(IGeneratedStore s) => FindImpl(s).ReleaseRead();
public void ReleaseRead() => WriteSyncObject.ExitWriteLock();
internal static MethodInfo ImplTakeWriteMethod = typeof(Impl).GetMethod(nameof(ImplTakeWrite)); internal static MethodInfo ImplTakeWriteMethod = typeof(Impl).GetMethod(nameof(ImplTakeWrite));
internal static void ImplTakeWrite(IGeneratedStore s) => FindImpl(s).TakeWrite();
internal void TakeWrite() => WriteSyncObject.EnterWriteLock();
public static void ImplTakeWrite(IGeneratedStore s) => FindImpl(s).TakeWrite();
public void TakeWrite() => WriteSyncObject.EnterWriteLock();
internal static MethodInfo ImplReleaseWriteMethod = typeof(Impl).GetMethod(nameof(ImplReleaseWrite)); internal static MethodInfo ImplReleaseWriteMethod = typeof(Impl).GetMethod(nameof(ImplReleaseWrite));
internal static void ImplReleaseWrite(IGeneratedStore s) => FindImpl(s).ReleaseWrite();
internal void ReleaseWrite() => WriteSyncObject.ExitWriteLock();
public static void ImplReleaseWrite(IGeneratedStore s) => FindImpl(s).ReleaseWrite();
public void ReleaseWrite() => WriteSyncObject.ExitWriteLock();
internal static MethodInfo FindImplMethod = typeof(Impl).GetMethod(nameof(FindImpl)); internal static MethodInfo FindImplMethod = typeof(Impl).GetMethod(nameof(FindImpl));
internal static Impl FindImpl(IGeneratedStore store)
public static Impl FindImpl(IGeneratedStore store)
{ {
while (store != null) store = store.Parent; // walk to the top of the tree while (store != null) store = store.Parent; // walk to the top of the tree
return store?.Impl; return store?.Impl;
@ -144,6 +148,8 @@ namespace IPA.Config.Stores
} }
} }
internal const string GeneratedAssemblyName = "IPA.Config.Generated";
private static AssemblyBuilder assembly = null; private static AssemblyBuilder assembly = null;
private static AssemblyBuilder Assembly private static AssemblyBuilder Assembly
{ {
@ -151,20 +157,26 @@ namespace IPA.Config.Stores
{ {
if (assembly == null) if (assembly == null)
{ {
var name = new AssemblyName("IPA.Config.Generated");
var name = new AssemblyName(GeneratedAssemblyName);
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave); assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
} }
return assembly; return assembly;
} }
} }
internal static void DebugSaveAssembly(string file)
{
Assembly.Save(file);
}
private static ModuleBuilder module = null; private static ModuleBuilder module = null;
private static ModuleBuilder Module private static ModuleBuilder Module
{ {
get get
{ {
if (module == null) if (module == null)
module = Assembly.DefineDynamicModule(Assembly.GetName().Name);
module = Assembly.DefineDynamicModule(Assembly.GetName().Name + ".dll");
return module; return module;
} }
@ -412,7 +424,7 @@ namespace IPA.Config.Stores
typeBuilder.DefineMethodOverride(readFrom, IConfigStore_ReadFrom); typeBuilder.DefineMethodOverride(readFrom, IConfigStore_ReadFrom);
{ {
var il = writeTo.GetILGenerator();
var il = readFrom.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, Impl.FindImplMethod); il.Emit(OpCodes.Call, Impl.FindImplMethod);


Loading…
Cancel
Save