Add VisibilityService to improve tick performance with many online pairs
This commit is contained in:
@@ -19,7 +19,7 @@ namespace MareSynchronos.Services;
|
||||
|
||||
public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
{
|
||||
internal struct PlayerCharacter
|
||||
public struct PlayerCharacter
|
||||
{
|
||||
public uint ObjectId;
|
||||
public string Name;
|
||||
@@ -390,7 +390,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
||||
return _gameGui.WorldToScreen(obj.Position, out var screenPos) ? screenPos : Vector2.Zero;
|
||||
}
|
||||
|
||||
internal PlayerCharacter FindPlayerByNameHash(string ident)
|
||||
public PlayerCharacter FindPlayerByNameHash(string ident)
|
||||
{
|
||||
_playerCharas.TryGetValue(ident, out var result);
|
||||
return result;
|
||||
|
||||
@@ -72,6 +72,7 @@ public record ProfilePopoutToggle(Pair? Pair) : MessageBase;
|
||||
public record CompactUiChange(Vector2 Size, Vector2 Position) : MessageBase;
|
||||
public record ProfileOpenStandaloneMessage(Pair Pair) : MessageBase;
|
||||
public record RemoveWindowMessage(WindowMediatorSubscriberBase Window) : MessageBase;
|
||||
public record PlayerVisibilityMessage(string Ident, bool IsVisible) : KeyedMessage(Ident, SameThread: true);
|
||||
public record PairHandlerVisibleMessage(PairHandler Player) : MessageBase;
|
||||
public record OpenReportPopupMessage(Pair PairToReport) : MessageBase;
|
||||
public record OpenBanUserPopupMessage(Pair PairToBan, GroupFullInfoDto GroupFullInfoDto) : MessageBase;
|
||||
|
||||
51
MareSynchronos/Services/VisibilityService.cs
Normal file
51
MareSynchronos/Services/VisibilityService.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace MareSynchronos.Services;
|
||||
|
||||
// Detect when players of interest are visible
|
||||
public class VisibilityService : DisposableMediatorSubscriberBase
|
||||
{
|
||||
private readonly DalamudUtilService _dalamudUtil;
|
||||
private ConcurrentDictionary<string, bool> _trackedPlayerVisibility = new();
|
||||
private ConcurrentQueue<string> _removedPlayerMessageQueue = new();
|
||||
|
||||
public VisibilityService(ILogger<PairAnalyzer> logger, MareMediator mediator, DalamudUtilService dalamudUtil)
|
||||
: base(logger, mediator)
|
||||
{
|
||||
_dalamudUtil = dalamudUtil;
|
||||
Mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => FrameworkUpdate());
|
||||
}
|
||||
|
||||
public void StartTracking(string ident)
|
||||
{
|
||||
_trackedPlayerVisibility.TryAdd(ident, false);
|
||||
}
|
||||
|
||||
public void StopTracking(string ident)
|
||||
{
|
||||
// No PairVisibilityMessage is emitted if the player was visible when removed
|
||||
_trackedPlayerVisibility.TryRemove(ident, out _);
|
||||
}
|
||||
|
||||
private void FrameworkUpdate()
|
||||
{
|
||||
foreach (var player in _trackedPlayerVisibility)
|
||||
{
|
||||
string ident = player.Key;
|
||||
var findResult = _dalamudUtil.FindPlayerByNameHash(ident);
|
||||
|
||||
if (!player.Value && findResult.ObjectId != 0)
|
||||
{
|
||||
if (_trackedPlayerVisibility.TryUpdate(ident, newValue: true, comparisonValue: false))
|
||||
Mediator.Publish<PlayerVisibilityMessage>(new(ident, IsVisible: true));
|
||||
}
|
||||
else if (player.Value && findResult.ObjectId == 0)
|
||||
{
|
||||
if (_trackedPlayerVisibility.TryUpdate(ident, newValue: false, comparisonValue: true))
|
||||
Mediator.Publish<PlayerVisibilityMessage>(new(ident, IsVisible: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user