diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-11-05 01:46:52 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-11-05 01:46:52 -0400 |
commit | e092417b9e9093106609a33aba8863c5ec2c5ddd (patch) | |
tree | c97e3cef4b7081ddacb4f47925d6e47702a75b8c | |
parent | 067d5f6b693c9e30ff5f4f2b1cd363b036a7b3cc (diff) | |
download | SMAPI-e092417b9e9093106609a33aba8863c5ec2c5ddd.tar.gz SMAPI-e092417b9e9093106609a33aba8863c5ec2c5ddd.tar.bz2 SMAPI-e092417b9e9093106609a33aba8863c5ec2c5ddd.zip |
add new config system, mark previous methods obsolete (#159)
-rw-r--r-- | src/StardewModdingAPI/Advanced/ConfigFile.cs | 35 | ||||
-rw-r--r-- | src/StardewModdingAPI/Advanced/IConfigFile.cs | 25 | ||||
-rw-r--r-- | src/StardewModdingAPI/Config.cs | 9 | ||||
-rw-r--r-- | src/StardewModdingAPI/Mod.cs | 15 | ||||
-rw-r--r-- | src/StardewModdingAPI/ModHelper.cs | 98 | ||||
-rw-r--r-- | src/StardewModdingAPI/Program.cs | 4 | ||||
-rw-r--r-- | src/StardewModdingAPI/StardewModdingAPI.csproj | 3 |
7 files changed, 184 insertions, 5 deletions
diff --git a/src/StardewModdingAPI/Advanced/ConfigFile.cs b/src/StardewModdingAPI/Advanced/ConfigFile.cs new file mode 100644 index 00000000..000eaf4c --- /dev/null +++ b/src/StardewModdingAPI/Advanced/ConfigFile.cs @@ -0,0 +1,35 @@ +using System.IO; +using Newtonsoft.Json; + +namespace StardewModdingAPI.Advanced +{ + /// <summary>Wraps a configuration file with IO methods for convenience.</summary> + public abstract class ConfigFile : IConfigFile + { + /********* + ** Accessors + *********/ + /// <summary>Provides methods for interacting with the mod directory, including read/writing the config file.</summary> + public ModHelper ModHelper { get; set; } + + /// <summary>The file path from which the model was loaded, relative to the mod directory.</summary> + public string FilePath { get; set; } + + + /********* + ** Public methods + *********/ + /// <summary>Reparse the underlying file and update this model.</summary> + public void Reload() + { + string json = File.ReadAllText(Path.Combine(this.ModHelper.DirectoryPath, this.FilePath)); + JsonConvert.PopulateObject(json, this); + } + + /// <summary>Save this model to the underlying file.</summary> + public void Save() + { + this.ModHelper.WriteJsonFile(this.FilePath, this); + } + } +}
\ No newline at end of file diff --git a/src/StardewModdingAPI/Advanced/IConfigFile.cs b/src/StardewModdingAPI/Advanced/IConfigFile.cs new file mode 100644 index 00000000..78fd44a6 --- /dev/null +++ b/src/StardewModdingAPI/Advanced/IConfigFile.cs @@ -0,0 +1,25 @@ +namespace StardewModdingAPI.Advanced +{ + /// <summary>Wraps a configuration file with IO methods for convenience.</summary> + public interface IConfigFile + { + /********* + ** Accessors + *********/ + /// <summary>Provides methods for interacting with the mod directory, including read/writing the config file.</summary> + ModHelper ModHelper { get; set; } + + /// <summary>The file path from which the model was loaded, relative to the mod directory.</summary> + string FilePath { get; set; } + + + /********* + ** Methods + *********/ + /// <summary>Reparse the underlying file and update this model.</summary> + void Reload(); + + /// <summary>Save this model to the underlying file.</summary> + void Save(); + } +} diff --git a/src/StardewModdingAPI/Config.cs b/src/StardewModdingAPI/Config.cs index ff8ade90..d811d69d 100644 --- a/src/StardewModdingAPI/Config.cs +++ b/src/StardewModdingAPI/Config.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json.Linq; namespace StardewModdingAPI { /// <summary>A dynamic configuration class for a mod.</summary> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public abstract class Config { /********* @@ -26,10 +27,12 @@ namespace StardewModdingAPI *********/ /// <summary>Construct an instance of the config class.</summary> /// <typeparam name="T">The config class type.</typeparam> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public virtual Config Instance<T>() where T : Config => Activator.CreateInstance<T>(); /// <summary>Load the config from the JSON file, saving it to disk if needed.</summary> /// <typeparam name="T">The config class type.</typeparam> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public virtual T LoadConfig<T>() where T : Config { // validate @@ -67,10 +70,12 @@ namespace StardewModdingAPI } /// <summary>Get the default config values.</summary> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public abstract T GenerateDefaultConfig<T>() where T : Config; /// <summary>Get the current configuration with missing values defaulted.</summary> /// <typeparam name="T">The config class type.</typeparam> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public virtual T UpdateConfig<T>() where T : Config { try @@ -97,12 +102,14 @@ namespace StardewModdingAPI } /// <summary>Provides extension methods for <see cref="Config"/> classes.</summary> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public static class ConfigExtensions { /// <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> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public static T InitializeConfig<T>(this T baseConfig, string configLocation) where T : Config { if (baseConfig == null) @@ -121,6 +128,7 @@ namespace StardewModdingAPI /// <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> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public static void WriteConfig<T>(this T baseConfig) where T : Config { if (string.IsNullOrEmpty(baseConfig?.ConfigLocation) || string.IsNullOrEmpty(baseConfig.ConfigDir)) @@ -140,6 +148,7 @@ namespace StardewModdingAPI /// <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> + [Obsolete("This base class is obsolete since SMAPI 1.0. See the latest project README for details.")] public static T ReloadConfig<T>(this T baseConfig) where T : Config { return baseConfig.LoadConfig<T>(); diff --git a/src/StardewModdingAPI/Mod.cs b/src/StardewModdingAPI/Mod.cs index e8824fc6..c1cc99d4 100644 --- a/src/StardewModdingAPI/Mod.cs +++ b/src/StardewModdingAPI/Mod.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; namespace StardewModdingAPI { @@ -8,6 +9,9 @@ namespace StardewModdingAPI /********* ** Accessors *********/ + /// <summary>Provides methods for interacting with the mod directory, such as read/writing a config file or custom JSON files.</summary> + public ModHelper Helper { get; internal set; } + /// <summary>The mod's manifest.</summary> public Manifest Manifest { get; internal set; } @@ -28,9 +32,12 @@ namespace StardewModdingAPI ** Public methods *********/ /// <summary>The entry point for your mod. It will always be called once when the mod loads.</summary> - public virtual void Entry(params object[] objects) - { - } + [Obsolete("This overload is obsolete since SMAPI 1.0.")] + public virtual void Entry(params object[] objects) { } + + /// <summary>The entry point for your mod. It will always be called once when the mod loads.</summary> + /// <param name="helper">Provides methods for interacting with the mod directory, such as read/writing a config file or custom JSON files.</param> + public virtual void Entry(ModHelper helper) { } /********* diff --git a/src/StardewModdingAPI/ModHelper.cs b/src/StardewModdingAPI/ModHelper.cs new file mode 100644 index 00000000..bb753170 --- /dev/null +++ b/src/StardewModdingAPI/ModHelper.cs @@ -0,0 +1,98 @@ +using System; +using System.IO; +using Newtonsoft.Json; +using StardewModdingAPI.Advanced; + +namespace StardewModdingAPI +{ + /// <summary>Provides methods for interacting with a mod directory.</summary> + public class ModHelper + { + /********* + ** Accessors + *********/ + /// <summary>The mod directory path.</summary> + public string DirectoryPath { get; } + + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + /// <param name="modDirectory">The mod directory path.</param> + public ModHelper(string modDirectory) + { + // validate + if (string.IsNullOrWhiteSpace(modDirectory)) + throw new InvalidOperationException("The mod directory cannot be empty."); + if (!Directory.Exists(modDirectory)) + throw new InvalidOperationException("The specified mod directory does not exist."); + + // initialise + this.DirectoryPath = modDirectory; + } + + /**** + ** Mod config file + ****/ + /// <summary>Read the mod's configuration file (and create it if needed).</summary> + /// <typeparam name="TConfig">The config class type. This should be a plain class that has public properties for the settings you want. These can be complex types.</typeparam> + public TConfig ReadConfig<TConfig>() + where TConfig : class, new() + { + var config = this.ReadJsonFile<TConfig>("config.json") ?? new TConfig(); + this.WriteConfig(config); // create file or fill in missing fields + return config; + } + + /// <summary>Save to the mod's configuration file.</summary> + /// <typeparam name="TConfig">The config class type.</typeparam> + /// <param name="config">The config settings to save.</param> + public void WriteConfig<TConfig>(TConfig config) + where TConfig : class, new() + { + this.WriteJsonFile("config.json", config); + } + + /**** + ** Generic JSON files + ****/ + /// <summary>Read a JSON file.</summary> + /// <typeparam name="TModel">The model type.</typeparam> + /// <param name="path">The file path relative to the mod directory.</param> + public TModel ReadJsonFile<TModel>(string path) + where TModel : class + { + string fullPath = Path.Combine(this.DirectoryPath, path); + TModel model = JsonConvert.DeserializeObject<TModel>(File.ReadAllText(fullPath)); + + if (model is IConfigFile) + { + var wrapper = (IConfigFile)model; + wrapper.ModHelper = this; + wrapper.FilePath = path; + } + + return model; + } + + /// <summary>Save to a JSON file.</summary> + /// <typeparam name="TModel">The model type.</typeparam> + /// <param name="path">The file path relative to the mod directory.</param> + /// <param name="model">The model to save.</param> + public void WriteJsonFile<TModel>(string path, TModel model) + where TModel : class + { + path = Path.Combine(this.DirectoryPath, path); + + // create directory if needed + string dir = Path.GetDirectoryName(path); + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + + // write file + string json = JsonConvert.SerializeObject(model, Formatting.Indented); + File.WriteAllText(path, json); + } + } +} diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 8c38a88b..032f1192 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -314,11 +314,13 @@ namespace StardewModdingAPI Mod modEntry = (Mod)modAssembly.CreateInstance(tar.ToString()); if (modEntry != null) { + modEntry.Helper = new ModHelper(targDir); modEntry.PathOnDisk = targDir; modEntry.Manifest = manifest; Log.Info($"Loaded mod: {modEntry.Manifest.Name} by {modEntry.Manifest.Author}, v{modEntry.Manifest.Version} | {modEntry.Manifest.Description}\n@ {targDll}"); Program.ModsLoaded += 1; - modEntry.Entry(); + modEntry.Entry(); // obsolete + modEntry.Entry(modEntry.Helper); } } else diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj index 9e89c9e6..451e5961 100644 --- a/src/StardewModdingAPI/StardewModdingAPI.csproj +++ b/src/StardewModdingAPI/StardewModdingAPI.csproj @@ -161,6 +161,8 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="Advanced\ConfigFile.cs" /> + <Compile Include="Advanced\IConfigFile.cs" /> <Compile Include="Command.cs" /> <Compile Include="Config.cs" /> <Compile Include="Constants.cs" /> @@ -202,6 +204,7 @@ <Compile Include="Framework\LogWriter.cs" /> <Compile Include="Manifest.cs" /> <Compile Include="Mod.cs" /> + <Compile Include="ModHelper.cs" /> <Compile Include="Program.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Inheritance\SGame.cs" /> |