split mod DB into a separate file

The mod metadata has grown over time, and there's no need to keep it in memory after mod loading. This lets us load the config earlier (since it has a smaller impact on memory usage which affects the game's audio code), and lets us discard the mod metadata when we're done with it.
This commit is contained in:
Jesse Plamondon-Willard 2018-04-13 22:41:34 -04:00
parent 5997857064
commit a3ade7a512
10 changed files with 1875 additions and 1853 deletions

View File

@ -87,6 +87,7 @@
<Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI'"> <Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI'">
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).config.json" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\$(TargetName).config.json" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).metadata.json" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)" />

View File

@ -31,6 +31,7 @@
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Runtime.Caching.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Runtime.Caching.dll" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackageInternalPath)\Mono" />
@ -44,6 +45,7 @@
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackageInternalPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(PackageInternalPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Windows" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackageInternalPath)\Mono" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackageInternalPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(PackageInternalPath)\Windows\Mods\%(RecursiveDir)" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(PackageInternalPath)\Windows\Mods\%(RecursiveDir)" />
</Target> </Target>

View File

@ -15,6 +15,7 @@
* For SMAPI developers: * For SMAPI developers:
* Added prerelease versions to the mod update-check API response where available (GitHub only). * Added prerelease versions to the mod update-check API response where available (GitHub only).
* Added support for beta releases on the home page. * Added support for beta releases on the home page.
* Split mod DB out of `StardewModdingAPI.config.json`, so we can load config earlier and reduce unnecessary memory usage later.
--> -->
## 2.5.5 ## 2.5.5

View File

@ -72,6 +72,9 @@ namespace StardewModdingAPI
/// <summary>The file path for the SMAPI configuration file.</summary> /// <summary>The file path for the SMAPI configuration file.</summary>
internal static string ApiConfigPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.config.json"); internal static string ApiConfigPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.config.json");
/// <summary>The file path for the SMAPI metadata file.</summary>
internal static string ApiMetadataPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.metadata.json");
/// <summary>The file path to the log where the latest output should be saved.</summary> /// <summary>The file path to the log where the latest output should be saved.</summary>
internal static string DefaultLogPath => Path.Combine(Constants.LogDir, "SMAPI-latest.txt"); internal static string DefaultLogPath => Path.Combine(Constants.LogDir, "SMAPI-latest.txt");

View File

@ -1,6 +1,3 @@
using System.Collections.Generic;
using StardewModdingAPI.Framework.ModData;
namespace StardewModdingAPI.Framework.Models namespace StardewModdingAPI.Framework.Models
{ {
/// <summary>The SMAPI configuration settings.</summary> /// <summary>The SMAPI configuration settings.</summary>
@ -23,8 +20,5 @@ namespace StardewModdingAPI.Framework.Models
/// <summary>Whether SMAPI should log more information about the game context.</summary> /// <summary>Whether SMAPI should log more information about the game context.</summary>
public bool VerboseLogging { get; set; } public bool VerboseLogging { get; set; }
/// <summary>Extra metadata about mods.</summary>
public IDictionary<string, ModDataRecord> ModData { get; set; }
} }
} }

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using StardewModdingAPI.Framework.ModData;
namespace StardewModdingAPI.Framework.Models
{
/// <summary>The SMAPI predefined metadata.</summary>
internal class SMetadata
{
/********
** Accessors
********/
/// <summary>Extra metadata about mods.</summary>
public IDictionary<string, ModDataRecord> ModData { get; set; }
}
}

View File

@ -54,16 +54,15 @@ namespace StardewModdingAPI
/// <summary>Simplifies access to private game code.</summary> /// <summary>Simplifies access to private game code.</summary>
private readonly Reflector Reflection = new Reflector(); private readonly Reflector Reflection = new Reflector();
/// <summary>The SMAPI configuration settings.</summary>
private readonly SConfig Settings;
/// <summary>The underlying game instance.</summary> /// <summary>The underlying game instance.</summary>
private SGame GameInstance; private SGame GameInstance;
/// <summary>The underlying content manager.</summary> /// <summary>The underlying content manager.</summary>
private ContentCore ContentCore => this.GameInstance.ContentCore; private ContentCore ContentCore => this.GameInstance.ContentCore;
/// <summary>The SMAPI configuration settings.</summary>
/// <remarks>This is initialised after the game starts.</remarks>
private SConfig Settings;
/// <summary>Tracks the installed mods.</summary> /// <summary>Tracks the installed mods.</summary>
/// <remarks>This is initialised after the game starts.</remarks> /// <remarks>This is initialised after the game starts.</remarks>
private readonly ModRegistry ModRegistry = new ModRegistry(); private readonly ModRegistry ModRegistry = new ModRegistry();
@ -133,8 +132,14 @@ namespace StardewModdingAPI
public Program(bool writeToConsole, string logPath) public Program(bool writeToConsole, string logPath)
{ {
// init basics // init basics
this.Settings = JsonConvert.DeserializeObject<SConfig>(File.ReadAllText(Constants.ApiConfigPath));
this.LogFile = new LogFileManager(logPath); this.LogFile = new LogFileManager(logPath);
this.Monitor = new Monitor("SMAPI", this.ConsoleManager, this.LogFile, this.CancellationTokenSource) { WriteToConsole = writeToConsole }; this.Monitor = new Monitor("SMAPI", this.ConsoleManager, this.LogFile, this.CancellationTokenSource)
{
WriteToConsole = writeToConsole,
ShowTraceInConsole = this.Settings.DeveloperMode,
ShowFullStampInConsole = this.Settings.DeveloperMode
};
this.EventManager = new EventManager(this.Monitor, this.ModRegistry); this.EventManager = new EventManager(this.Monitor, this.ModRegistry);
// hook up events // hook up events
@ -345,7 +350,6 @@ namespace StardewModdingAPI
private void InitialiseAfterGameStart() private void InitialiseAfterGameStart()
{ {
// load settings // load settings
this.Settings = JsonConvert.DeserializeObject<SConfig>(File.ReadAllText(Constants.ApiConfigPath));
this.GameInstance.VerboseLogging = this.Settings.VerboseLogging; this.GameInstance.VerboseLogging = this.Settings.VerboseLogging;
// load core components // load core components
@ -361,11 +365,7 @@ namespace StardewModdingAPI
// add headers // add headers
if (this.Settings.DeveloperMode) if (this.Settings.DeveloperMode)
{
this.Monitor.ShowTraceInConsole = true;
this.Monitor.ShowFullStampInConsole = true;
this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info); this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info);
}
if (!this.Settings.CheckForUpdates) if (!this.Settings.CheckForUpdates)
this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn); this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn);
if (!this.Monitor.WriteToConsole) if (!this.Monitor.WriteToConsole)
@ -377,7 +377,8 @@ namespace StardewModdingAPI
this.Monitor.Log("SMAPI found problems in your game's content files which are likely to cause errors or crashes. Consider uninstalling XNB mods or reinstalling the game.", LogLevel.Error); this.Monitor.Log("SMAPI found problems in your game's content files which are likely to cause errors or crashes. Consider uninstalling XNB mods or reinstalling the game.", LogLevel.Error);
// load mod data // load mod data
ModDatabase modDatabase = new ModDatabase(this.Settings.ModData, Constants.GetUpdateUrl); SMetadata metadata = JsonConvert.DeserializeObject<SMetadata>(File.ReadAllText(Constants.ApiMetadataPath));
ModDatabase modDatabase = new ModDatabase(metadata.ModData, Constants.GetUpdateUrl);
// load mods // load mods
{ {

File diff suppressed because it is too large Load Diff

View File

@ -100,6 +100,7 @@
<Compile Include="Framework\ModData\ModDataFieldKey.cs" /> <Compile Include="Framework\ModData\ModDataFieldKey.cs" />
<Compile Include="Framework\ModData\ParsedModDataRecord.cs" /> <Compile Include="Framework\ModData\ParsedModDataRecord.cs" />
<Compile Include="Framework\Models\ManifestContentPackFor.cs" /> <Compile Include="Framework\Models\ManifestContentPackFor.cs" />
<Compile Include="Framework\Models\SMetadata.cs" />
<Compile Include="Framework\ModLoading\Finders\EventFinder.cs" /> <Compile Include="Framework\ModLoading\Finders\EventFinder.cs" />
<Compile Include="Framework\ModLoading\Finders\FieldFinder.cs" /> <Compile Include="Framework\ModLoading\Finders\FieldFinder.cs" />
<Compile Include="Framework\ModLoading\Finders\MethodFinder.cs" /> <Compile Include="Framework\ModLoading\Finders\MethodFinder.cs" />
@ -262,6 +263,9 @@
<Content Include="StardewModdingAPI.config.json"> <Content Include="StardewModdingAPI.config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Include="StardewModdingAPI.metadata.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="icon.ico" /> <Content Include="icon.ico" />

File diff suppressed because it is too large Load Diff