-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBellWatcher.cs
More file actions
64 lines (55 loc) · 2 KB
/
Copy pathBellWatcher.cs
File metadata and controls
64 lines (55 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Restocker;
/// <summary>
/// リテイナーベル(RetainerList addon)の表示状態を 150ms ポーリングし、
/// 開閉に合わせて MainWindow の表示/非表示を同期させる。RepeatBuy の ShopWatcher 流。
/// </summary>
public sealed unsafe class BellWatcher : IDisposable
{
private readonly IFramework framework;
private readonly IGameGui gameGui;
private readonly Func<bool> isEnabled;
private readonly Action<bool> setMainWindowOpen;
private readonly Action onBellOpened;
private bool lastVisible;
private DateTime nextPoll = DateTime.MinValue;
private readonly TimeSpan pollInterval = TimeSpan.FromMilliseconds(150);
public BellWatcher(
IFramework framework,
IGameGui gameGui,
Action<bool> setMainWindowOpen,
Func<bool> isEnabled,
Action onBellOpened)
{
this.framework = framework;
this.gameGui = gameGui;
this.setMainWindowOpen = setMainWindowOpen;
this.isEnabled = isEnabled;
this.onBellOpened = onBellOpened;
framework.Update += OnUpdate;
}
public bool IsBellOpen()
{
var addon = gameGui.GetAddonByName("RetainerList");
if (addon.Address == nint.Zero) return false;
var unitBase = (AtkUnitBase*)addon.Address;
return unitBase != null && unitBase->IsVisible;
}
private void OnUpdate(IFramework _)
{
var now = DateTime.UtcNow;
if (now < nextPoll) return;
nextPoll = now + pollInterval;
var visible = IsBellOpen();
if (visible != lastVisible)
{
// ウィンドウ自動開閉は AutoOpenOnBell に従う、キャラスナップショットは常に取る
if (isEnabled()) setMainWindowOpen(visible);
if (visible) onBellOpened();
lastVisible = visible;
}
}
public void Dispose() => framework.Update -= OnUpdate;
}