Skip to content

Commit

Permalink
Event Controller, Additional Events (#654)
Browse files Browse the repository at this point in the history
MidoriKami authored Oct 27, 2023
1 parent dcd4dcc commit ddd4e96
Showing 9 changed files with 95 additions and 26 deletions.
28 changes: 25 additions & 3 deletions Debugging/EventsDebugging.cs
Original file line number Diff line number Diff line change
@@ -14,25 +14,35 @@ public unsafe class EventsDebugging : DebugHelper {

private Dictionary<AddonEvent, Dictionary<string, List<EventController.EventSubscriber>>>? addonEventDict;
private List<EventController.EventSubscriber> frameworkSubscribers;
private List<EventController.EventSubscriber> territoryChangedSubscribers;

private bool viewingFramework = false;
private bool viewingTerritoryChanged = false;
private AddonEvent selectedType;

public override void Draw() {
addonEventDict ??= (Dictionary<AddonEvent, Dictionary<string, List<EventController.EventSubscriber>>>)typeof(EventController).GetProperty("AddonEventSubscribers", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);
frameworkSubscribers ??= (List<EventController.EventSubscriber>)typeof(EventController).GetProperty("FrameworkUpdateSubscribers", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);

if (addonEventDict == null || frameworkSubscribers == null) return;
territoryChangedSubscribers ??= (List<EventController.EventSubscriber>)typeof(EventController).GetProperty("TerritoryChangedSubscribers", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);

if (addonEventDict == null || frameworkSubscribers == null || territoryChangedSubscribers == null) return;

if (ImGui.BeginChild("eventTypeSelect", new Vector2(200 * ImGuiHelpers.GlobalScale, ImGui.GetContentRegionAvail().Y), true)) {
if (ImGui.Selectable("Framework", viewingFramework)) {
viewingFramework = true;
viewingTerritoryChanged = false;
}

if (ImGui.Selectable("TerritoryChanged", viewingTerritoryChanged)) {
viewingTerritoryChanged = true;
viewingFramework = false;
}

foreach (var t in Enum.GetValues<AddonEvent>()) {
ImGui.BeginDisabled(addonEventDict == null || !addonEventDict!.ContainsKey(t));
if (ImGui.Selectable($"{t}", selectedType == t && viewingFramework == false)) {
if (ImGui.Selectable($"{t}", selectedType == t && viewingFramework == false && viewingTerritoryChanged == false)) {
viewingFramework = false;
viewingTerritoryChanged = false;
selectedType = t;
}
ImGui.EndDisabled();
@@ -42,7 +52,19 @@ public override void Draw() {
ImGui.SameLine();
if (ImGui.BeginChild("events", ImGui.GetContentRegionAvail(), true)) {
if (viewingFramework) {
ImGui.SetWindowFontScale(1.25f);
ImGui.Text($"Framework");
ImGui.Separator();
ImGui.SetWindowFontScale(1f);

ShowEventList(frameworkSubscribers, true);
} else if (viewingTerritoryChanged) {
ImGui.SetWindowFontScale(1.25f);
ImGui.Text($"TerritoryChanged");
ImGui.Separator();
ImGui.SetWindowFontScale(1f);

ShowEventList(territoryChangedSubscribers, true);
} else {
if (addonEventDict.TryGetValue(selectedType, out var selectedTypeDict)) {
var h = true;
8 changes: 8 additions & 0 deletions Events/AddonEventAttribute.cs
Original file line number Diff line number Diff line change
@@ -59,4 +59,12 @@ public class AddonPostRefreshAttribute : AddonEventAttribute {
public AddonPostRefreshAttribute(params string[] addonNames) : base(AddonEvent.PostRefresh, addonNames) { }
}

public class AddonPreReceiveEventAttribute : AddonEventAttribute {
public AddonPreReceiveEventAttribute(params string[] addonNames) : base(AddonEvent.PreReceiveEvent, addonNames) { }
}

public class AddonPostReceiveEventAttribute : AddonEventAttribute {
public AddonPostReceiveEventAttribute(params string[] addonNames) : base(AddonEvent.PostReceiveEvent, addonNames) { }
}

#endregion
51 changes: 46 additions & 5 deletions Events/EventController.cs
Original file line number Diff line number Diff line change
@@ -42,6 +42,15 @@ public static EventSubscriber CreateFrameworkSubscriber(BaseTweak tweak, MethodI
return s;
}

public static EventSubscriber CreateTerritoryChangedSubscriber(BaseTweak tweak, MethodInfo method) {
var s = new EventSubscriber {
Tweak = tweak,
Method = method,
Kind = SubscriberKind.TerritoryChanged,
};
return s;
}

public enum SubscriberKind {
Unknown,
Invalid,
@@ -59,6 +68,8 @@ public enum SubscriberKind {
AddonFinalizeArgs,
AddonRequestedUpdateArgs,
AddonRefreshArgs,
AddonReceiveEventArgs,
TerritoryChanged,
}

private bool IsAddonPointer(ParameterInfo p) {
@@ -125,6 +136,11 @@ private bool DetermineInvokeKind() {
Kind = SubscriberKind.AddonRefreshArgs;
return true;
}

if (p[0].ParameterType == typeof(AddonReceiveEventArgs)) {
Kind = SubscriberKind.AddonReceiveEventArgs;
return true;
}

} else if (p.Length == 3) {
if (p[1].IsPointer<NumberArrayData>(2) && p[2].IsPointer<StringArrayData>(2)) {
@@ -154,7 +170,7 @@ private bool DetermineInvokeKind() {
return false;
}

public void Invoke(AddonArgs args) {
public void Invoke(object args) {
if (NthTick > 1) {
if (++tick < NthTick) return;
tick = 0;
@@ -176,17 +192,19 @@ public void Invoke(AddonArgs args) {
SubscriberKind.Unknown => null,
SubscriberKind.Framework => Method.Invoke(Tweak, Array.Empty<object>()),
SubscriberKind.NoParameter => Method.Invoke(Tweak, Array.Empty<object>()),
SubscriberKind.AtkUnitBase => Method.Invoke(Tweak, new[] { Pointer.Box((void*)args.Addon, typeof(AtkUnitBase*)) }),
SubscriberKind.AtkUnitBaseWithArrays => Method.Invoke(Tweak, new[] { Pointer.Box((void*)args.Addon, typeof(AtkUnitBase*)), Pointer.Box(AtkStage.GetSingleton()->GetNumberArrayData(), typeof(NumberArrayData**)), Pointer.Box(AtkStage.GetSingleton()->GetStringArrayData(), typeof(StringArrayData**)), }),
SubscriberKind.AddonPointer => Method.Invoke(Tweak, new[] { Pointer.Box((void*)args.Addon, addonPointerType) }),
SubscriberKind.AddonPointerWithArrays => Method.Invoke(Tweak, new[] { Pointer.Box((void*)args.Addon, addonPointerType), Pointer.Box(AtkStage.GetSingleton()->GetNumberArrayData(), typeof(NumberArrayData**)), Pointer.Box(AtkStage.GetSingleton()->GetStringArrayData(), typeof(StringArrayData**)), }),
SubscriberKind.AtkUnitBase => Method.Invoke(Tweak, new[] { Pointer.Box((void*)((AddonArgs)args).Addon, typeof(AtkUnitBase*)) }),
SubscriberKind.AtkUnitBaseWithArrays => Method.Invoke(Tweak, new[] { Pointer.Box((void*)((AddonArgs)args).Addon, typeof(AtkUnitBase*)), Pointer.Box(AtkStage.GetSingleton()->GetNumberArrayData(), typeof(NumberArrayData**)), Pointer.Box(AtkStage.GetSingleton()->GetStringArrayData(), typeof(StringArrayData**)), }),
SubscriberKind.AddonPointer => Method.Invoke(Tweak, new[] { Pointer.Box((void*)((AddonArgs)args).Addon, addonPointerType) }),
SubscriberKind.AddonPointerWithArrays => Method.Invoke(Tweak, new[] { Pointer.Box((void*)((AddonArgs)args).Addon, addonPointerType), Pointer.Box(AtkStage.GetSingleton()->GetNumberArrayData(), typeof(NumberArrayData**)), Pointer.Box(AtkStage.GetSingleton()->GetStringArrayData(), typeof(StringArrayData**)), }),
SubscriberKind.AddonArgs => Method.Invoke(Tweak, new object[] { args }),
SubscriberKind.AddonSetupArgs when args is AddonSetupArgs addonSetupArgs => Method.Invoke(Tweak, new object[] { addonSetupArgs }),
SubscriberKind.AddonUpdateArgs when args is AddonUpdateArgs addonUpdateArgs => Method.Invoke(Tweak, new object[] { addonUpdateArgs }),
SubscriberKind.AddonDrawArgs when args is AddonDrawArgs addonDrawArgs => Method.Invoke(Tweak, new object[] { addonDrawArgs }),
SubscriberKind.AddonFinalizeArgs when args is AddonFinalizeArgs addonFinalizeArgs => Method.Invoke(Tweak, new object[] { addonFinalizeArgs }),
SubscriberKind.AddonRequestedUpdateArgs when args is AddonRequestedUpdateArgs addonRequestedUpdateArgs => Method.Invoke(Tweak, new object[] { addonRequestedUpdateArgs }),
SubscriberKind.AddonRefreshArgs when args is AddonRefreshArgs addonRefreshArgs => Method.Invoke(Tweak, new object[] { addonRefreshArgs }),
SubscriberKind.AddonReceiveEventArgs when args is AddonReceiveEventArgs addonReceiveEventArgs => Method.Invoke(Tweak, new object[] { addonReceiveEventArgs }),
SubscriberKind.TerritoryChanged => Method.Invoke(Tweak, new object[] { args }),
_ => null,
};
} catch (Exception ex) {
@@ -200,6 +218,7 @@ public void Invoke(AddonArgs args) {

private static Dictionary<AddonEvent, Dictionary<string, List<EventSubscriber>>> AddonEventSubscribers { get; } = new();
private static List<EventSubscriber> FrameworkUpdateSubscribers { get; } = new();
private static List<EventSubscriber> TerritoryChangedSubscribers { get; } = new();

private static bool TryGetCustomAttribute<T>(this MemberInfo element, out T attribute) where T : Attribute {
attribute = element.GetCustomAttribute<T>();
@@ -224,6 +243,17 @@ public static void RegisterEvents(BaseTweak tweak) {
FrameworkUpdateSubscribers.Add(subscriber);
}

if (method.TryGetCustomAttribute<TerritoryChangedAttribute>(out _)) {
var subscriber = EventSubscriber.CreateTerritoryChangedSubscriber(tweak, method);

if (TerritoryChangedSubscribers.Count == 0) {
Service.ClientState.TerritoryChanged -= HandleTerritoryChanged;
Service.ClientState.TerritoryChanged += HandleTerritoryChanged;
}

TerritoryChangedSubscribers.Add(subscriber);
}

foreach (var attr in method.GetCustomAttributes<AddonEventAttribute>()) {
foreach (var addon in attr.AddonNames) {
SimpleLog.Verbose($"[EventController] {tweak.Name} requesting event '{attr.Event}' on method '{method.Name}' for addon '{addon}'");
@@ -253,6 +283,12 @@ private static void HandleFrameworkUpdate(IFramework framework) {
}
}

private static void HandleTerritoryChanged(ushort newTerritory) {
foreach (var tcSubscriber in TerritoryChangedSubscribers) {
tcSubscriber.Invoke(newTerritory);
}
}

private static void HandleEvent(AddonEvent type, AddonArgs args) {
if (!AddonEventSubscribers.TryGetValue(type, out var addonSubscriberDict)) return;

@@ -278,6 +314,11 @@ public static void UnregisterEvents(BaseTweak tweak) {
if (FrameworkUpdateSubscribers.Count == 0) {
Service.Framework.Update -= HandleFrameworkUpdate;
}

TerritoryChangedSubscribers.RemoveAll(f => f.Tweak == tweak);
if (TerritoryChangedSubscribers.Count == 0) {
Service.ClientState.TerritoryChanged -= HandleTerritoryChanged;
}

foreach (var (_, addonSubscribers) in AddonEventSubscribers) {
foreach (var (_, subscribers) in addonSubscribers) {
5 changes: 5 additions & 0 deletions Events/TerritoryChangedAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace SimpleTweaksPlugin.Events;

public class TerritoryChangedAttribute : EventAttribute {

}
4 changes: 2 additions & 2 deletions Tweaks/AutoLockHotbar.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Dalamud.Game.ClientState.Conditions;
using SimpleTweaksPlugin.Events;
using SimpleTweaksPlugin.TweakSystem;
using SimpleTweaksPlugin.Utility;

@@ -22,7 +23,6 @@ public class Configs : TweakConfig {

protected override void Enable() {
Config = LoadConfig<Configs>() ?? new Configs();
Service.ClientState.TerritoryChanged += OnTerritoryChanged;
Service.Condition.ConditionChange += OnConditionChange;
base.Enable();
}
@@ -31,12 +31,12 @@ private void OnConditionChange(ConditionFlag flag, bool value) {
if (Config.CombatStart && flag == ConditionFlag.InCombat && value) SetLock(true);
}

[TerritoryChanged]
private void OnTerritoryChanged(ushort _) {
if (Config.ZoneChange) SetLock(true);
}

protected override void Disable() {
Service.ClientState.TerritoryChanged -= OnTerritoryChanged;
Service.Condition.ConditionChange -= OnConditionChange;
SaveConfig(Config);
base.Disable();
11 changes: 2 additions & 9 deletions Tweaks/Chat/EchoPartyFinder.cs
Original file line number Diff line number Diff line change
@@ -42,15 +42,8 @@ public class Config : TweakConfig {
public override void Setup() {
onLookingForGroupEventHook ??= Common.Hook(AgentModule.Instance()->GetAgentByInternalId(AgentId.LookingForGroup)->VTable->ReceiveEvent, new ReceiveEventDelegate(OnLookingForGroupReceiveEvent));
}

protected override void Enable() {
Service.ClientState.TerritoryChanged += OnTerritoryChanged;
}

protected override void Disable() {
Service.ClientState.TerritoryChanged -= OnTerritoryChanged;
}


[TerritoryChanged]
private void OnTerritoryChanged(ushort territoryId) {
if (territoryId != targetTerritoryId) return;
if (TweakConfig.ShowUponEnteringInstance) PrintListing();
4 changes: 2 additions & 2 deletions Tweaks/Chat/HideChatPanelButtons.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FFXIVClientStructs.FFXIV.Component.GUI;
using SimpleTweaksPlugin.Events;
using SimpleTweaksPlugin.Utility;

namespace SimpleTweaksPlugin.Tweaks.Chat;
@@ -10,11 +11,11 @@ public unsafe class HideChatPanelButtons : ChatTweaks.SubTweak {
private readonly string[] panels = { "ChatLogPanel_1", "ChatLogPanel_2", "ChatLogPanel_3" };

protected override void Enable() {
Service.ClientState.TerritoryChanged += TerritoryChange;
ToggleButtons(false);
base.Enable();
}

[TerritoryChanged]
private void TerritoryChange(ushort territory) => ToggleButtons(false);

private void ToggleButtons(AtkUnitBase* atkUnitBase, bool visible) {
@@ -33,7 +34,6 @@ private void ToggleButtons(bool visible) {
}

protected override void Disable() {
Service.ClientState.TerritoryChanged -= TerritoryChange;
ToggleButtons(true);
base.Disable();
}
3 changes: 2 additions & 1 deletion Tweaks/UiAdjustment/MinimapAdjustments.cs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
using System.Numerics;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
using SimpleTweaksPlugin.Events;
using SimpleTweaksPlugin.TweakSystem;
using SimpleTweaksPlugin.Utility;

@@ -64,11 +65,11 @@ public class Configs : TweakConfig {
protected override void Enable() {
Config = LoadConfig<Configs>() ?? new Configs();
Service.ClientState.Login += OnLogin;
Service.ClientState.TerritoryChanged += OnTerritoryChanged;
base.Enable();
Update();
}

[TerritoryChanged]
private void OnTerritoryChanged(ushort _) {
sw.Restart();
Common.FrameworkUpdate -= WaitForUpdate;
7 changes: 3 additions & 4 deletions Tweaks/UiAdjustment/ParameterBarAdjustments.cs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using SimpleTweaksPlugin.Events;
using SimpleTweaksPlugin.TweakSystem;
using SimpleTweaksPlugin.Utility;

@@ -75,20 +76,17 @@ protected override void Enable() {
}

Config = LoadConfig<Configs>() ?? new Configs();
Common.FrameworkUpdate += OnFrameworkUpdate;
Service.ClientState.TerritoryChanged += OnTerritoryChanged;
OnTerritoryChanged(Service.ClientState.TerritoryType);
base.Enable();
}

protected override void Disable() {
Common.FrameworkUpdate -= OnFrameworkUpdate;
Service.ClientState.TerritoryChanged -= OnTerritoryChanged;
UpdateParameterBar(true);
SaveConfig(Config);
base.Disable();
}

[FrameworkUpdate]
private void OnFrameworkUpdate() {
try {
UpdateParameterBar();
@@ -98,6 +96,7 @@ private void OnFrameworkUpdate() {
}
}

[TerritoryChanged]
private void OnTerritoryChanged(ushort territoryType) {
var territory = Service.Data.Excel.GetSheet<TerritoryType>()?.GetRow(territoryType);
if (territory == null) return;

0 comments on commit ddd4e96

Please sign in to comment.