From 4a7fb011753bf53c108f44e41f6ba167ab1edf1c Mon Sep 17 00:00:00 2001 From: ghorsington Date: Sun, 27 Jun 2021 21:36:21 +0300 Subject: [PATCH] Rework IConfigurationProvider API --- BepInEx.Core/Configuration/ConfigFile.cs | 21 +++---- .../Provider/ConfigurationPath.cs | 17 ------ .../Provider/IConfigurationProvider.cs | 21 +++++-- .../Provider/LegacyConfigurationProvider.cs | 57 +++++++++++++++---- 4 files changed, 75 insertions(+), 41 deletions(-) delete mode 100644 BepInEx.Core/Configuration/Provider/ConfigurationPath.cs diff --git a/BepInEx.Core/Configuration/ConfigFile.cs b/BepInEx.Core/Configuration/ConfigFile.cs index 9f409e2..98e0147 100644 --- a/BepInEx.Core/Configuration/ConfigFile.cs +++ b/BepInEx.Core/Configuration/ConfigFile.cs @@ -16,30 +16,31 @@ namespace BepInEx.Configuration { private readonly BepInPlugin _ownerMetadata; - /// + /// public ConfigFile(string configPath, bool saveOnInit) : this(configPath, saveOnInit, null) { } + /// + public ConfigFile(string configPath, bool saveOnInit, BepInPlugin ownerMetadata) : this(new LegacyConfigurationProvider(configPath), saveOnInit, ownerMetadata) { } + /// /// Create a new config file at the specified config path. /// /// Full path to a file that contains settings. The file will be created as needed. /// If the config file/directory doesn't exist, create it immediately. /// Information about the plugin that owns this setting file. - public ConfigFile(string configPath, bool saveOnInit, BepInPlugin ownerMetadata) + public ConfigFile(IConfigurationProvider configurationProvider, bool saveOnInit, BepInPlugin ownerMetadata) { _ownerMetadata = ownerMetadata; - - if (configPath == null) throw new ArgumentNullException(nameof(configPath)); - configPath = Path.GetFullPath(configPath); - ConfigFilePath = configPath; - - if (File.Exists(ConfigFilePath)) - Reload(); - else if (saveOnInit) Save(); + ConfigurationProvider = configurationProvider; + + Reload(); + if (saveOnInit) Save(); } public static ConfigFile CoreConfig { get; } = new(Paths.BepInExConfigPath, true); + public IConfigurationProvider ConfigurationProvider { get; set; } + /// /// All config entries inside /// diff --git a/BepInEx.Core/Configuration/Provider/ConfigurationPath.cs b/BepInEx.Core/Configuration/Provider/ConfigurationPath.cs deleted file mode 100644 index 74aec87..0000000 --- a/BepInEx.Core/Configuration/Provider/ConfigurationPath.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace BepInEx.Configuration -{ - public static class ConfigurationPath - { - public static readonly string KeyDelimiter = ":"; - - public static string Combine(IEnumerable segements) - { - segements = segements ?? throw new ArgumentNullException(nameof(segements)); - return string.Join(KeyDelimiter, segements.ToArray()); - } - } -} diff --git a/BepInEx.Core/Configuration/Provider/IConfigurationProvider.cs b/BepInEx.Core/Configuration/Provider/IConfigurationProvider.cs index 0fed319..9b62794 100644 --- a/BepInEx.Core/Configuration/Provider/IConfigurationProvider.cs +++ b/BepInEx.Core/Configuration/Provider/IConfigurationProvider.cs @@ -1,13 +1,26 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; namespace BepInEx.Configuration { public interface IConfigurationProvider { - public IDictionary RawData { get; } + public void Load(); - public void Load(string resourceUri); + public void Save(); - public void Save(string resourceUri); + public ConfigurationNode Get(string[] path); + + public void Set(string[] path, ConfigurationNode node); + + public IEnumerable EntryPaths { get; } + } + + public class ConfigurationNode + { + public string Value { get; set; } + public string Comment { get; set; } + public Type ValueType { get; set; } } } diff --git a/BepInEx.Core/Configuration/Provider/LegacyConfigurationProvider.cs b/BepInEx.Core/Configuration/Provider/LegacyConfigurationProvider.cs index daa28b5..1a53034 100644 --- a/BepInEx.Core/Configuration/Provider/LegacyConfigurationProvider.cs +++ b/BepInEx.Core/Configuration/Provider/LegacyConfigurationProvider.cs @@ -6,17 +6,40 @@ namespace BepInEx.Configuration { public class LegacyConfigurationProvider : IConfigurationProvider { - public IDictionary RawData { get; private set; } + private string filePath; - public void Load(string resourceUri) + private Dictionary items = new(new ArrayComparer()); + + private class ArrayComparer : IEqualityComparer { - if (!File.Exists(resourceUri)) - throw new FileNotFoundException(resourceUri); + public bool Equals(string[] x, string[] y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + return x.GetType() == y.GetType() && x.SequenceEqual(y); + } + + public int GetHashCode(string[] arr) + { + return arr.Aggregate(1009, (current, s) => current * 9176 + s.GetHashCode()); + } + } + + public LegacyConfigurationProvider(string filePath) + { + if (!File.Exists(filePath)) + throw new FileNotFoundException(filePath); + this.filePath = filePath; + } + + public void Load() + { + items.Clear(); - var dict = new Dictionary(); var currentSection = new string[0]; - foreach (var rawLine in File.ReadAllLines(resourceUri)) + foreach (var rawLine in File.ReadAllLines(filePath)) { var line = rawLine.Trim(); @@ -36,12 +59,26 @@ namespace BepInEx.Configuration var currentKey = split[0].Trim(); var currentValue = split[1].Trim(); - dict[ConfigurationPath.Combine(currentSection.Concat(new []{ currentKey }))] = currentValue; + items[currentSection.Concat(new[] { currentKey }).ToArray()] = currentValue; } - - RawData = dict; } - public void Save(string resourceUri) => throw new System.NotImplementedException(); + // TODO: Write to TOML instead + public void Save() => throw new System.NotImplementedException(); + + public ConfigurationNode Get(string[] path) + { + if (!items.TryGetValue(path, out var value)) + return null; + return new ConfigurationNode + { + ValueType = typeof(string), + Value = value + }; + } + + public void Set(string[] path, ConfigurationNode node) => items[path] = node.Value; + + public IEnumerable EntryPaths => items.Keys.ToList(); } }