summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Config.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/StardewModdingAPI/Config.cs')
-rw-r--r--src/StardewModdingAPI/Config.cs134
1 files changed, 57 insertions, 77 deletions
diff --git a/src/StardewModdingAPI/Config.cs b/src/StardewModdingAPI/Config.cs
index 7e5c4046..ff8ade90 100644
--- a/src/StardewModdingAPI/Config.cs
+++ b/src/StardewModdingAPI/Config.cs
@@ -1,8 +1,4 @@
-/*
- Copyright 2016 Zoey (Zoryn)
-*/
-
-using System;
+using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
@@ -10,119 +6,107 @@ using Newtonsoft.Json.Linq;
namespace StardewModdingAPI
{
+ /// <summary>A dynamic configuration class for a mod.</summary>
public abstract class Config
{
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The full path to the configuration file.</summary>
[JsonIgnore]
public virtual string ConfigLocation { get; protected internal set; }
+ /// <summary>The directory path containing the configuration file.</summary>
[JsonIgnore]
- public virtual string ConfigDir => Path.GetDirectoryName(ConfigLocation);
+ public virtual string ConfigDir => Path.GetDirectoryName(this.ConfigLocation);
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance of the config class.</summary>
+ /// <typeparam name="T">The config class type.</typeparam>
public virtual Config Instance<T>() where T : Config => Activator.CreateInstance<T>();
- /// <summary>
- /// Loads the config from the json blob on disk, updating and re-writing to the disk if needed.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
+ /// <summary>Load the config from the JSON file, saving it to disk if needed.</summary>
+ /// <typeparam name="T">The config class type.</typeparam>
public virtual T LoadConfig<T>() where T : Config
{
- if (string.IsNullOrEmpty(ConfigLocation))
+ // validate
+ if (string.IsNullOrEmpty(this.ConfigLocation))
{
Log.AsyncR("A config tried to load without specifying a location on the disk.");
return null;
}
- T ret = null;
-
- if (!File.Exists(ConfigLocation))
+ // read or generate config
+ T returnValue;
+ if (!File.Exists(this.ConfigLocation))
{
- //no config exists, generate default values
- var c = GenerateDefaultConfig<T>();
- c.ConfigLocation = ConfigLocation;
- ret = c;
+ T config = this.GenerateDefaultConfig<T>();
+ config.ConfigLocation = this.ConfigLocation;
+ returnValue = config;
}
else
{
try
{
- //try to load the config from a json blob on disk
T config = JsonConvert.DeserializeObject<T>(File.ReadAllText(this.ConfigLocation));
config.ConfigLocation = this.ConfigLocation;
-
- //update the config with default values if needed
- ret = config.UpdateConfig<T>();
+ returnValue = config.UpdateConfig<T>();
}
catch (Exception ex)
{
- Log.AsyncR($"Invalid JSON ({GetType().Name}): {ConfigLocation} \n{ex}");
- return GenerateDefaultConfig<T>();
+ Log.AsyncR($"Invalid JSON ({this.GetType().Name}): {this.ConfigLocation} \n{ex}");
+ return this.GenerateDefaultConfig<T>();
}
}
- ret.WriteConfig();
- return ret;
+ returnValue.WriteConfig();
+ return returnValue;
}
/// <summary>Get the default config values.</summary>
public abstract T GenerateDefaultConfig<T>() where T : Config;
- /// <summary>
- /// Merges a default-value config with the user-config on disk.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
+ /// <summary>Get the current configuration with missing values defaulted.</summary>
+ /// <typeparam name="T">The config class type.</typeparam>
public virtual T UpdateConfig<T>() where T : Config
{
try
{
- //default config
- var b = JObject.FromObject(this.Instance<T>().GenerateDefaultConfig<T>());
-
- //user config
- var u = JObject.FromObject(this);
-
- //overwrite default values with user values
- b.Merge(u, new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Replace});
+ // get default + user config
+ JObject defaultConfig = JObject.FromObject(this.Instance<T>().GenerateDefaultConfig<T>());
+ JObject currentConfig = JObject.FromObject(this);
+ defaultConfig.Merge(currentConfig, new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Replace });
- //cast json object to config
- var c = b.ToObject<T>();
+ // cast json object to config
+ T config = defaultConfig.ToObject<T>();
- //re-write the location on disk to the object
- c.ConfigLocation = this.ConfigLocation;
+ // update location
+ config.ConfigLocation = this.ConfigLocation;
- return c;
+ return config;
}
catch (Exception ex)
{
- Log.AsyncR("An error occured when updating a config: " + ex);
+ Log.AsyncR($"An error occured when updating a config: {ex}");
return this as T;
}
}
}
+ /// <summary>Provides extension methods for <see cref="Config"/> classes.</summary>
public static class ConfigExtensions
{
- /// <summary>
- /// Initializes an instance of any class that inherits from Config.
- /// This method performs the loading, saving, and merging of the config on the disk and in memory at a default state.
- /// This method should not be used to re-load or to re-save a config.
- /// NOTE: You MUST set your config EQUAL to the return of this method!
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="baseConfig"></param>
- /// <param name="configLocation"></param>
- /// <returns></returns>
+ /// <summary>Initialise the configuration. That includes loading, saving, and merging the config file and in memory at a default state. This method should not be used to reload or to resave a config. NOTE: You MUST set your config EQUAL to the return of this method!</summary>
+ /// <typeparam name="T">The config class type.</typeparam>
+ /// <param name="baseConfig">The base configuration to initialise.</param>
+ /// <param name="configLocation">The base configuration file path.</param>
public static T InitializeConfig<T>(this T baseConfig, string configLocation) where T : Config
{
if (baseConfig == null)
- {
baseConfig = Activator.CreateInstance<T>();
- /*
- Log.AsyncR("A config tried to initialize whilst being null.");
- return null;
- */
- }
if (string.IsNullOrEmpty(configLocation))
{
@@ -131,14 +115,12 @@ namespace StardewModdingAPI
}
baseConfig.ConfigLocation = configLocation;
- var c = baseConfig.LoadConfig<T>();
-
- return c;
+ return baseConfig.LoadConfig<T>();
}
- /// <summary>
- /// Writes a config to a json blob on the disk specified in the config's properties.
- /// </summary>
+ /// <summary>Writes the configuration to the JSON file.</summary>
+ /// <typeparam name="T">The config class type.</typeparam>
+ /// <param name="baseConfig">The base configuration to initialise.</param>
public static void WriteConfig<T>(this T baseConfig) where T : Config
{
if (string.IsNullOrEmpty(baseConfig?.ConfigLocation) || string.IsNullOrEmpty(baseConfig.ConfigDir))
@@ -147,22 +129,20 @@ namespace StardewModdingAPI
return;
}
- var s = JsonConvert.SerializeObject(baseConfig, Formatting.Indented);
-
+ string json = JsonConvert.SerializeObject(baseConfig, Formatting.Indented);
if (!Directory.Exists(baseConfig.ConfigDir))
Directory.CreateDirectory(baseConfig.ConfigDir);
- if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllText(baseConfig.ConfigLocation).SequenceEqual(s))
- File.WriteAllText(baseConfig.ConfigLocation, s);
+ if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllText(baseConfig.ConfigLocation).SequenceEqual(json))
+ File.WriteAllText(baseConfig.ConfigLocation, json);
}
- /// <summary>
- /// Re-reads the json blob on the disk and merges its values with a default config.
- /// NOTE: You MUST set your config EQUAL to the return of this method!
- /// </summary>
+ /// <summary>Rereads the JSON file and merges its values with a default config. NOTE: You MUST set your config EQUAL to the return of this method!</summary>
+ /// <typeparam name="T">The config class type.</typeparam>
+ /// <param name="baseConfig">The base configuration to initialise.</param>
public static T ReloadConfig<T>(this T baseConfig) where T : Config
{
return baseConfig.LoadConfig<T>();
}
}
-} \ No newline at end of file
+}