Improve automatic service detection.

This commit is contained in:
Ottermandias 2023-12-30 14:37:31 +01:00
parent b5c69b2946
commit 81cdcad72e
13 changed files with 86 additions and 128 deletions

@ -1 +1 @@
Subproject commit 197d23eee167c232000f22ef40a7a2bded913b6c
Subproject commit f6a8ad0f8e585408e0aa17c90209358403b52535

@ -1 +1 @@
Subproject commit ed37f83424c11a5a601e74f4660cd52ebd68a7b3
Subproject commit 192fd1e6ad269c3cbdb81aa8c43a8bc20c5ae7f0

View file

@ -1,15 +1,24 @@
using Newtonsoft.Json.Linq;
using OtterGui.Classes;
using OtterGui.Log;
using OtterGui.Services;
namespace Penumbra.Services;
public class BackupService
public class BackupService : IAsyncService
{
/// <inheritdoc/>
public Task Awaiter { get; }
/// <inheritdoc/>
public bool Finished
=> Awaiter.IsCompletedSuccessfully;
/// <summary> Start a backup process on the collected files. </summary>
public BackupService(Logger logger, FilenameService fileNames)
{
var files = PenumbraFiles(fileNames);
Backup.CreateAutomaticBackup(logger, new DirectoryInfo(fileNames.ConfigDirectory), files);
Awaiter = Task.Run(() => Backup.CreateAutomaticBackup(logger, new DirectoryInfo(fileNames.ConfigDirectory), files));
}
/// <summary> Collect all relevant files for penumbra configuration. </summary>

View file

@ -1,10 +1,11 @@
using OtterGui.Classes;
using OtterGui.Log;
using OtterGui.Services;
using Penumbra.Communication;
namespace Penumbra.Services;
public class CommunicatorService : IDisposable
public class CommunicatorService : IDisposable, IService
{
public CommunicatorService(Logger logger)
{

View file

@ -1,7 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui.Classes;
using OtterGui.Filesystem;
using OtterGui.Services;
using Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.Collections.Manager;
@ -22,10 +22,8 @@ namespace Penumbra.Services;
/// Contains everything to migrate from older versions of the config to the current,
/// including deprecated fields.
/// </summary>
public class ConfigMigrationService
public class ConfigMigrationService(SaveService saveService) : IService
{
private readonly SaveService _saveService;
private Configuration _config = null!;
private JObject _data = null!;
@ -33,14 +31,11 @@ public class ConfigMigrationService
public string DefaultCollection = ModCollection.DefaultCollectionName;
public string ForcedCollection = string.Empty;
public Dictionary<string, string> CharacterCollections = [];
public Dictionary<string, string> ModSortOrder = new();
public Dictionary<string, string> ModSortOrder = [];
public bool InvertModListOrder;
public bool SortFoldersFirst;
public SortModeV3 SortMode = SortModeV3.FoldersFirst;
public ConfigMigrationService(SaveService saveService)
=> _saveService = saveService;
/// <summary> Add missing colors to the dictionary if necessary. </summary>
private static void AddColors(Configuration config, bool forceSave)
{
@ -61,13 +56,13 @@ public class ConfigMigrationService
// because it stayed alive for a bunch of people for some reason.
DeleteMetaTmp();
if (config.Version >= Configuration.Constants.CurrentVersion || !File.Exists(_saveService.FileNames.ConfigFile))
if (config.Version >= Configuration.Constants.CurrentVersion || !File.Exists(saveService.FileNames.ConfigFile))
{
AddColors(config, false);
return;
}
_data = JObject.Parse(File.ReadAllText(_saveService.FileNames.ConfigFile));
_data = JObject.Parse(File.ReadAllText(saveService.FileNames.ConfigFile));
CreateBackup();
Version0To1();
@ -118,7 +113,7 @@ public class ConfigMigrationService
if (_config.Version != 6)
return;
ActiveCollectionMigration.MigrateUngenderedCollections(_saveService.FileNames);
ActiveCollectionMigration.MigrateUngenderedCollections(saveService.FileNames);
_config.Version = 7;
}
@ -223,7 +218,7 @@ public class ConfigMigrationService
return;
// Add the previous forced collection to all current collections except itself as an inheritance.
foreach (var collection in _saveService.FileNames.CollectionFiles)
foreach (var collection in saveService.FileNames.CollectionFiles)
{
try
{
@ -246,7 +241,7 @@ public class ConfigMigrationService
private void ResettleSortOrder()
{
ModSortOrder = _data[nameof(ModSortOrder)]?.ToObject<Dictionary<string, string>>() ?? ModSortOrder;
var file = _saveService.FileNames.FilesystemFile;
var file = saveService.FileNames.FilesystemFile;
using var stream = File.Open(file, File.Exists(file) ? FileMode.Truncate : FileMode.CreateNew);
using var writer = new StreamWriter(stream);
using var j = new JsonTextWriter(writer);
@ -281,7 +276,7 @@ public class ConfigMigrationService
private void SaveActiveCollectionsV0(string def, string ui, string current, IEnumerable<(string, string)> characters,
IEnumerable<(CollectionType, string)> special)
{
var file = _saveService.FileNames.ActiveCollectionsFile;
var file = saveService.FileNames.ActiveCollectionsFile;
try
{
using var stream = File.Open(file, File.Exists(file) ? FileMode.Truncate : FileMode.CreateNew);
@ -337,7 +332,7 @@ public class ConfigMigrationService
if (!collectionJson.Exists)
return;
var defaultCollectionFile = new FileInfo(_saveService.FileNames.CollectionFile(ModCollection.DefaultCollectionName));
var defaultCollectionFile = new FileInfo(saveService.FileNames.CollectionFile(ModCollection.DefaultCollectionName));
if (defaultCollectionFile.Exists)
return;
@ -370,9 +365,9 @@ public class ConfigMigrationService
dict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value with { Priority = maxPriority - kvp.Value.Priority });
var emptyStorage = new ModStorage();
var collection = ModCollection.CreateFromData(_saveService, emptyStorage, ModCollection.DefaultCollectionName, 0, 1, dict,
var collection = ModCollection.CreateFromData(saveService, emptyStorage, ModCollection.DefaultCollectionName, 0, 1, dict,
Array.Empty<string>());
_saveService.ImmediateSaveSync(new ModCollectionSave(emptyStorage, collection));
saveService.ImmediateSaveSync(new ModCollectionSave(emptyStorage, collection));
}
catch (Exception e)
{
@ -384,7 +379,7 @@ public class ConfigMigrationService
// Create a backup of the configuration file specifically.
private void CreateBackup()
{
var name = _saveService.FileNames.ConfigFile;
var name = saveService.FileNames.ConfigFile;
var bakName = name + ".bak";
try
{

View file

@ -1,21 +1,12 @@
using Dalamud.Game;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Interface;
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Interface.DragDrop;
using Dalamud.Plugin.Services;
using OtterGui.Services;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
namespace Penumbra.Services;
public class DalamudConfigService
public class DalamudConfigService : IService
{
public DalamudConfigService(DalamudPluginInterface pluginInterface)
public DalamudConfigService()
{
pluginInterface.Inject(this);
try
{
var serviceType =
@ -115,29 +106,3 @@ public class DalamudConfigService
}
}
}
public static class DalamudServices
{
public static void AddServices(ServiceManager services, DalamudPluginInterface pi)
{
services.AddExistingService(pi);
services.AddExistingService(pi.UiBuilder);
services.AddDalamudService<ICommandManager>(pi);
services.AddDalamudService<IDataManager>(pi);
services.AddDalamudService<IClientState>(pi);
services.AddDalamudService<IChatGui>(pi);
services.AddDalamudService<IFramework>(pi);
services.AddDalamudService<ICondition>(pi);
services.AddDalamudService<ITargetManager>(pi);
services.AddDalamudService<IObjectTable>(pi);
services.AddDalamudService<ITitleScreenMenu>(pi);
services.AddDalamudService<IGameGui>(pi);
services.AddDalamudService<IKeyState>(pi);
services.AddDalamudService<ISigScanner>(pi);
services.AddDalamudService<IDragDropManager>(pi);
services.AddDalamudService<ITextureProvider>(pi);
services.AddDalamudService<ITextureSubstitutionProvider>(pi);
services.AddDalamudService<IGameInteropProvider>(pi);
services.AddDalamudService<IPluginLog>(pi);
}
}

View file

@ -1,11 +1,11 @@
using Dalamud.Plugin;
using OtterGui.Filesystem;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.Mods;
namespace Penumbra.Services;
public class FilenameService(DalamudPluginInterface pi)
public class FilenameService(DalamudPluginInterface pi) : IService
{
public readonly string ConfigDirectory = pi.ConfigDirectory.FullName;
public readonly string CollectionDirectory = Path.Combine(pi.ConfigDirectory.FullName, "collections");

View file

@ -5,15 +5,12 @@ using Dalamud.Interface;
using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets;
using OtterGui.Log;
using OtterGui.Services;
namespace Penumbra.Services;
public class MessageService : OtterGui.Classes.MessageService
public class MessageService(Logger log, UiBuilder uiBuilder, IChatGui chat) : OtterGui.Classes.MessageService(log, uiBuilder, chat), IService
{
public MessageService(Logger log, UiBuilder uiBuilder, IChatGui chat)
: base(log, uiBuilder, chat)
{ }
public void LinkItem(Item item)
{
// @formatter:off

View file

@ -1,5 +1,6 @@
using OtterGui.Classes;
using OtterGui.Log;
using OtterGui.Services;
using Penumbra.Mods;
using Penumbra.Mods.Subclasses;
@ -11,12 +12,9 @@ namespace Penumbra.Services;
public interface ISavable : ISavable<FilenameService>
{ }
public sealed class SaveService : SaveServiceBase<FilenameService>
public sealed class SaveService(Logger log, FrameworkManager framework, FilenameService fileNames, BackupService backupService)
: SaveServiceBase<FilenameService>(log, framework, fileNames, backupService.Awaiter), IService
{
public SaveService(Logger log, FrameworkManager framework, FilenameService fileNames)
: base(log, framework, fileNames)
{ }
/// <summary> Immediately delete all existing option group files for a mod and save them anew. </summary>
public void SaveAllOptionGroups(Mod mod, bool backup, bool onlyAscii)
{

View file

@ -1,5 +1,10 @@
using Dalamud.Game;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Interface.DragDrop;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Compression;
using OtterGui.Log;
@ -8,7 +13,6 @@ using Penumbra.Api;
using Penumbra.Collections.Cache;
using Penumbra.Collections.Manager;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Data;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Structs;
using Penumbra.Import.Textures;
@ -37,10 +41,9 @@ public static class ServiceManagerA
public static ServiceManager CreateProvider(Penumbra penumbra, DalamudPluginInterface pi, Logger log)
{
var services = new ServiceManager(log)
.AddDalamudServices(pi)
.AddExistingService(log)
.AddExistingService(penumbra)
.AddMeta()
.AddGameData()
.AddInterop()
.AddConfiguration()
.AddCollections()
@ -52,27 +55,31 @@ public static class ServiceManagerA
.AddApi();
services.AddIServices(typeof(EquipItem).Assembly);
services.AddIServices(typeof(Penumbra).Assembly);
DalamudServices.AddServices(services, pi);
services.AddIServices(typeof(ImGuiUtil).Assembly);
services.CreateProvider();
return services;
}
private static ServiceManager AddMeta(this ServiceManager services)
=> services.AddSingleton<ValidityChecker>()
.AddSingleton<PerformanceTracker>()
.AddSingleton<FilenameService>()
.AddSingleton<BackupService>()
.AddSingleton<CommunicatorService>()
.AddSingleton<MessageService>()
.AddSingleton<SaveService>()
.AddSingleton<FileCompactor>()
.AddSingleton<DalamudConfigService>();
private static ServiceManager AddGameData(this ServiceManager services)
=> services.AddSingleton<GamePathParser>()
.AddSingleton<StainService>()
.AddSingleton<HumanModelList>();
private static ServiceManager AddDalamudServices(this ServiceManager services, DalamudPluginInterface pi)
=> services.AddExistingService(pi)
.AddExistingService(pi.UiBuilder)
.AddDalamudService<ICommandManager>(pi)
.AddDalamudService<IDataManager>(pi)
.AddDalamudService<IClientState>(pi)
.AddDalamudService<IChatGui>(pi)
.AddDalamudService<IFramework>(pi)
.AddDalamudService<ICondition>(pi)
.AddDalamudService<ITargetManager>(pi)
.AddDalamudService<IObjectTable>(pi)
.AddDalamudService<ITitleScreenMenu>(pi)
.AddDalamudService<IGameGui>(pi)
.AddDalamudService<IKeyState>(pi)
.AddDalamudService<ISigScanner>(pi)
.AddDalamudService<IDragDropManager>(pi)
.AddDalamudService<ITextureProvider>(pi)
.AddDalamudService<ITextureSubstitutionProvider>(pi)
.AddDalamudService<IGameInteropProvider>(pi)
.AddDalamudService<IPluginLog>(pi);
private static ServiceManager AddInterop(this ServiceManager services)
=> services.AddSingleton<GameEventManager>()
@ -95,8 +102,7 @@ public static class ServiceManagerA
.AddSingleton<ModelResourceHandleUtility>();
private static ServiceManager AddConfiguration(this ServiceManager services)
=> services.AddSingleton<ConfigMigrationService>()
.AddSingleton<Configuration>()
=> services.AddSingleton<Configuration>()
.AddSingleton<EphemeralConfig>();
private static ServiceManager AddCollections(this ServiceManager services)

View file

@ -1,36 +1,26 @@
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ImGuiNET;
using OtterGui.Log;
using OtterGui.Services;
using OtterGui.Widgets;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Files;
using Penumbra.UI.AdvancedWindow;
using Penumbra.Util;
namespace Penumbra.Services;
public class StainService : IDisposable
public class StainService : IService
{
public sealed class StainTemplateCombo : FilterComboCache<ushort>
public sealed class StainTemplateCombo(FilterComboColors stainCombo, StmFile stmFile)
: FilterComboCache<ushort>(stmFile.Entries.Keys.Prepend((ushort)0), Penumbra.Log)
{
private readonly StmFile _stmFile;
private readonly FilterComboColors _stainCombo;
public StainTemplateCombo(FilterComboColors stainCombo, StmFile stmFile)
: base(stmFile.Entries.Keys.Prepend((ushort)0), Penumbra.Log)
{
_stainCombo = stainCombo;
_stmFile = stmFile;
}
protected override float GetFilterWidth()
{
var baseSize = ImGui.CalcTextSize("0000").X + ImGui.GetStyle().ScrollbarSize + ImGui.GetStyle().ItemInnerSpacing.X;
if (_stainCombo.CurrentSelection.Key == 0)
if (stainCombo.CurrentSelection.Key == 0)
return baseSize;
return baseSize + ImGui.GetTextLineHeight() * 3 + ImGui.GetStyle().ItemInnerSpacing.X * 3;
}
@ -50,15 +40,15 @@ public class StainService : IDisposable
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(1, 0.5f))
.Push(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = ImGui.GetStyle().ItemInnerSpacing.X });
var spaceSize = ImGui.CalcTextSize(" ").X;
var spaces = (int) (previewWidth / spaceSize) - 1;
var spaces = (int)(previewWidth / spaceSize) - 1;
return base.Draw(label, preview.PadLeft(spaces), tooltip, ref currentSelection, previewWidth, itemHeight, flags);
}
protected override bool DrawSelectable(int globalIdx, bool selected)
{
var ret = base.DrawSelectable(globalIdx, selected);
var selection = _stainCombo.CurrentSelection.Key;
if (selection == 0 || !_stmFile.TryGetValue(Items[globalIdx], selection, out var colors))
var selection = stainCombo.CurrentSelection.Key;
if (selection == 0 || !stmFile.TryGetValue(Items[globalIdx], selection, out var colors))
return ret;
ImGui.SameLine();
@ -72,25 +62,18 @@ public class StainService : IDisposable
}
}
public readonly DictStains StainData;
public readonly DictStain StainData;
public readonly FilterComboColors StainCombo;
public readonly StmFile StmFile;
public readonly StainTemplateCombo TemplateCombo;
public StainService(DalamudPluginInterface pluginInterface, IDataManager dataManager, Logger logger)
public StainService(IDataManager dataManager, DictStain stainData)
{
StainData = new DictStains(pluginInterface, logger, dataManager);
StainData = stainData;
StainCombo = new FilterComboColors(140,
() => StainData.Value.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))).ToList(),
Penumbra.Log);
StmFile = new StmFile(dataManager);
TemplateCombo = new StainTemplateCombo(StainCombo, StmFile);
Penumbra.Log.Verbose($"[{nameof(StainService)}] Created.");
}
public void Dispose()
{
StainData.Dispose();
Penumbra.Log.Verbose($"[{nameof(StainService)}] Disposed.");
}
}

View file

@ -1,10 +1,11 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin;
using OtterGui.Classes;
using OtterGui.Services;
namespace Penumbra.Services;
public class ValidityChecker
public class ValidityChecker : IService
{
public const string Repository = "https://raw.githubusercontent.com/xivdev/Penumbra/master/repo.json";
public const string SeaOfStars = "https://raw.githubusercontent.com/Ottermandias/SeaOfStars/main/repo.json";

View file

@ -1,7 +1,10 @@
global using PerformanceTracker = OtterGui.Classes.PerformanceTracker<Penumbra.Util.PerformanceType>;
using Dalamud.Plugin.Services;
using OtterGui.Services;
namespace Penumbra.Util;
public sealed class PerformanceTracker(IFramework framework) : OtterGui.Classes.PerformanceTracker<PerformanceType>(framework), IService;
public enum PerformanceType
{
UiMainWindow,