add new config system, mark previous methods obsolete (#159)

This commit is contained in:
Jesse Plamondon-Willard 2016-11-05 01:46:52 -04:00
parent 067d5f6b69
commit e092417b9e
7 changed files with 184 additions and 5 deletions

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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>();

View File

@ -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) { }
/*********

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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" />