diff --git a/IPA.Loader/Config/Config.cs b/IPA.Loader/Config/Config.cs
index 90564ea9..a9114a19 100644
--- a/IPA.Loader/Config/Config.cs
+++ b/IPA.Loader/Config/Config.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Runtime.CompilerServices;
using IPA.Config.Providers;
using IPA.Utilities;
#if NET3
@@ -19,7 +20,7 @@ namespace IPA.Config
{
static Config()
{
- JsonConfigProvider.RegisterConfig();
+ //JsonConfigProvider.RegisterConfig();
}
///
@@ -110,19 +111,18 @@ namespace IPA.Config
/// the type to register
public static void Register(Type type)
{
- if (!(type.GetCustomAttribute(typeof(TypeAttribute)) is TypeAttribute ext))
- throw new InvalidOperationException("Type does not have TypeAttribute");
+ var inst = Activator.CreateInstance(type) as IConfigProvider;
+ if (inst == null)
+ throw new ArgumentException($"Type not an {nameof(IConfigProvider)}");
- if (!typeof(IConfigProvider).IsAssignableFrom(type))
- throw new InvalidOperationException("Type not IConfigProvider");
+ if (registeredProviders.ContainsKey(inst.Extension))
+ throw new InvalidOperationException($"Extension provider for {inst.Extension} already exists");
- if (registeredProviders.ContainsKey(ext.Extension))
- throw new InvalidOperationException($"Extension provider for {ext.Extension} already exists");
-
- registeredProviders.Add(ext.Extension, type);
+ registeredProviders.Add(inst.Extension, type);
}
- private static List, IConfigProvider>> configProviders = new List, IConfigProvider>>();
+ private static List configProviders = new List();
+ private static ConditionalWeakTable file = new ConditionalWeakTable();
///
/// Gets an using the specified list of preferred config types.
@@ -135,11 +135,9 @@ namespace IPA.Config
var chosenExt = extensions.FirstOrDefault(s => registeredProviders.ContainsKey(s)) ?? "json";
var type = registeredProviders[chosenExt];
var provider = Activator.CreateInstance(type) as IConfigProvider;
- if (provider != null)
- {
- provider.Filename = Path.Combine(BeatSaber.UserDataPath, configName);
- configProviders.Add(Tuple.Create(Ref.Create(provider.LastModified), provider));
- }
+ configProviders.Add(provider);
+
+ // TODO: rething this one a bit
return provider;
}
@@ -154,108 +152,5 @@ namespace IPA.Config
return GetProviderFor(modName, prefs);
}
-
- private static Dictionary linkedProviders =
- new Dictionary();
-
- ///
- /// Creates a linked for the config provider. This will be automatically updated whenever the file on-disk changes.
- ///
- /// the type of the parsed value
- /// the to create a link to
- /// an action to perform on value change
- /// a to an ever-changing value, mirroring whatever the file contains.
- public static Ref MakeLink(this IConfigProvider config, Action> onChange = null)
- { // TODO: rework this stuff
- Ref @ref = config.Parse();
- void ChangeDelegate()
- {
- @ref.Value = config.Parse();
- onChange?.Invoke(config, @ref);
- }
-
- if (linkedProviders.ContainsKey(config))
- linkedProviders[config] = (Action) Delegate.Combine(linkedProviders[config], (Action) ChangeDelegate);
- else
- linkedProviders.Add(config, ChangeDelegate);
-
- ChangeDelegate();
-
- return @ref;
- }
-
- ///
- /// Removes all linked such that they are no longer updated.
- ///
- /// the to unlink
- public static void RemoveLinks(this IConfigProvider config)
- {
- if (linkedProviders.ContainsKey(config))
- linkedProviders.Remove(config);
- }
-
- internal static void Update()
- {
- foreach (var provider in configProviders)
- {
- if (provider.Item2.LastModified > provider.Item1.Value)
- {
- try
- {
- provider.Item2.Load(); // auto reload if it changes
- provider.Item1.Value = provider.Item2.LastModified;
- }
- catch (Exception e)
- {
- Logging.Logger.config.Error("Error when trying to load config");
- Logging.Logger.config.Error(e);
- }
- }
- if (provider.Item2.HasChanged)
- {
- try
- {
- provider.Item2.Save();
- provider.Item1.Value = Utils.CurrentTime();
- }
- catch (Exception e)
- {
- Logging.Logger.config.Error("Error when trying to save config");
- Logging.Logger.config.Error(e);
- }
- }
-
- if (provider.Item2.InMemoryChanged)
- {
- provider.Item2.InMemoryChanged = false;
- try
- {
- if (linkedProviders.ContainsKey(provider.Item2))
- linkedProviders[provider.Item2]();
- }
- catch (Exception e)
- {
- Logging.Logger.config.Error("Error running link change events");
- Logging.Logger.config.Error(e);
- }
- }
- }
- }
-
- internal static void Save()
- {
- foreach (var provider in configProviders)
- if (provider.Item2.HasChanged)
- try
- {
- provider.Item2.Save();
- }
- catch (Exception e)
- {
- Logging.Logger.config.Error("Error when trying to save config");
- Logging.Logger.config.Error(e);
- }
- }
-
}
}
diff --git a/IPA.Loader/Config/IConfigProvider.cs b/IPA.Loader/Config/IConfigProvider.cs
index 69ff72c8..710145f6 100644
--- a/IPA.Loader/Config/IConfigProvider.cs
+++ b/IPA.Loader/Config/IConfigProvider.cs
@@ -1,63 +1,49 @@
using System;
-// ReSharper disable UnusedMember.Global
+using System.IO;
+using IPA.Config.Data;
namespace IPA.Config
{
///
/// An interface for configuration providers.
///
+ ///
+ /// Implementers must provide a default constructor. Do not assume that will ever be set for a given object.
+ ///
public interface IConfigProvider
- { // TODO: rework this
+ {
///
- /// Loads the data provided by this into an object of type .
+ /// Gets the extension without a dot to use for files handled by this provider.
///
- /// the type of the object to parse into
- /// the values from the config provider parsed into the object
- T Parse();
- ///
- /// Stores the data from into the .
- ///
- /// the type of
- /// the object containing the data to save
- void Store(T obj);
+ ///
+ /// This must work immediately, and is used to generate the used to set
+ /// .
+ ///
+ string Extension { get; }
-#if NET4
///
- /// Gets a dynamic object providing access to the configuration.
+ /// Sets the file that this provider will read and write to.
///
- /// a dynamically bound object to use to access config values directly
- dynamic Dynamic { get; }
-#endif
+ ///
+ /// The provider is expected to gracefully handle this changing at any point,
+ /// and is expected to close any old file handles when this is reassigned.
+ /// This may be set to the same file multiple times in this object's lifetime.
+ /// This will always have been set at least once before any calls to
+ /// or are made.
+ ///
+ FileInfo File { set; }
-#region State getters
- ///
- /// Returns if object has changed since the last save
- ///
- /// if object has changed since the last save, else
- bool HasChanged { get; }
- ///
- /// Returns if the data in memory has been changed - notably including loads.
- ///
- /// if the data in memory has been changed, else
- bool InMemoryChanged { get; set; }
///
- /// Will be set with the filename (no extension) to save to. When saving, the implementation should add the appropriate extension. Should error if set multiple times.
+ /// Stores the given to disk in the format specified.
///
- /// the extensionless filename to save to
- string Filename { set; }
- ///
- /// Gets the last time the config was modified.
- ///
- /// the last time the config file was modified
- DateTime LastModified { get; }
- ///
- /// Saves configuration to file. Should error if not a root object.
- ///
- void Save();
+ /// the to store
+ void Store(Value value);
+
///
- /// Loads the state of the file on disk.
+ /// Loads a from disk in whatever format this provider provides
+ /// and returns it.
///
- void Load();
-#endregion
+ /// the loaded
+ Value Load();
}
}
diff --git a/IPA.Loader/Config/Providers/JsonConfigProvider.cs b/IPA.Loader/Config/Providers/JsonConfigProvider.cs
index 7daa9227..1ef6e04a 100644
--- a/IPA.Loader/Config/Providers/JsonConfigProvider.cs
+++ b/IPA.Loader/Config/Providers/JsonConfigProvider.cs
@@ -7,8 +7,8 @@ using System.ComponentModel;
using System.IO;
namespace IPA.Config.Providers
-{
- [Config.Type("json")]
+{ // TODO: implement this for the new provider system
+ /*[Config.Type("json")]
internal class JsonConfigProvider : IConfigProvider
{
public static void RegisterConfig()
@@ -123,5 +123,5 @@ namespace IPA.Config.Providers
HasChanged = true;
InMemoryChanged = true;
}
- }
+ }*/
}
\ No newline at end of file