From 970438883c44aadbc69168c1effa9c47d2471aea Mon Sep 17 00:00:00 2001 From: ManlyMarco Date: Mon, 12 Aug 2019 18:24:54 +0200 Subject: [PATCH] Added documentation, misc accessibility changes --- BepInEx/Configuration/ConfigDefinition.cs | 31 +++++++++ BepInEx/Configuration/ConfigDescription.cs | 16 ++++- BepInEx/Configuration/ConfigEntry.cs | 35 +++++++++- BepInEx/Configuration/ConfigFile.cs | 68 ++++++++++++++++--- BepInEx/Configuration/ConfigWrapper.cs | 17 +++++ .../Configuration/SettingChangedEventArgs.cs | 8 +++ BepInEx/Configuration/TomlTypeConverter.cs | 2 +- 7 files changed, 165 insertions(+), 12 deletions(-) diff --git a/BepInEx/Configuration/ConfigDefinition.cs b/BepInEx/Configuration/ConfigDefinition.cs index ff49c71..628b400 100644 --- a/BepInEx/Configuration/ConfigDefinition.cs +++ b/BepInEx/Configuration/ConfigDefinition.cs @@ -2,18 +2,38 @@ namespace BepInEx.Configuration { + /// + /// Section and key of a setting. Used as a unique key for identification within a . + /// The same definition can be used in multiple config files, it will point to different settings then. + /// + /// public class ConfigDefinition : IEquatable { + /// + /// Group of the setting. All settings within a config file are grouped by this. + /// public string Section { get; } + /// + /// Name of the setting. + /// public string Key { get; } + /// + /// Create a new definition. Definitions with same section and key are equal. + /// + /// Group of the setting, case sensitive. + /// Name of the setting, case sensitive. public ConfigDefinition(string section, string key) { Key = key; Section = section; } + /// + /// Check if the definitions are the same. + /// + /// public bool Equals(ConfigDefinition other) { if (other == null) return false; @@ -21,6 +41,9 @@ namespace BepInEx.Configuration && string.Equals(Section, other.Section); } + /// + /// Check if the definitions are the same. + /// public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) @@ -31,6 +54,7 @@ namespace BepInEx.Configuration return Equals(obj as ConfigDefinition); } + /// public override int GetHashCode() { unchecked @@ -41,12 +65,19 @@ namespace BepInEx.Configuration } } + /// + /// Check if the definitions are the same. + /// public static bool operator ==(ConfigDefinition left, ConfigDefinition right) => Equals(left, right); + /// + /// Check if the definitions are the same. + /// public static bool operator !=(ConfigDefinition left, ConfigDefinition right) => !Equals(left, right); + /// public override string ToString() { return Section + " / " + Key; diff --git a/BepInEx/Configuration/ConfigDescription.cs b/BepInEx/Configuration/ConfigDescription.cs index f14216f..2b0df1f 100644 --- a/BepInEx/Configuration/ConfigDescription.cs +++ b/BepInEx/Configuration/ConfigDescription.cs @@ -2,17 +2,29 @@ namespace BepInEx.Configuration { + //todo value range + /// + /// Metadata of a . + /// public class ConfigDescription { + /// + /// Create a new description. + /// + /// Text describing the function of the setting and any notes or warnings. public ConfigDescription(string description) { Description = description ?? throw new ArgumentNullException(nameof(description)); } + /// + /// Text describing the function of the setting and any notes or warnings. + /// public string Description { get; } - //todo value range - + /// + /// Convert the description object into a form suitable for writing into a config file. + /// public string ToSerializedString() { return $"# {Description.Replace("\n", "\n# ")}"; diff --git a/BepInEx/Configuration/ConfigEntry.cs b/BepInEx/Configuration/ConfigEntry.cs index 6ba9900..51c7339 100644 --- a/BepInEx/Configuration/ConfigEntry.cs +++ b/BepInEx/Configuration/ConfigEntry.cs @@ -5,6 +5,10 @@ using BepInEx.Logging; namespace BepInEx.Configuration { + /// + /// Container for a single setting of a . + /// Each config entry is linked to one config file. + /// public sealed class ConfigEntry { internal ConfigEntry(ConfigFile configFile, ConfigDefinition definition, Type settingType, object defaultValue) : this(configFile, definition) @@ -49,12 +53,29 @@ namespace BepInEx.Configuration private object _convertedValue; private string _serializedValue; + /// + /// Config file this entry is a part of. + /// public ConfigFile ConfigFile { get; } + + /// + /// Category and name of this setting. Used as a unique key for identification within a . + /// public ConfigDefinition Definition { get; } + /// + /// Description / metadata of this setting. + /// public ConfigDescription Description { get; internal set; } + /// + /// Type of the that this setting holds. + /// public Type SettingType { get; private set; } + + /// + /// Default value of this setting (set only if the setting was not changed before). + /// public object DefaultValue { get; private set; } /// @@ -64,6 +85,7 @@ namespace BepInEx.Configuration public bool IsDefined => SettingType != null; /// + /// Get or set the value of the setting. /// Can't be used when is false. /// public object Value @@ -91,6 +113,9 @@ namespace BepInEx.Configuration } } + /// + /// Get the serialized representation of the value. + /// public string GetSerializedValue() { if (_serializedValue != null) @@ -102,7 +127,12 @@ namespace BepInEx.Configuration return TomlTypeConverter.ConvertToString(Value, SettingType); } - public void SetSerializedValue(string newValue, bool fireEvent, object sender) + /// + /// Set the value by using its serialized form. + /// + public void SetSerializedValue(string newValue) => SetSerializedValue(newValue, true, this); + + internal void SetSerializedValue(string newValue, bool fireEvent, object sender) { string current = GetSerializedValue(); if (string.Equals(current, newValue)) return; @@ -162,6 +192,9 @@ namespace BepInEx.Configuration ConfigFile.OnSettingChanged(sender, this); } + /// + /// Write a description of this setting using all available metadata. + /// public void WriteDescription(StreamWriter writer) { if (Description != null) diff --git a/BepInEx/Configuration/ConfigFile.cs b/BepInEx/Configuration/ConfigFile.cs index 390d427..228c415 100644 --- a/BepInEx/Configuration/ConfigFile.cs +++ b/BepInEx/Configuration/ConfigFile.cs @@ -15,20 +15,40 @@ namespace BepInEx.Configuration { internal static ConfigFile CoreConfig { get; } = new ConfigFile(Paths.BepInExConfigPath, true); + /// + /// All config entries inside + /// protected Dictionary Entries { get; } = new Dictionary(); - [Obsolete("Use ConfigEntries instead")] + /// + /// Create a list with all config entries inside of this config file. + /// + [Obsolete("Use GetConfigEntries instead")] public ReadOnlyCollection ConfigDefinitions => Entries.Keys.ToList().AsReadOnly(); - public ReadOnlyCollection ConfigEntries => Entries.Values.ToList().AsReadOnly(); + /// + /// Create an array with all config entries inside of this config file. Should be only used for metadata purposes. + /// If you want to access and modify an existing setting then use + /// instead with no description. + /// + public ConfigEntry[] GetConfigEntries() => Entries.Values.ToArray(); + /// + /// Full path to the config file. The file might not exist until a setting is added and changed, or is called. + /// public string ConfigFilePath { get; } /// - /// If enabled, writes the config to disk every time a value is set. If disabled, you have to manually save or the changes will be lost! + /// If enabled, writes the config to disk every time a value is set. + /// If disabled, you have to manually use or the changes will be lost! /// public bool SaveOnConfigSet { get; set; } = true; + /// + /// 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. public ConfigFile(string configPath, bool saveOnInit) { if (configPath == null) throw new ArgumentNullException(nameof(configPath)); @@ -138,6 +158,16 @@ namespace BepInEx.Configuration #region Wraps + /// + /// Create a new setting or access one of the existing ones. The setting is saved to drive and loaded automatically. + /// If you are the creator of the setting, provide a ConfigDescription object to give user information about the setting. + /// If you are using a setting created by another plugin/class, do not provide any ConfigDescription. + /// + /// Type of the value contained in this setting. + /// Section and Key of the setting. + /// Value of the setting if the setting was not created yet. + /// Description of the setting shown to the user. + /// public ConfigWrapper Wrap(ConfigDefinition configDefinition, T defaultValue, ConfigDescription configDescription = null) { if (!TomlTypeConverter.CanConvert(typeof(T))) @@ -166,10 +196,26 @@ namespace BepInEx.Configuration return new ConfigWrapper(entry); } + /// + /// Create a new setting or access one of the existing ones. The setting is saved to drive and loaded automatically. + /// If you are the creator of the setting, provide a ConfigDescription object to give user information about the setting. + /// If you are using a setting created by another plugin/class, do not provide any ConfigDescription. + /// [Obsolete("Use other Wrap overloads instead")] public ConfigWrapper Wrap(string section, string key, string description = null, T defaultValue = default(T)) => Wrap(new ConfigDefinition(section, key), defaultValue, string.IsNullOrEmpty(description) ? null : new ConfigDescription(description)); + /// + /// Create a new setting or access one of the existing ones. The setting is saved to drive and loaded automatically. + /// If you are the creator of the setting, provide a ConfigDescription object to give user information about the setting. + /// If you are using a setting created by another plugin/class, do not provide any ConfigDescription. + /// + /// Type of the value contained in this setting. + /// Section/category/group of the setting. Settings are grouped by this. + /// Name of the setting. + /// Value of the setting if the setting was not created yet. + /// Description of the setting shown to the user. + /// public ConfigWrapper Wrap(string section, string key, T defaultValue, ConfigDescription configDescription = null) => Wrap(new ConfigDefinition(section, key), defaultValue, configDescription); @@ -187,7 +233,7 @@ namespace BepInEx.Configuration /// public event EventHandler SettingChanged; - protected internal void OnSettingChanged(object sender, ConfigEntry changedEntry) + internal void OnSettingChanged(object sender, ConfigEntry changedEntry) { if (changedEntry == null) throw new ArgumentNullException(nameof(changedEntry)); @@ -208,12 +254,13 @@ namespace BepInEx.Configuration } } - // todo better way to prevent write loop? maybe do some caching? + // Check sender to prevent infinite loops + // todo batching / async? if (sender != this && SaveOnConfigSet) Save(); } - protected void OnConfigReloaded() + private void OnConfigReloaded() { if (ConfigReloaded != null) { @@ -266,11 +313,16 @@ namespace BepInEx.Configuration { lock (_ioLock) { - _watcher?.Dispose(); - _watcher = null; + if (_watcher != null) + { + _watcher.EnableRaisingEvents = false; + _watcher.Dispose(); + _watcher = null; + } } } + /// ~ConfigFile() { StopWatching(); diff --git a/BepInEx/Configuration/ConfigWrapper.cs b/BepInEx/Configuration/ConfigWrapper.cs index 8f919f6..1e1f0eb 100644 --- a/BepInEx/Configuration/ConfigWrapper.cs +++ b/BepInEx/Configuration/ConfigWrapper.cs @@ -2,11 +2,25 @@ namespace BepInEx.Configuration { + /// + /// Provides access to a single setting inside of a . + /// + /// Type of the setting. public sealed class ConfigWrapper { + /// + /// Entry of this setting in the . + /// public ConfigEntry ConfigEntry { get; } + /// + /// Unique definition of this setting. + /// public ConfigDefinition Definition => ConfigEntry.Definition; + + /// + /// Config file this setting is inside of. + /// public ConfigFile ConfigFile => ConfigEntry.ConfigFile; /// @@ -14,6 +28,9 @@ namespace BepInEx.Configuration /// public event EventHandler SettingChanged; + /// + /// Value of this setting. + /// public T Value { get => (T)ConfigEntry.Value; diff --git a/BepInEx/Configuration/SettingChangedEventArgs.cs b/BepInEx/Configuration/SettingChangedEventArgs.cs index 3767e9b..53d81b2 100644 --- a/BepInEx/Configuration/SettingChangedEventArgs.cs +++ b/BepInEx/Configuration/SettingChangedEventArgs.cs @@ -2,13 +2,21 @@ namespace BepInEx.Configuration { + /// + /// Arguments for events concerning a change of a setting. + /// + /// public sealed class SettingChangedEventArgs : EventArgs { + /// public SettingChangedEventArgs(ConfigEntry changedSetting) { ChangedSetting = changedSetting; } + /// + /// Setting that was changed + /// public ConfigEntry ChangedSetting { get; } } } \ No newline at end of file diff --git a/BepInEx/Configuration/TomlTypeConverter.cs b/BepInEx/Configuration/TomlTypeConverter.cs index 8a836a3..aff8bde 100644 --- a/BepInEx/Configuration/TomlTypeConverter.cs +++ b/BepInEx/Configuration/TomlTypeConverter.cs @@ -4,7 +4,7 @@ using System.Globalization; namespace BepInEx.Configuration { - public class TypeConverter + internal class TypeConverter { public Func ConvertToString { get; set; } public Func ConvertToObject { get; set; }