A bit of work on new IPC

This commit is contained in:
RisaDev
2024-03-03 02:42:16 +03:00
parent 7f18030018
commit 57c91eb834
8 changed files with 152 additions and 4 deletions

View File

@@ -24,7 +24,7 @@ using CustomizePlus.GameData.Extensions;
namespace CustomizePlus.Api.Compatibility; namespace CustomizePlus.Api.Compatibility;
public class CustomizePlusIpc : IDisposable public class CustomizePlusLegacyIpc : IDisposable
{ {
private readonly IObjectTable _objectTable; private readonly IObjectTable _objectTable;
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
@@ -52,7 +52,7 @@ public class CustomizePlusIpc : IDisposable
internal ICallGateProvider<Character?, string?>? ProviderGetProfileFromCharacter; internal ICallGateProvider<Character?, string?>? ProviderGetProfileFromCharacter;
internal ICallGateProvider<(int, int)>? ProviderGetApiVersion; internal ICallGateProvider<(int, int)>? ProviderGetApiVersion;
public CustomizePlusIpc( public CustomizePlusLegacyIpc(
IObjectTable objectTable, IObjectTable objectTable,
DalamudPluginInterface pluginInterface, DalamudPluginInterface pluginInterface,
Logger logger, Logger logger,

View File

@@ -0,0 +1,61 @@
using Dalamud.Plugin.Ipc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Penumbra.Api.Ipc;
namespace CustomizePlus.Api;
//I'm not a big fan of having functions and variables/properties
//grouped up like that but it makes sense here
public partial class CustomizePlusIpc : IDisposable
{
/// <summary>
/// When there are breaking changes the first number is bumped up and second one is reset.
/// When there are non-breaking changes only second number is bumped up.
/// In general clients should not try to use IPC if they encounter unexpected Breaking version.
/// </summary>
private readonly (int Breaking, int Feature) _apiVersion = (4, 0);
private const string _providerGetApiVersionLabel = $"CustomizePlus.General.{nameof(GetApiVersion)}";
private ICallGateProvider<(int, int)>? _providerGetApiVersion;
private (int, int) GetApiVersion()
{
return _apiVersion;
}
/// <summary>
/// This indicates if Customize+ is in valid state and can accept IPC requests.
/// This only indicates that no fatal errors occured in Customize+.
/// This will still be true if, for example, user turns off Customize+ in its settings.
/// </summary>
private const string _providerIsValidLabel = $"CustomizePlus.General.{nameof(IsValid)}";
private ICallGateProvider<bool>? _providerIsValid;
private bool IsValid()
{
return !IPCFailed &&
!_hookingService.RenderHookFailed &&
!_hookingService.MovementHookFailed;
}
private void InitializeGeneralProviders()
{
_logger.Debug("Initializing General Customize+ IPC providers.");
_providerGetApiVersion = _pluginInterface.GetIpcProvider<(int, int)>(_providerGetApiVersionLabel);
_providerGetApiVersion.RegisterFunc(GetApiVersion);
_providerIsValid = _pluginInterface.GetIpcProvider<bool>(_providerIsValidLabel);
_providerIsValid.RegisterFunc(IsValid);
}
private void DisposeGeneralProviders()
{
_logger.Debug("Disposing General Customize+ IPC providers.");
_providerGetApiVersion?.UnregisterFunc();
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomizePlus.Api;
public partial class CustomizePlusIpc : IDisposable
{
}

View File

@@ -0,0 +1,56 @@
using CustomizePlus.Core.Services;
using Dalamud.Plugin;
using OtterGui.Log;
using System;
namespace CustomizePlus.Api;
public partial class CustomizePlusIpc : IDisposable
{
private readonly DalamudPluginInterface _pluginInterface;
private readonly Logger _logger;
private readonly HookingService _hookingService;
/// <summary>
/// Shows if IPC failed to initialize or any other unrecoverable fatal error occured.
/// </summary>
public bool IPCFailed { get; private set; }
public CustomizePlusIpc(
DalamudPluginInterface pluginInterface,
Logger logger,
HookingService hookingService)
{
_pluginInterface = pluginInterface;
_logger = logger;
_hookingService = hookingService;
InitializeProviders();
}
private void InitializeProviders()
{
try
{
InitializeGeneralProviders();
}
catch(Exception ex)
{
_logger.Fatal($"Fatal error while initializing Customize+ IPC: {ex}");
IPCFailed = true;
DisposeProviders();
}
}
private void DisposeProviders()
{
DisposeGeneralProviders();
}
public void Dispose()
{
DisposeProviders();
}
}

View File

@@ -33,6 +33,7 @@ using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using OtterGui; using OtterGui;
using CustomizePlus.Api;
namespace CustomizePlus.Core; namespace CustomizePlus.Core;
@@ -147,6 +148,7 @@ public static class ServiceManagerBuilder
{ {
services services
.AddSingleton<PoseFileBoneLoader>() .AddSingleton<PoseFileBoneLoader>()
.AddSingleton<CustomizePlusLegacyIpc>()
.AddSingleton<CustomizePlusIpc>(); .AddSingleton<CustomizePlusIpc>();
return services; return services;

View File

@@ -9,6 +9,7 @@ using CustomizePlus.Core;
using CustomizePlus.Api.Compatibility; using CustomizePlus.Api.Compatibility;
using CustomizePlus.Configuration.Services.Temporary; using CustomizePlus.Configuration.Services.Temporary;
using OtterGui.Services; using OtterGui.Services;
using CustomizePlus.Api;
namespace CustomizePlus; namespace CustomizePlus;
@@ -38,6 +39,7 @@ public sealed class Plugin : IDalamudPlugin
v3ConfigFixer.FixV3ConfigIfNeeded(); v3ConfigFixer.FixV3ConfigIfNeeded();
_services.GetService<CustomizePlusIpc>(); _services.GetService<CustomizePlusIpc>();
_services.GetService<CustomizePlusLegacyIpc>();
_services.GetService<CPlusWindowSystem>(); _services.GetService<CPlusWindowSystem>();
_services.GetService<CommandService>(); _services.GetService<CommandService>();

View File

@@ -7,6 +7,7 @@ using CustomizePlus.Game.Services;
using CustomizePlus.Configuration.Data; using CustomizePlus.Configuration.Data;
using CustomizePlus.UI.Windows.MainWindow.Tabs.Templates; using CustomizePlus.UI.Windows.MainWindow.Tabs.Templates;
using CustomizePlus.Core.Helpers; using CustomizePlus.Core.Helpers;
using CustomizePlus.Api;
namespace CustomizePlus.UI.Windows.Controls; namespace CustomizePlus.UI.Windows.Controls;
@@ -17,6 +18,7 @@ public class PluginStateBlock
private readonly GameStateService _gameStateService; private readonly GameStateService _gameStateService;
private readonly FantasiaPlusDetectService _fantasiaPlusDetectService; private readonly FantasiaPlusDetectService _fantasiaPlusDetectService;
private readonly HookingService _hookingService; private readonly HookingService _hookingService;
private readonly CustomizePlusIpc _ipcService;
private static Vector4 normalColor = new Vector4(1, 1, 1, 1); private static Vector4 normalColor = new Vector4(1, 1, 1, 1);
private static Vector4 warnColor = new Vector4(1, 0.5f, 0, 1); private static Vector4 warnColor = new Vector4(1, 0.5f, 0, 1);
@@ -27,13 +29,15 @@ public class PluginStateBlock
PluginConfiguration configuration, PluginConfiguration configuration,
GameStateService gameStateService, GameStateService gameStateService,
FantasiaPlusDetectService fantasiaPlusDetectService, FantasiaPlusDetectService fantasiaPlusDetectService,
HookingService hookingService) HookingService hookingService,
CustomizePlusIpc ipcService)
{ {
_boneEditorPanel = boneEditorPanel; _boneEditorPanel = boneEditorPanel;
_configuration = configuration; _configuration = configuration;
_gameStateService = gameStateService; _gameStateService = gameStateService;
_fantasiaPlusDetectService = fantasiaPlusDetectService; _fantasiaPlusDetectService = fantasiaPlusDetectService;
_hookingService = hookingService; _hookingService = hookingService;
_ipcService = ipcService;
} }
public void Draw(float yPos) public void Draw(float yPos)
@@ -76,6 +80,11 @@ public class PluginStateBlock
message = $"Editor is active.{(_boneEditorPanel.HasChanges ? " You have unsaved changes, finish template bone editing to open save/revert dialog." : "")}"; message = $"Editor is active.{(_boneEditorPanel.HasChanges ? " You have unsaved changes, finish template bone editing to open save/revert dialog." : "")}";
} }
} }
else if (_ipcService.IPCFailed) //this is low priority error
{
severity = PluginStateSeverity.Error;
message = $"Detected failure in IPC. Integrations with other plugins will not function.";
}
if (message != null) if (message != null)
{ {

View File

@@ -24,6 +24,7 @@ public class IPCTestTab //: IDisposable
private readonly ActorManager _actorManager; private readonly ActorManager _actorManager;
private readonly ICallGateSubscriber<(int, int)>? _getApiVersion; private readonly ICallGateSubscriber<(int, int)>? _getApiVersion;
private readonly ICallGateSubscriber<bool>? _isValid;
private readonly ICallGateSubscriber<string, Character?, object>? _setCharacterProfile; private readonly ICallGateSubscriber<string, Character?, object>? _setCharacterProfile;
private readonly ICallGateSubscriber<Character?, string>? _getProfileFromCharacter; private readonly ICallGateSubscriber<Character?, string>? _getProfileFromCharacter;
private readonly ICallGateSubscriber<Character?, object>? _revertCharacter; private readonly ICallGateSubscriber<Character?, object>? _revertCharacter;
@@ -51,9 +52,11 @@ public class IPCTestTab //: IDisposable
_gameObjectService = gameObjectService; _gameObjectService = gameObjectService;
_actorManager = actorManager; _actorManager = actorManager;
_getApiVersion = pluginInterface.GetIpcSubscriber<(int, int)>("CustomizePlus.GetApiVersion"); _getApiVersion = pluginInterface.GetIpcSubscriber<(int, int)>("CustomizePlus.General.GetApiVersion");
_apiVersion = _getApiVersion.InvokeFunc(); _apiVersion = _getApiVersion.InvokeFunc();
_isValid = pluginInterface.GetIpcSubscriber<bool>("CustomizePlus.General.IsValid");
_setCharacterProfile = pluginInterface.GetIpcSubscriber<string, Character?, object>("CustomizePlus.SetProfileToCharacter"); _setCharacterProfile = pluginInterface.GetIpcSubscriber<string, Character?, object>("CustomizePlus.SetProfileToCharacter");
_getProfileFromCharacter = pluginInterface.GetIpcSubscriber<Character?, string>("CustomizePlus.GetProfileFromCharacter"); _getProfileFromCharacter = pluginInterface.GetIpcSubscriber<Character?, string>("CustomizePlus.GetProfileFromCharacter");
_revertCharacter = pluginInterface.GetIpcSubscriber<Character?, object>("CustomizePlus.RevertCharacter"); _revertCharacter = pluginInterface.GetIpcSubscriber<Character?, object>("CustomizePlus.RevertCharacter");
@@ -79,6 +82,9 @@ public class IPCTestTab //: IDisposable
_targetCharacterName = _gameObjectService.GetCurrentPlayerName(); _targetCharacterName = _gameObjectService.GetCurrentPlayerName();
ImGui.Text($"Version: {_apiVersion.Item1}.{_apiVersion.Item2}"); ImGui.Text($"Version: {_apiVersion.Item1}.{_apiVersion.Item2}");
//
//ImGui.Text($"IsValid: {_isValid?.InvokeFunc()}");
//ImGui.Text($"Last profile update: {_lastProfileUpdate}, Character: {_lastProfileUpdateName}"); //ImGui.Text($"Last profile update: {_lastProfileUpdate}, Character: {_lastProfileUpdateName}");
ImGui.Text($"Memory: {(string.IsNullOrWhiteSpace(_rememberedProfileJson) ? "empty" : "has data")}"); ImGui.Text($"Memory: {(string.IsNullOrWhiteSpace(_rememberedProfileJson) ? "empty" : "has data")}");