Make AutoRedraw for IPC wait a bit before applying.

This commit is contained in:
Ottermandias 2024-02-22 18:32:40 +01:00
parent d8ce81cdc4
commit 53c2a7495f
2 changed files with 49 additions and 5 deletions

View file

@ -61,6 +61,7 @@ namespace Glamourer.Events
public enum Priority
{
GlamourerIpc = int.MinValue,
PenumbraAutoRedraw = 0,
}
}
}

View file

@ -1,5 +1,8 @@
using Dalamud.Plugin.Services;
using Glamourer.Events;
using Glamourer.Interop.Structs;
using Glamourer.State;
using OtterGui.Classes;
using OtterGui.Services;
using Penumbra.Api.Enums;
@ -7,24 +10,61 @@ namespace Glamourer.Interop.Penumbra;
public class PenumbraAutoRedraw : IDisposable, IRequiredService
{
private const int WaitFrames = 5;
private readonly Configuration _config;
private readonly PenumbraService _penumbra;
private readonly StateManager _state;
private readonly ObjectManager _objects;
private readonly IFramework _framework;
private readonly StateChanged _stateChanged;
public PenumbraAutoRedraw(PenumbraService penumbra, Configuration config, StateManager state, ObjectManager objects, IFramework framework)
public PenumbraAutoRedraw(PenumbraService penumbra, Configuration config, StateManager state, ObjectManager objects, IFramework framework,
StateChanged stateChanged)
{
_penumbra = penumbra;
_config = config;
_state = state;
_objects = objects;
_framework = framework;
_stateChanged = stateChanged;
_penumbra.ModSettingChanged += OnModSettingChange;
_framework.Update += OnFramework;
_stateChanged.Subscribe(OnStateChange, StateChanged.Priority.PenumbraAutoRedraw);
}
public void Dispose()
=> _penumbra.ModSettingChanged -= OnModSettingChange;
{
_penumbra.ModSettingChanged -= OnModSettingChange;
_framework.Update -= OnFramework;
_stateChanged.Unsubscribe(OnStateChange);
}
private readonly ConcurrentQueue<(ActorState, Action, int)> _actions = [];
private readonly ConcurrentSet<ActorState> _skips = [];
private void OnStateChange(StateChanged.Type type, StateSource source, ActorState state, ActorData _1, object? _2)
{
if (type is StateChanged.Type.Design && source.IsIpc())
_skips.TryAdd(state);
}
private void OnFramework(IFramework _)
{
var count = _actions.Count;
while (_actions.TryDequeue(out var tuple) && count-- > 0)
{
if (_skips.ContainsKey(tuple.Item1))
{
_skips.TryRemove(tuple.Item1);
continue;
}
if (tuple.Item3 > 0)
_actions.Enqueue((tuple.Item1, tuple.Item2, tuple.Item3 - 1));
else
tuple.Item2();
}
}
private void OnModSettingChange(ModSettingChange type, string name, string mod, bool inherited)
{
@ -41,9 +81,12 @@ public class PenumbraAutoRedraw : IDisposable, IRequiredService
if (collection != name)
continue;
foreach (var actor in actors.Objects)
_state.ReapplyState(actor, state, StateSource.IpcManual);
Glamourer.Log.Debug($"Automatically applied mod settings of type {type} to {id.Incognito(null)}.");
_actions.Enqueue((state, () =>
{
foreach (var actor in actors.Objects)
_state.ReapplyState(actor, state, StateSource.IpcManual);
Glamourer.Log.Debug($"Automatically applied mod settings of type {type} to {id.Incognito(null)}.");
}, WaitFrames));
}
});
else if (_config.AutoRedrawEquipOnChanges)