diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-10-31 20:46:23 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-10-31 20:46:23 -0400 |
commit | 605c99ba7074c3dbfeb441f608d77a2bc50e4629 (patch) | |
tree | 9ea5c18872201e280075008abbe375a2b87f6a2d /src | |
parent | 9d461bb05bfa25c20cba46651f2ecf86028f1a1a (diff) | |
download | SMAPI-605c99ba7074c3dbfeb441f608d77a2bc50e4629.tar.gz SMAPI-605c99ba7074c3dbfeb441f608d77a2bc50e4629.tar.bz2 SMAPI-605c99ba7074c3dbfeb441f608d77a2bc50e4629.zip |
format & document config code
Diffstat (limited to 'src')
-rw-r--r-- | src/StardewModdingAPI.sln.DotSettings | 3 | ||||
-rw-r--r-- | src/StardewModdingAPI/Config.cs | 134 | ||||
-rw-r--r-- | src/StardewModdingAPI/Manifest.cs | 63 | ||||
-rw-r--r-- | src/StardewModdingAPI/Program.cs | 30 |
4 files changed, 106 insertions, 124 deletions
diff --git a/src/StardewModdingAPI.sln.DotSettings b/src/StardewModdingAPI.sln.DotSettings index 734205d2..716a8ded 100644 --- a/src/StardewModdingAPI.sln.DotSettings +++ b/src/StardewModdingAPI.sln.DotSettings @@ -4,4 +4,5 @@ <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseVarWhenEvident</s:String> - <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String></wpf:ResourceDictionary>
\ No newline at end of file + <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String> + <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String></wpf:ResourceDictionary>
\ No newline at end of file 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 +} diff --git a/src/StardewModdingAPI/Manifest.cs b/src/StardewModdingAPI/Manifest.cs index 5eabc01b..ed43ab7d 100644 --- a/src/StardewModdingAPI/Manifest.cs +++ b/src/StardewModdingAPI/Manifest.cs @@ -6,74 +6,71 @@ using Newtonsoft.Json.Linq; namespace StardewModdingAPI { + /// <summary>A manifest which describes a mod for SMAPI.</summary> public class Manifest : Config { - /// <summary> - /// The name of your mod. - /// </summary> + /********* + ** Accessors + *********/ + /// <summary>The mod name.</summary> public virtual string Name { get; set; } - /// <summary> - /// The name of the mod's authour. - /// </summary> + /// <summary>The mod author's name.</summary> public virtual string Authour { get; set; } - /// <summary> - /// The version of the mod. - /// </summary> + /// <summary>The mod version.</summary> public virtual Version Version { get; set; } - /// <summary> - /// A description of the mod. - /// </summary> + /// <summary>A brief description of the mod.</summary> public virtual string Description { get; set; } - /// <summary> - /// The unique ID of the mod. It doesn't *need* to be anything. - /// </summary> + /// <summary>The unique mod ID.</summary> public virtual string UniqueID { get; set; } - /// <summary> - /// Whether or not the mod uses per-save-config files. - /// </summary> + /// <summary>Whether the mod uses per-save config files.</summary> public virtual bool PerSaveConfigs { get; set; } - /// <summary> - /// The name of the DLL in the directory that has the Entry() method. - /// </summary> + /// <summary>The name of the DLL in the directory that has the <see cref="Mod.Entry"/> method.</summary> public virtual string EntryDll { get; set; } + + /********* + ** Public methods + *********/ + /// <summary>Get the default config values.</summary> public override T GenerateDefaultConfig<T>() { - Name = ""; - Authour = ""; - Version = new Version(0, 0, 0, ""); - Description = ""; - UniqueID = Guid.NewGuid().ToString(); - PerSaveConfigs = false; - EntryDll = ""; + this.Name = ""; + this.Authour = ""; + this.Version = new Version(0, 0, 0, ""); + this.Description = ""; + this.UniqueID = Guid.NewGuid().ToString(); + this.PerSaveConfigs = false; + this.EntryDll = ""; return this as T; } + /// <summary>Load the config from the JSON file, saving it to disk if needed.</summary> + /// <typeparam name="T">The config class type.</typeparam> public override T LoadConfig<T>() { - if (File.Exists(ConfigLocation)) + if (File.Exists(this.ConfigLocation)) { try { - Manifest m = JsonConvert.DeserializeObject<Manifest>(File.ReadAllText(ConfigLocation)); + Manifest m = JsonConvert.DeserializeObject<Manifest>(File.ReadAllText(this.ConfigLocation)); } catch { //Invalid json blob. Try to remove version? try { - JObject j = JObject.Parse(File.ReadAllText(ConfigLocation)); + JObject j = JObject.Parse(File.ReadAllText(this.ConfigLocation)); if (!j.GetValue("Version").Contains("{")) { Log.AsyncC("INVALID JSON VERSION. TRYING TO REMOVE SO A NEW CAN BE AUTO-GENERATED"); j.Remove("Version"); - File.WriteAllText(ConfigLocation, j.ToString()); + File.WriteAllText(this.ConfigLocation, j.ToString()); } } catch (Exception) @@ -86,4 +83,4 @@ namespace StardewModdingAPI return base.LoadConfig<T>(); } } -}
\ No newline at end of file +} diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 0099b045..b08d17c2 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -38,7 +38,7 @@ namespace StardewModdingAPI public static Texture2D DebugPixel { get; private set; }
// ReSharper disable once PossibleNullReferenceException
- public static int BuildType => (int) StardewProgramType.GetField("buildType", BindingFlags.Public | BindingFlags.Static).GetValue(null);
+ public static int BuildType => (int)StardewProgramType.GetField("buildType", BindingFlags.Public | BindingFlags.Static).GetValue(null);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -215,35 +215,39 @@ namespace StardewModdingAPI Log.AsyncY("LOADING MODS");
foreach (string directory in Directory.GetDirectories(ModPath))
{
- foreach (string manifestFile in Directory.GetFiles(directory, "manifest.json"))
+ foreach (string manifestPath in Directory.GetFiles(directory, "manifest.json"))
{
- if (manifestFile.Contains("StardewInjector"))
+ if (manifestPath.Contains("StardewInjector"))
continue;
- Log.AsyncG("Found Manifest: " + manifestFile);
- var manifest = new Manifest();
+
+ // read manifest
+ Log.AsyncG($"Found Manifest: {manifestPath}");
+ Manifest manifest = new Manifest();
try
{
- string t = File.ReadAllText(manifestFile);
- if (string.IsNullOrEmpty(t))
+ // read manifest text
+ string json = File.ReadAllText(manifestPath);
+ if (string.IsNullOrEmpty(json))
{
- Log.AsyncR($"Failed to read mod manifest '{manifestFile}'. Manifest is empty!");
+ Log.AsyncR($"Failed to read mod manifest '{manifestPath}'. Manifest is empty!");
continue;
}
- manifest = manifest.InitializeConfig(manifestFile);
-
+ // deserialise manifest
+ manifest = manifest.InitializeConfig(manifestPath);
if (string.IsNullOrEmpty(manifest.EntryDll))
{
- Log.AsyncR($"Failed to read mod manifest '{manifestFile}'. EntryDll is empty!");
+ Log.AsyncR($"Failed to read mod manifest '{manifestPath}'. EntryDll is empty!");
continue;
}
}
catch (Exception ex)
{
- Log.AsyncR($"Failed to read mod manifest '{manifestFile}'. Exception details:\n" + ex);
+ Log.AsyncR($"Failed to read mod manifest '{manifestPath}'. Exception details:\n" + ex);
continue;
}
- string targDir = Path.GetDirectoryName(manifestFile);
+
+ string targDir = Path.GetDirectoryName(manifestPath);
string psDir = Path.Combine(targDir, "psconfigs");
Log.AsyncY($"Created psconfigs directory @{psDir}");
try
|