From 0450c4e3f7b70db54d2a3a77fb4fae75525410ce Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sat, 1 Jun 2024 20:26:18 +0200 Subject: [PATCH] Add StateChangedWithType. --- Glamourer.Api | 2 +- Glamourer/Api/GlamourerApi.cs | 2 +- Glamourer/Api/StateApi.cs | 17 ++-- Glamourer/Events/StateChanged.cs | 78 +++++-------------- .../Tabs/DebugTab/IpcTester/StateIpcTester.cs | 6 +- .../Interop/Penumbra/PenumbraAutoRedraw.cs | 5 +- Glamourer/State/StateEditor.cs | 31 ++++---- Glamourer/State/StateManager.cs | 7 +- 8 files changed, 56 insertions(+), 92 deletions(-) diff --git a/Glamourer.Api b/Glamourer.Api index 30cdd0a..a20d4ab 160000 --- a/Glamourer.Api +++ b/Glamourer.Api @@ -1 +1 @@ -Subproject commit 30cdd0a2386045b84f3cfdde483a1ffe60441f05 +Subproject commit a20d4ab1811a7f66918afab9b41ec723f75054f5 diff --git a/Glamourer/Api/GlamourerApi.cs b/Glamourer/Api/GlamourerApi.cs index 2c555af..b9e21fd 100644 --- a/Glamourer/Api/GlamourerApi.cs +++ b/Glamourer/Api/GlamourerApi.cs @@ -6,7 +6,7 @@ namespace Glamourer.Api; public class GlamourerApi(DesignsApi designs, StateApi state, ItemsApi items) : IGlamourerApi, IApiService { public const int CurrentApiVersionMajor = 1; - public const int CurrentApiVersionMinor = 1; + public const int CurrentApiVersionMinor = 2; public (int Major, int Minor) ApiVersion => (CurrentApiVersionMajor, CurrentApiVersionMinor); diff --git a/Glamourer/Api/StateApi.cs b/Glamourer/Api/StateApi.cs index 344fc5c..203f1b0 100644 --- a/Glamourer/Api/StateApi.cs +++ b/Glamourer/Api/StateApi.cs @@ -247,8 +247,9 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable return ApiHelpers.Return(GlamourerApiEc.Success, args); } - public event Action? StateChanged; - public event Action? GPoseChanged; + public event Action? StateChanged; + public event Action? StateChangedWithType; + public event Action? GPoseChanged; private void ApplyDesign(ActorState state, DesignBase design, uint key, ApplyFlag flags) { @@ -329,12 +330,14 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable private void OnGPoseChange(bool gPose) => GPoseChanged?.Invoke(gPose); - private void OnStateChange(StateChanged.Type _1, StateSource _2, ActorState _3, ActorData actors, object? _5) + private void OnStateChange(StateChangeType type, StateSource _2, ActorState _3, ActorData actors, object? _5) { - if (StateChanged == null) - return; + if (StateChanged != null) + foreach (var actor in actors.Objects) + StateChanged.Invoke(actor.Address); - foreach (var actor in actors.Objects) - StateChanged.Invoke(actor.Address); + if (StateChangedWithType != null) + foreach (var actor in actors.Objects) + StateChangedWithType.Invoke(actor.Address, type); } } diff --git a/Glamourer/Events/StateChanged.cs b/Glamourer/Events/StateChanged.cs index 4d878e8..641665c 100644 --- a/Glamourer/Events/StateChanged.cs +++ b/Glamourer/Events/StateChanged.cs @@ -1,67 +1,25 @@ +using Glamourer.Api.Enums; using Glamourer.Interop.Structs; using Glamourer.State; using OtterGui.Classes; -namespace Glamourer.Events +namespace Glamourer.Events; + +/// +/// Triggered when a Design is edited in any way. +/// +/// Parameter is the type of the change +/// Parameter is the changed saved state. +/// Parameter is the existing actors using this saved state. +/// Parameter is any additional data depending on the type of change. +/// +/// +public sealed class StateChanged() + : EventWrapper(nameof(StateChanged)) { - /// - /// Triggered when a Design is edited in any way. - /// - /// Parameter is the type of the change - /// Parameter is the changed saved state. - /// Parameter is the existing actors using this saved state. - /// Parameter is any additional data depending on the type of change. - /// - /// - public sealed class StateChanged() - : EventWrapper(nameof(StateChanged)) + public enum Priority { - public enum Type - { - /// A characters saved state had the model id changed. This means everything may have changed. Data is the old model id and the new model id. [(uint, uint)] - Model, - - /// A characters saved state had multiple customization values changed. TData is the old customize array and the applied changes. [(Customize, CustomizeFlag)] - EntireCustomize, - - /// A characters saved state had a customization value changed. Data is the old value, the new value and the type. [(CustomizeValue, CustomizeValue, CustomizeIndex)]. - Customize, - - /// A characters saved state had an equipment piece changed. Data is the old value, the new value and the slot [(EquipItem, EquipItem, EquipSlot)]. - Equip, - - /// A characters saved state had its weapons changed. Data is the old mainhand, the old offhand, the new mainhand and the new offhand [(EquipItem, EquipItem, EquipItem, EquipItem)]. - Weapon, - - /// A characters saved state had a stain changed. Data is the old stain id, the new stain id and the slot [(StainId, StainId, EquipSlot)]. - Stain, - - /// A characters saved state had a crest visibility changed. Data is the old crest visibility, the new crest visibility and the slot [(bool, bool, EquipSlot)]. - Crest, - - /// A characters saved state had its customize parameter changed. Data is the old value, the new value and the type [(CustomizeParameterValue, CustomizeParameterValue, CustomizeParameterFlag)]. - Parameter, - - /// A characters saved state had a material color table value changed. Data is the old value, the new value and the index [(Vector3, Vector3, MaterialValueIndex)] or just the index for resets. - MaterialValue, - - /// A characters saved state had a design applied. This means everything may have changed. Data is the applied design. [DesignBase] - Design, - - /// A characters saved state had its state reset to its game values. This means everything may have changed. Data is null. - Reset, - - /// A characters saved state had a meta toggle changed. Data is the old stain id, the new stain id and the slot [(StainId, StainId, EquipSlot)]. - Other, - - /// A characters state was reapplied. Data is null. - Reapply, - } - - public enum Priority - { - GlamourerIpc = int.MinValue, - PenumbraAutoRedraw = 0, - } + GlamourerIpc = int.MinValue, + PenumbraAutoRedraw = 0, } -} +} \ No newline at end of file diff --git a/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs b/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs index f210b0f..81c8cab 100644 --- a/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs +++ b/Glamourer/Gui/Tabs/DebugTab/IpcTester/StateIpcTester.cs @@ -30,7 +30,7 @@ public class StateIpcTester : IUiService, IDisposable private string _base64State = string.Empty; private string? _getStateString; - public readonly EventSubscriber StateChanged; + public readonly EventSubscriber StateChanged; private nint _lastStateChangeActor; private ByteString _lastStateChangeName = ByteString.Empty; private DateTime _lastStateChangeTime; @@ -44,7 +44,7 @@ public class StateIpcTester : IUiService, IDisposable public StateIpcTester(DalamudPluginInterface pluginInterface) { _pluginInterface = pluginInterface; - StateChanged = Api.IpcSubscribers.StateChanged.Subscriber(_pluginInterface, OnStateChanged); + StateChanged = Api.IpcSubscribers.StateChangedWithType.Subscriber(_pluginInterface, OnStateChanged); GPoseChanged = Api.IpcSubscribers.GPoseChanged.Subscriber(_pluginInterface, OnGPoseChange); StateChanged.Disable(); GPoseChanged.Disable(); @@ -195,7 +195,7 @@ public class StateIpcTester : IUiService, IDisposable ImGui.TextUnformatted($"at {_lastStateChangeTime.ToLocalTime().TimeOfDay}"); } - private void OnStateChanged(nint actor) + private void OnStateChanged(nint actor, StateChangeType _) { _lastStateChangeActor = actor; _lastStateChangeTime = DateTime.UtcNow; diff --git a/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs b/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs index 9359bea..72fb554 100644 --- a/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs +++ b/Glamourer/Interop/Penumbra/PenumbraAutoRedraw.cs @@ -1,4 +1,5 @@ using Dalamud.Plugin.Services; +using Glamourer.Api.Enums; using Glamourer.Events; using Glamourer.Interop.Structs; using Glamourer.State; @@ -43,9 +44,9 @@ public class PenumbraAutoRedraw : IDisposable, IRequiredService private readonly ConcurrentSet _skips = []; private DateTime _frame; - private void OnStateChange(StateChanged.Type type, StateSource source, ActorState state, ActorData _1, object? _2) + private void OnStateChange(StateChangeType type, StateSource source, ActorState state, ActorData _1, object? _2) { - if (type is StateChanged.Type.Design && source.IsIpc()) + if (type is StateChangeType.Design && source.IsIpc()) _skips.TryAdd(state); } diff --git a/Glamourer/State/StateEditor.cs b/Glamourer/State/StateEditor.cs index bd5d1e0..c20a69d 100644 --- a/Glamourer/State/StateEditor.cs +++ b/Glamourer/State/StateEditor.cs @@ -1,3 +1,4 @@ +using Glamourer.Api.Enums; using Glamourer.Designs; using Glamourer.Designs.Links; using Glamourer.Events; @@ -38,7 +39,7 @@ public class StateEditor( var actors = Applier.ForceRedraw(state, source.RequiresChange()); Glamourer.Log.Verbose( $"Set model id in state {state.Identifier.Incognito(null)} from {old} to {modelId}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Model, source, state, actors, (old, modelId)); + StateChanged.Invoke(StateChangeType.Model, source, state, actors, (old, modelId)); } /// @@ -51,7 +52,7 @@ public class StateEditor( var actors = Applier.ChangeCustomize(state, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set {idx.ToDefaultName()} customizations in state {state.Identifier.Incognito(null)} from {old.Value} to {value.Value}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Customize, settings.Source, state, actors, (old, value, idx)); + StateChanged.Invoke(StateChangeType.Customize, settings.Source, state, actors, (old, value, idx)); } /// @@ -64,7 +65,7 @@ public class StateEditor( var actors = Applier.ChangeCustomize(state, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set {applied} customizations in state {state.Identifier.Incognito(null)} from {old} to {customizeInput}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.EntireCustomize, settings.Source, state, actors, (old, applied)); + StateChanged.Invoke(StateChangeType.EntireCustomize, settings.Source, state, actors, (old, applied)); } /// @@ -74,8 +75,8 @@ public class StateEditor( if (!Editor.ChangeItem(state, slot, item, settings.Source, out var old, settings.Key)) return; - var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon; - var actors = type is StateChanged.Type.Equip + var type = slot.ToIndex() < 10 ? StateChangeType.Equip : StateChangeType.Weapon; + var actors = type is StateChangeType.Equip ? Applier.ChangeArmor(state, slot, settings.Source.RequiresChange()) : Applier.ChangeWeapon(state, slot, settings.Source.RequiresChange(), item.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType)); @@ -107,8 +108,8 @@ public class StateEditor( out var old, out var oldStain, settings.Key)) return; - var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon; - var actors = type is StateChanged.Type.Equip + var type = slot.ToIndex() < 10 ? StateChangeType.Equip : StateChangeType.Weapon; + var actors = type is StateChangeType.Equip ? Applier.ChangeArmor(state, slot, settings.Source.RequiresChange()) : Applier.ChangeWeapon(state, slot, settings.Source.RequiresChange(), item!.Value.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType)); @@ -119,7 +120,7 @@ public class StateEditor( Glamourer.Log.Verbose( $"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item!.Value.Name} ({item.Value.ItemId}) and its stain from {oldStain.Id} to {stain!.Value.Id}. [Affecting {actors.ToLazyString("nothing")}.]"); StateChanged.Invoke(type, settings.Source, state, actors, (old, item!.Value, slot)); - StateChanged.Invoke(StateChanged.Type.Stain, settings.Source, state, actors, (oldStain, stain!.Value, slot)); + StateChanged.Invoke(StateChangeType.Stain, settings.Source, state, actors, (oldStain, stain!.Value, slot)); } /// @@ -132,7 +133,7 @@ public class StateEditor( var actors = Applier.ChangeStain(state, slot, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old.Id} to {stain.Id}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Stain, settings.Source, state, actors, (old, stain, slot)); + StateChanged.Invoke(StateChangeType.Stain, settings.Source, state, actors, (old, stain, slot)); } /// @@ -145,7 +146,7 @@ public class StateEditor( var actors = Applier.ChangeCrests(state, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set {slot.ToLabel()} crest in state {state.Identifier.Incognito(null)} from {old} to {crest}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Crest, settings.Source, state, actors, (old, crest, slot)); + StateChanged.Invoke(StateChangeType.Crest, settings.Source, state, actors, (old, crest, slot)); } /// @@ -163,7 +164,7 @@ public class StateEditor( var actors = Applier.ChangeParameters(state, flag, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set {flag} crest in state {state.Identifier.Incognito(null)} from {old} to {@new}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Parameter, settings.Source, state, actors, (old, @new, flag)); + StateChanged.Invoke(StateChangeType.Parameter, settings.Source, state, actors, (old, @new, flag)); } public void ChangeMaterialValue(object data, MaterialValueIndex index, in MaterialValueState newValue, ApplySettings settings) @@ -175,7 +176,7 @@ public class StateEditor( var actors = Applier.ChangeMaterialValue(state, index, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set material value in state {state.Identifier.Incognito(null)} from {oldValue} to {newValue.Game}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.MaterialValue, settings.Source, state, actors, (oldValue, newValue.Game, index)); + StateChanged.Invoke(StateChangeType.MaterialValue, settings.Source, state, actors, (oldValue, newValue.Game, index)); } public void ResetMaterialValue(object data, MaterialValueIndex index, ApplySettings settings) @@ -187,7 +188,7 @@ public class StateEditor( var actors = Applier.ChangeMaterialValue(state, index, true); Glamourer.Log.Verbose( $"Reset material value in state {state.Identifier.Incognito(null)} to game value. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.MaterialValue, settings.Source, state, actors, index); + StateChanged.Invoke(StateChangeType.MaterialValue, settings.Source, state, actors, index); } /// @@ -200,7 +201,7 @@ public class StateEditor( var actors = Applier.ChangeMetaState(state, index, settings.Source.RequiresChange()); Glamourer.Log.Verbose( $"Set Head Gear Visibility in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Other, settings.Source, state, actors, (old, value, MetaIndex.HatState)); + StateChanged.Invoke(StateChangeType.Other, settings.Source, state, actors, (old, value, MetaIndex.HatState)); } /// @@ -357,7 +358,7 @@ public class StateEditor( Glamourer.Log.Verbose( $"Applied design to {state.Identifier.Incognito(null)}. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Design, state.Sources[MetaIndex.Wetness], state, actors, mergedDesign.Design); + StateChanged.Invoke(StateChangeType.Design, state.Sources[MetaIndex.Wetness], state, actors, mergedDesign.Design); return; diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs index 77e8797..f057580 100644 --- a/Glamourer/State/StateManager.cs +++ b/Glamourer/State/StateManager.cs @@ -1,4 +1,5 @@ using Dalamud.Plugin.Services; +using Glamourer.Api.Enums; using Glamourer.Designs; using Glamourer.Designs.Links; using Glamourer.Events; @@ -257,7 +258,7 @@ public sealed class StateManager( Glamourer.Log.Verbose( $"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Reset, source, state, actors, null); + StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null); } public void ResetAdvancedState(ActorState state, StateSource source, uint key = 0) @@ -282,7 +283,7 @@ public sealed class StateManager( Glamourer.Log.Verbose( $"Reset advanced customization and dye state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]"); - StateChanged.Invoke(StateChanged.Type.Reset, source, state, actors, null); + StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null); } public void ResetCustomize(ActorState state, StateSource source, uint key = 0) @@ -414,7 +415,7 @@ public sealed class StateManager( { var data = Applier.ApplyAll(state, forceRedraw || !actor.Model.IsHuman || CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), false); - StateChanged.Invoke(StateChanged.Type.Reapply, source, state, data, null); + StateChanged.Invoke(StateChangeType.Reapply, source, state, data, null); } public void DeleteState(ActorIdentifier identifier)