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 public enum Priority
{ {
GlamourerIpc = int.MinValue, GlamourerIpc = int.MinValue,
PenumbraAutoRedraw = 0,
} }
} }
} }

View file

@ -1,5 +1,8 @@
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Glamourer.Events;
using Glamourer.Interop.Structs;
using Glamourer.State; using Glamourer.State;
using OtterGui.Classes;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
@ -7,24 +10,61 @@ namespace Glamourer.Interop.Penumbra;
public class PenumbraAutoRedraw : IDisposable, IRequiredService public class PenumbraAutoRedraw : IDisposable, IRequiredService
{ {
private const int WaitFrames = 5;
private readonly Configuration _config; private readonly Configuration _config;
private readonly PenumbraService _penumbra; private readonly PenumbraService _penumbra;
private readonly StateManager _state; private readonly StateManager _state;
private readonly ObjectManager _objects; private readonly ObjectManager _objects;
private readonly IFramework _framework; 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; _penumbra = penumbra;
_config = config; _config = config;
_state = state; _state = state;
_objects = objects; _objects = objects;
_framework = framework; _framework = framework;
_stateChanged = stateChanged;
_penumbra.ModSettingChanged += OnModSettingChange; _penumbra.ModSettingChanged += OnModSettingChange;
_framework.Update += OnFramework;
_stateChanged.Subscribe(OnStateChange, StateChanged.Priority.PenumbraAutoRedraw);
} }
public void Dispose() 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) private void OnModSettingChange(ModSettingChange type, string name, string mod, bool inherited)
{ {
@ -41,9 +81,12 @@ public class PenumbraAutoRedraw : IDisposable, IRequiredService
if (collection != name) if (collection != name)
continue; continue;
foreach (var actor in actors.Objects) _actions.Enqueue((state, () =>
_state.ReapplyState(actor, state, StateSource.IpcManual); {
Glamourer.Log.Debug($"Automatically applied mod settings of type {type} to {id.Incognito(null)}."); 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) else if (_config.AutoRedrawEquipOnChanges)