Browse Source

Updated all of the config references to use new system

4.0.0-beta
Anairkoen Schno 5 years ago
parent
commit
a1d6acbf23
11 changed files with 93 additions and 96 deletions
  1. +6
    -6
      BSIPA-ModList/UI/ViewControllers/SettingsViewController.cs
  2. +12
    -1
      IPA.Loader/Config/Config.cs
  3. +37
    -17
      IPA.Loader/Config/ConfigRuntime.cs
  4. +15
    -31
      IPA.Loader/Config/SelfConfig.cs
  5. +9
    -2
      IPA.Loader/Config/Stores/GeneratedStore.cs
  6. +5
    -19
      IPA.Loader/Loader/DisabledConfig.cs
  7. +1
    -7
      IPA.Loader/Loader/PluginComponent.cs
  8. +2
    -4
      IPA.Loader/Loader/PluginInitInjector.cs
  9. +3
    -4
      IPA.Loader/Loader/PluginLoader.cs
  10. +2
    -4
      IPA.Loader/Loader/PluginManager.cs
  11. +1
    -1
      IPA.Loader/Logging/StandardLogger.cs

+ 6
- 6
BSIPA-ModList/UI/ViewControllers/SettingsViewController.cs View File

@ -20,19 +20,19 @@ namespace BSIPA_ModList.UI
showEnableDisable = menu.AddBool("Show Enable/Disable Button", "If enabled, BSIPA mods will have a button to enable or disable them."); showEnableDisable = menu.AddBool("Show Enable/Disable Button", "If enabled, BSIPA mods will have a button to enable or disable them.");
autoCheck.applyImmediately = true; autoCheck.applyImmediately = true;
autoCheck.GetValue += () => IPA.Config.SelfConfig.SelfConfigRef.Value.Updates.AutoCheckUpdates;
autoCheck.GetValue += () => IPA.Config.SelfConfig.Instance.Value.Updates.AutoCheckUpdates;
autoCheck.SetValue += val => autoCheck.SetValue += val =>
{ {
IPA.Config.SelfConfig.SelfConfigRef.Value.Updates.AutoCheckUpdates = val;
IPA.Config.SelfConfig.LoaderConfig.Store(IPA.Config.SelfConfig.SelfConfigRef.Value);
IPA.Config.SelfConfig.Instance.Value.Updates.AutoCheckUpdates = val;
IPA.Config.SelfConfig.LoaderConfig.Store(IPA.Config.SelfConfig.Instance.Value);
}; };
autoUpdate.applyImmediately = true; autoUpdate.applyImmediately = true;
autoUpdate.GetValue += () => IPA.Config.SelfConfig.SelfConfigRef.Value.Updates.AutoUpdate;
autoUpdate.GetValue += () => IPA.Config.SelfConfig.Instance.Value.Updates.AutoUpdate;
autoUpdate.SetValue += val => autoUpdate.SetValue += val =>
{ {
IPA.Config.SelfConfig.SelfConfigRef.Value.Updates.AutoUpdate = val;
IPA.Config.SelfConfig.LoaderConfig.Store(IPA.Config.SelfConfig.SelfConfigRef.Value);
IPA.Config.SelfConfig.Instance.Value.Updates.AutoUpdate = val;
IPA.Config.SelfConfig.LoaderConfig.Store(IPA.Config.SelfConfig.Instance.Value);
}; };
showEnableDisable.applyImmediately = true; showEnableDisable.applyImmediately = true;


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

@ -4,6 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPA.Config.Providers; using IPA.Config.Providers;
using IPA.Utilities; using IPA.Utilities;
#if NET3 #if NET3
@ -116,7 +117,7 @@ namespace IPA.Config
return config; return config;
} }
internal static Config GetProviderFor(string modName, ParameterInfo info)
internal static Config GetConfigFor(string modName, ParameterInfo info)
{ {
var prefs = Array.Empty<string>(); var prefs = Array.Empty<string>();
if (info.GetCustomAttribute<PreferAttribute>() is PreferAttribute prefer) if (info.GetCustomAttribute<PreferAttribute>() is PreferAttribute prefer)
@ -151,6 +152,16 @@ namespace IPA.Config
Store = store; Store = store;
} }
/// <summary>
/// Forces a synchronous load from disk.
/// </summary>
public void LoadSync() => LoadAsync().Wait();
/// <summary>
/// Forces an asynchronous load from disk.
/// </summary>
public Task LoadAsync() => ConfigRuntime.TriggerFileLoad(this);
private Config(string name, IConfigProvider provider, FileInfo file) private Config(string name, IConfigProvider provider, FileInfo file)
{ {
Name = name; Provider = provider; File = file; Name = name; Provider = provider; File = file;


+ 37
- 17
IPA.Loader/Config/ConfigRuntime.cs View File

@ -114,6 +114,42 @@ namespace IPA.Config
public static Task TriggerFileLoad(Config config) => loadFactory.StartNew(() => LoadTask(config)); public static Task TriggerFileLoad(Config config) => loadFactory.StartNew(() => LoadTask(config));
public static Task TriggerLoadAll()
=> Task.WhenAll(configs.Select(TriggerFileLoad));
/// <summary>
/// this is synchronous, unlike <see cref="TriggerFileLoad(Config)"/>
/// </summary>
/// <param name="config"></param>
public static void Save(Config config)
{
var store = config.Store;
try
{
using var readLock = Synchronization.LockRead(store.WriteSyncObject);
lock (config.Provider)
{
config.Provider.File = config.File;
store.WriteTo(config.Provider);
}
}
catch (Exception e)
{
Logger.config.Error($"{nameof(IConfigStore)} for {config.File} errored while writing to disk");
Logger.config.Error(e);
}
}
/// <summary>
/// this is synchronous, unlike <see cref="TriggerLoadAll"/>
/// </summary>
public static void SaveAll()
{
foreach (var config in configs)
Save(config);
}
private static void LoadTask(Config config) private static void LoadTask(Config config)
{ // these tasks will always be running in the same thread as each other { // these tasks will always be running in the same thread as each other
try try
@ -149,23 +185,7 @@ namespace IPA.Config
} }
// otherwise, we have a thing that changed in a store // otherwise, we have a thing that changed in a store
var config = configArr[index - 1];
var store = config.Store;
try
{
using var readLock = Synchronization.LockRead(store.WriteSyncObject);
lock (config.Provider)
{
config.Provider.File = config.File;
store.WriteTo(config.Provider);
}
}
catch (Exception e)
{
Logger.config.Error($"{nameof(IConfigStore)} for {config.File} errored while writing to disk");
Logger.config.Error(e);
}
Save(configArr[index - 1]);
} }
} }
} }


+ 15
- 31
IPA.Loader/Config/SelfConfig.cs View File

@ -1,6 +1,7 @@
// BEGIN: section ignore // BEGIN: section ignore
using IPA.Logging; using IPA.Logging;
using IPA.Utilities; using IPA.Utilities;
using IPA.Config.Stores;
// END: section ignore // END: section ignore
using Newtonsoft.Json; using Newtonsoft.Json;
@ -11,31 +12,14 @@ namespace IPA.Config
// This is to allow the doc generation to parse this file and use Newtonsoft to generate a JSON schema // This is to allow the doc generation to parse this file and use Newtonsoft to generate a JSON schema
// BEGIN: section ignore // BEGIN: section ignore
private static IConfigProvider _loaderConfig;
public static Config LoaderConfig { get; set; }
public static IConfigProvider LoaderConfig
{
get => _loaderConfig;
set
{
_loaderConfig?.RemoveLinks();
value.Load();
SelfConfigRef = value.MakeLink<SelfConfig>((c, v) =>
{
if (v.Value.Regenerate)
c.Store(v.Value = new SelfConfig { Regenerate = false });
StandardLogger.Configure(v.Value);
});
_loaderConfig = value;
}
}
public static Ref<SelfConfig> SelfConfigRef = new SelfConfig();
public static SelfConfig Instance = new SelfConfig();
public static void Load() public static void Load()
{ {
LoaderConfig = Config.GetConfigFor(IPAName, "json"); LoaderConfig = Config.GetConfigFor(IPAName, "json");
Instance = LoaderConfig.Generated<SelfConfig>();
} }
public static void ReadCommandLine(string[] args) public static void ReadCommandLine(string[] args)
@ -81,12 +65,12 @@ namespace IPA.Config
{ {
public bool AutoUpdate = true; public bool AutoUpdate = true;
// LINE: ignore 2 // LINE: ignore 2
public static bool AutoUpdate_ => SelfConfigRef.Value.Updates.AutoUpdate
public static bool AutoUpdate_ => Instance.Updates.AutoUpdate
&& CommandLineValues.Updates.AutoUpdate; && CommandLineValues.Updates.AutoUpdate;
public bool AutoCheckUpdates = true; public bool AutoCheckUpdates = true;
// LINE: ignore 2 // LINE: ignore 2
public static bool AutoCheckUpdates_ => SelfConfigRef.Value.Updates.AutoCheckUpdates
public static bool AutoCheckUpdates_ => Instance.Updates.AutoCheckUpdates
&& CommandLineValues.Updates.AutoCheckUpdates; && CommandLineValues.Updates.AutoCheckUpdates;
} }
@ -96,35 +80,35 @@ namespace IPA.Config
{ {
public bool ShowCallSource = false; public bool ShowCallSource = false;
// LINE: ignore 2 // LINE: ignore 2
public static bool ShowCallSource_ => SelfConfigRef.Value.Debug.ShowCallSource
public static bool ShowCallSource_ => Instance.Debug.ShowCallSource
|| CommandLineValues.Debug.ShowCallSource; || CommandLineValues.Debug.ShowCallSource;
public bool ShowDebug = false; public bool ShowDebug = false;
// LINE: ignore 2 // LINE: ignore 2
public static bool ShowDebug_ => SelfConfigRef.Value.Debug.ShowDebug
public static bool ShowDebug_ => Instance.Debug.ShowDebug
|| CommandLineValues.Debug.ShowDebug; || CommandLineValues.Debug.ShowDebug;
// This option only takes effect after a full game restart, unless new logs are created again // This option only takes effect after a full game restart, unless new logs are created again
public bool CondenseModLogs = false; public bool CondenseModLogs = false;
// LINE: ignore 2 // LINE: ignore 2
public static bool CondenseModLogs_ => SelfConfigRef?.Value.Debug.CondenseModLogs ?? false
public static bool CondenseModLogs_ => Instance?.Debug.CondenseModLogs ?? false
|| CommandLineValues.Debug.CondenseModLogs; || CommandLineValues.Debug.CondenseModLogs;
public bool ShowHandledErrorStackTraces = false; public bool ShowHandledErrorStackTraces = false;
// LINE: ignore // LINE: ignore
public static bool ShowHandledErrorStackTraces_ => SelfConfigRef.Value.Debug.ShowHandledErrorStackTraces;
public static bool ShowHandledErrorStackTraces_ => Instance.Debug.ShowHandledErrorStackTraces;
public bool HideMessagesForPerformance = true; public bool HideMessagesForPerformance = true;
// LINE: ignore // LINE: ignore
public static bool HideMessagesForPerformance_ => SelfConfigRef.Value.Debug.HideMessagesForPerformance;
public static bool HideMessagesForPerformance_ => Instance.Debug.HideMessagesForPerformance;
public int HideLogThreshold = 512; public int HideLogThreshold = 512;
// LINE: ignore // LINE: ignore
public static int HideLogThreshold_ => SelfConfigRef.Value.Debug.HideLogThreshold;
public static int HideLogThreshold_ => Instance.Debug.HideLogThreshold;
public bool ShowTrace = false; public bool ShowTrace = false;
// LINE: ignore 2 // LINE: ignore 2
public static bool ShowTrace_ => SelfConfigRef.Value.Debug.ShowTrace
public static bool ShowTrace_ => Instance.Debug.ShowTrace
|| CommandLineValues.Debug.ShowTrace; || CommandLineValues.Debug.ShowTrace;
} }
@ -132,12 +116,12 @@ namespace IPA.Config
public bool YeetMods = true; public bool YeetMods = true;
// LINE: ignore 2 // LINE: ignore 2
public static bool YeetMods_ => SelfConfigRef.Value.YeetMods
public static bool YeetMods_ => Instance.YeetMods
&& CommandLineValues.YeetMods; && CommandLineValues.YeetMods;
[JsonProperty(Required = Required.Default)] [JsonProperty(Required = Required.Default)]
public string LastGameVersion = null; public string LastGameVersion = null;
// LINE: ignore // LINE: ignore
public static string LastGameVersion_ => SelfConfigRef.Value.LastGameVersion;
public static string LastGameVersion_ => Instance.LastGameVersion;
} }
} }

+ 9
- 2
IPA.Loader/Config/Stores/GeneratedStore.cs View File

@ -24,7 +24,8 @@ namespace IPA.Config.Stores
{ {
/// <summary> /// <summary>
/// Creates a generated <see cref="IConfigStore"/> of type <typeparamref name="T"/>, registers it to /// Creates a generated <see cref="IConfigStore"/> of type <typeparamref name="T"/>, registers it to
/// the <see cref="Config"/> object, and returns it.
/// the <see cref="Config"/> object, and returns it. This also forces a synchronous config load via
/// <see cref="Config.LoadSync"/> if <paramref name="loadSync"/> is <see langword="true"/>.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
@ -36,11 +37,17 @@ namespace IPA.Config.Stores
/// </remarks> /// </remarks>
/// <typeparam name="T">the type to wrap</typeparam> /// <typeparam name="T">the type to wrap</typeparam>
/// <param name="cfg">the <see cref="Config"/> to register to</param> /// <param name="cfg">the <see cref="Config"/> to register to</param>
/// <param name="loadSync">whether to synchronously load the content, or trigger an async load</param>
/// <returns>a generated instance of <typeparamref name="T"/> as a special <see cref="IConfigStore"/></returns> /// <returns>a generated instance of <typeparamref name="T"/> as a special <see cref="IConfigStore"/></returns>
public static T Generated<T>(this Config cfg) where T : class
public static T Generated<T>(this Config cfg, bool loadSync = true) where T : class
{ {
var ret = GeneratedStore.Create<T>(); var ret = GeneratedStore.Create<T>();
cfg.SetStore(ret as IConfigStore); cfg.SetStore(ret as IConfigStore);
if (loadSync)
cfg.LoadSync();
else
cfg.LoadAsync();
return ret; return ret;
} }
} }


+ 5
- 19
IPA.Loader/Loader/DisabledConfig.cs View File

@ -1,4 +1,5 @@
using IPA.Config; using IPA.Config;
using IPA.Config.Stores;
using IPA.Utilities; using IPA.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,29 +11,14 @@ namespace IPA.Loader
{ {
internal class DisabledConfig internal class DisabledConfig
{ {
private static IConfigProvider _provider;
public static Config.Config Disabled { get; set; }
public static IConfigProvider Provider
{
get => _provider;
set
{
_provider?.RemoveLinks();
value.Load();
Ref = value.MakeLink<DisabledConfig>((c, v) =>
{
if (v.Value.Reset)
c.Store(v.Value = new DisabledConfig { Reset = false });
});
_provider = value;
}
}
public static Ref<DisabledConfig> Ref;
public static DisabledConfig Instance;
public static void Load() public static void Load()
{ {
Provider = Config.Config.GetConfigFor("Disabled Mods", "json");
Disabled = Config.Config.GetConfigFor("Disabled Mods", "json");
Instance = Disabled.Generated<DisabledConfig>();
} }
public bool Reset = true; public bool Reset = true;


+ 1
- 7
IPA.Loader/Loader/PluginComponent.cs View File

@ -39,24 +39,18 @@ namespace IPA.Loader
SceneManager.activeSceneChanged += OnActiveSceneChanged; SceneManager.activeSceneChanged += OnActiveSceneChanged;
SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded; SceneManager.sceneUnloaded += OnSceneUnloaded;
Config.Config.Save();
} }
void Update() void Update()
{ {
bsPlugins.OnUpdate(); bsPlugins.OnUpdate();
ipaPlugins.OnUpdate(); ipaPlugins.OnUpdate();
Config.Config.Update();
} }
void LateUpdate() void LateUpdate()
{ {
bsPlugins.OnLateUpdate(); bsPlugins.OnLateUpdate();
ipaPlugins.OnLateUpdate(); ipaPlugins.OnLateUpdate();
//Config.Config.Update();
} }
void FixedUpdate() void FixedUpdate()
@ -82,7 +76,7 @@ namespace IPA.Loader
bsPlugins.OnApplicationQuit(); bsPlugins.OnApplicationQuit();
ipaPlugins.OnApplicationQuit(); ipaPlugins.OnApplicationQuit();
Config.Config.Save();
ConfigRuntime.SaveAll();
quitting = true; quitting = true;
} }


+ 2
- 4
IPA.Loader/Loader/PluginInitInjector.cs View File

@ -68,12 +68,10 @@ namespace IPA.Loader
new TypedInjector(typeof(IModPrefs), (prev, param, meta) => prev ?? new ModPrefs(meta)), new TypedInjector(typeof(IModPrefs), (prev, param, meta) => prev ?? new ModPrefs(meta)),
#pragma warning restore CS0618 // Type or member is obsolete #pragma warning restore CS0618 // Type or member is obsolete
new TypedInjector(typeof(PluginLoader.PluginMetadata), (prev, param, meta) => prev ?? meta), new TypedInjector(typeof(PluginLoader.PluginMetadata), (prev, param, meta) => prev ?? meta),
new TypedInjector(typeof(IConfigProvider), (prev, param, meta) =>
new TypedInjector(typeof(Config.Config), (prev, param, meta) =>
{ {
if (prev != null) return prev; if (prev != null) return prev;
var cfgProvider = Config.Config.GetProviderFor(meta.Name, param);
cfgProvider.Load();
return cfgProvider;
return Config.Config.GetConfigFor(meta.Name, param);
}) })
}; };


+ 3
- 4
IPA.Loader/Loader/PluginLoader.cs View File

@ -154,8 +154,7 @@ namespace IPA.Loader
Directory.CreateDirectory(pluginDir); Directory.CreateDirectory(pluginDir);
} }
SelfConfig.SelfConfigRef.Value.LastGameVersion = gameVer.ToString();
SelfConfig.LoaderConfig.Store(SelfConfig.SelfConfigRef.Value);
SelfConfig.Instance.LastGameVersion = gameVer.ToString();
} }
internal static List<PluginMetadata> PluginsMetadata = new List<PluginMetadata>(); internal static List<PluginMetadata> PluginsMetadata = new List<PluginMetadata>();
@ -409,7 +408,7 @@ namespace IPA.Loader
{ {
var enabled = new List<PluginMetadata>(PluginsMetadata.Count); var enabled = new List<PluginMetadata>(PluginsMetadata.Count);
var disabled = DisabledConfig.Ref.Value.DisabledModIds;
var disabled = DisabledConfig.Instance.DisabledModIds;
foreach (var meta in PluginsMetadata) foreach (var meta in PluginsMetadata)
{ {
if (disabled.Contains(meta.Id ?? meta.Name)) if (disabled.Contains(meta.Id ?? meta.Name))
@ -523,7 +522,7 @@ namespace IPA.Loader
else if (disable) else if (disable)
{ {
DisabledPlugins.Add(meta); DisabledPlugins.Add(meta);
DisabledConfig.Ref.Value.DisabledModIds.Add(meta.Id ?? meta.Name);
DisabledConfig.Instance.DisabledModIds.Add(meta.Id ?? meta.Name);
} }
else else
ignoredPlugins.Add(meta); ignoredPlugins.Add(meta);


+ 2
- 4
IPA.Loader/Loader/PluginManager.cs View File

@ -105,8 +105,7 @@ namespace IPA.Loader
var dependents = BSMetas.Where(m => m.Metadata.Dependencies.Contains(plugin.Metadata)).ToList(); var dependents = BSMetas.Where(m => m.Metadata.Dependencies.Contains(plugin.Metadata)).ToList();
needsRestart = dependents.Aggregate(needsRestart, (b, p) => DisablePlugin(p) || b); needsRestart = dependents.Aggregate(needsRestart, (b, p) => DisablePlugin(p) || b);
DisabledConfig.Ref.Value.DisabledModIds.Add(plugin.Metadata.Id ?? plugin.Metadata.Name);
DisabledConfig.Provider.Store(DisabledConfig.Ref.Value);
DisabledConfig.Instance.DisabledModIds.Add(plugin.Metadata.Id ?? plugin.Metadata.Name);
if (!needsRestart && plugin.Plugin is IDisablablePlugin disable) if (!needsRestart && plugin.Plugin is IDisablablePlugin disable)
{ {
@ -167,8 +166,7 @@ namespace IPA.Loader
Logger.loader.Info($"Enabling {plugin.Name}"); Logger.loader.Info($"Enabling {plugin.Name}");
DisabledConfig.Ref.Value.DisabledModIds.Remove(plugin.Id ?? plugin.Name);
DisabledConfig.Provider.Store(DisabledConfig.Ref.Value);
DisabledConfig.Instance.DisabledModIds.Remove(plugin.Id ?? plugin.Name);
var needsRestart = true; var needsRestart = true;


+ 1
- 1
IPA.Loader/Logging/StandardLogger.cs View File

@ -305,7 +305,7 @@ namespace IPA.Logging
} }
} }
var debugConfig = SelfConfig.SelfConfigRef?.Value?.Debug;
var debugConfig = SelfConfig.Instance?.Debug;
if (debugConfig != null && debugConfig.HideMessagesForPerformance if (debugConfig != null && debugConfig.HideMessagesForPerformance
&& logQueue.Count > debugConfig.HideLogThreshold) && logQueue.Count > debugConfig.HideLogThreshold)


Loading…
Cancel
Save