using Dalamud.Plugin; using LightlessSync.Interop.Ipc.Framework; using LightlessSync.PlayerData.Handlers; using LightlessSync.Services; using LightlessSync.Services.Mediator; using Microsoft.Extensions.Logging; using Penumbra.Api.Enums; using Penumbra.Api.Helpers; using Penumbra.Api.IpcSubscribers; namespace LightlessSync.Interop.Ipc.Penumbra; public sealed class PenumbraRedraw : PenumbraBase { private readonly RedrawManager _redrawManager; private readonly RedrawObject _penumbraRedraw; private readonly EventSubscriber _penumbraObjectIsRedrawn; public PenumbraRedraw( ILogger logger, IDalamudPluginInterface pluginInterface, DalamudUtilService dalamudUtil, LightlessMediator mediator, RedrawManager redrawManager) : base(logger, pluginInterface, dalamudUtil, mediator) { _redrawManager = redrawManager; _penumbraRedraw = new RedrawObject(pluginInterface); _penumbraObjectIsRedrawn = GameObjectRedrawn.Subscriber(pluginInterface, HandlePenumbraRedrawEvent); } public override string Name => "Penumbra.Redraw"; public void CancelPendingRedraws() => _redrawManager.Cancel(); public void RequestImmediateRedraw(int objectIndex, RedrawType redrawType) { if (!IsAvailable) { return; } _penumbraRedraw.Invoke(objectIndex, redrawType); } public async Task RedrawAsync(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token) { if (!IsAvailable || DalamudUtil.IsZoning) { return; } try { await _redrawManager.RedrawSemaphore.WaitAsync(token).ConfigureAwait(false); await _redrawManager.PenumbraRedrawInternalAsync(logger, handler, applicationId, chara => { logger.LogDebug("[{ApplicationId}] Calling on IPC: PenumbraRedraw", applicationId); _penumbraRedraw.Invoke(chara.ObjectIndex, RedrawType.Redraw); }, token).ConfigureAwait(false); } finally { _redrawManager.RedrawSemaphore.Release(); } } private void HandlePenumbraRedrawEvent(IntPtr objectAddress, int objectTableIndex) => Mediator.Publish(new PenumbraRedrawMessage(objectAddress, objectTableIndex, false)); protected override void HandleStateChange(IpcConnectionState previous, IpcConnectionState current) { } public override void Dispose() { base.Dispose(); _penumbraObjectIsRedrawn.Dispose(); } }