Skip to content

Commit

Permalink
use events to hide addon, fix event spamming in cd hook and re-fix fi…
Browse files Browse the repository at this point in the history
…rst draw (should help with #41)
  • Loading branch information
xorus committed Jan 2, 2024
1 parent 70b30a0 commit d71f86d
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 86 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
- Big code rewrite and a bit of optimization
- Fix save errors when spinning color sliders like a maniac in configuration
- Reorganized configuration file to preserve my sanity
- "Hide original addon" now uses AddonLifecycle events instead of searching for the original countdown every frame
- Reduce CountdownHook CPU usage by fixing a stupid event spam mistake
- Optimize countdown display code
- Fix the "first-draw" workaround that draws the countdown window once on plugin activation so it does not the micro
freeze caused by ImGUI initializing the window does not occur when starting a countdown

# v2.2.6.0

Expand Down
3 changes: 1 addition & 2 deletions Plugin/Commands/SettingsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

namespace EngageTimer.Commands;

public class SettingsCommand : IDisposable
public sealed class SettingsCommand : IDisposable
{
public SettingsCommand()
{
Expand All @@ -32,7 +32,6 @@ public SettingsCommand()
public void Dispose()
{
Plugin.Commands.RemoveHandler("/egsettings");
GC.SuppressFinalize(this);
}

private static void OpenSettingsCommand(string command, string args)
Expand Down
91 changes: 91 additions & 0 deletions Plugin/Game/AddonHider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// This file is part of EngageTimer
// Copyright (C) 2023 Xorus <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

using System;
using Dalamud.Game.Addon.Lifecycle;
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using FFXIVClientStructs.FFXIV.Component.GUI;

namespace EngageTimer.Game;

public sealed class AddonHider : IDisposable
{
private const byte VisibleFlag = 0x20;
private IntPtr _lastCountdownAddon = IntPtr.Zero;
private bool _addonHidden = false;

public AddonHider()
{
Plugin.State.CountingDownChanged += ShowAddonNearEnd;
Plugin.AddonLifecycle.RegisterListener(AddonEvent.PostSetup, "ScreenInfo_CountDown", HideAddon);
Plugin.AddonLifecycle.RegisterListener(AddonEvent.PreFinalize, "ScreenInfo_CountDown", AddonFinalize);
}

/**
* Re-enables the countdown addon when done counting down to show "START"
*/
private unsafe void ShowAddonNearEnd(object? sender, EventArgs eventArgs)
{
if (Plugin.State.CountingDown
|| !_addonHidden
|| !Plugin.Config.Countdown.HideOriginalAddon
|| _lastCountdownAddon == IntPtr.Zero) return;
_addonHidden = false;
try
{
var atkUnitBase = (AtkUnitBase*)_lastCountdownAddon;
atkUnitBase->Flags |= VisibleFlag;
// Plugin.Logger.Debug("show addon");
}
catch (Exception)
{
// invalid pointer, don't care and carry on
}
}

/**
* reset our internal "_addonHidden" state when the game destroys it
*/
private void AddonFinalize(AddonEvent type, AddonArgs args)
{
_lastCountdownAddon = IntPtr.Zero;
_addonHidden = false;
}

private unsafe void HideAddon(AddonEvent type, AddonArgs args)
{
if (!Plugin.Config.Countdown.HideOriginalAddon) return;
var addon = args.Addon;
_lastCountdownAddon = addon;
if (addon == IntPtr.Zero) return;
_addonHidden = true;
try
{
var atkUnitBase = (AtkUnitBase*)addon;
atkUnitBase->Flags = (byte)(atkUnitBase->Flags & ~VisibleFlag);
// Plugin.Logger.Debug("hide addon");
}
catch (Exception)
{
// invalid pointer, don't care and carry on
}
}

public void Dispose()
{
Plugin.AddonLifecycle.UnregisterListener(AddonEvent.PostSetup, "ScreenInfo_CountDown", HideAddon);
Plugin.AddonLifecycle.UnregisterListener(AddonEvent.PreFinalize, "ScreenInfo_CountDown", AddonFinalize);
}
}
13 changes: 9 additions & 4 deletions Plugin/Game/CountdownHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,13 @@ public void Update()

private void UpdateCountDown()
{
_state.CountingDown = false;
if (_countDown == 0) return;
var newCountingDown = false;
if (_countDown == 0)
{
_state.CountingDown = newCountingDown;
return;
}

var countDownPointerValue = Marshal.PtrToStructure<float>((IntPtr)_countDown + 0x2c);

// is last value close enough (workaround for floating point approx)
Expand All @@ -94,11 +99,11 @@ private void UpdateCountDown()
if (countDownPointerValue > 0 && _countDownRunning)
{
var newValue = Marshal.PtrToStructure<float>((IntPtr)_countDown + 0x2c);
if (newValue > _state.CountDownValue) _state.FireStartCountingDown();
_state.CountDownValue = newValue;
_state.CountingDown = true;
newCountingDown = true;
}

_state.CountingDown = newCountingDown;
_lastCountDownValue = countDownPointerValue;
}

Expand Down
4 changes: 3 additions & 1 deletion Plugin/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public sealed class Plugin : IDalamudPlugin
[PluginService] public static IChatGui ChatGui { get; private set; } = null!;
[PluginService] public static IGameInteropProvider GameInterop { get; private set; } = null!;
[PluginService] public static IPluginLog Logger { get; private set; } = null!;
[PluginService] public static IAddonLifecycle AddonLifecycle { get; private set; } = null!;
public static ConfigurationFile Config { get; private set; } = null!;
public static State State { get; private set; } = null!;
public static Translator Translator { get; private set; } = null!;
Expand All @@ -50,7 +51,8 @@ public sealed class Plugin : IDalamudPlugin

public Plugin(DalamudPluginInterface pluginInterface)
{
PluginPath = PluginInterface.AssemblyLocation.DirectoryName ?? throw new InvalidOperationException("Cannot find plugin directory");
PluginPath = PluginInterface.AssemblyLocation.DirectoryName ??
throw new InvalidOperationException("Cannot find plugin directory");
Config = ConfigurationLoader.Load();
State = new State();
Translator = new Translator();
Expand Down
6 changes: 0 additions & 6 deletions Plugin/Status/State.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,4 @@ public bool CountingDown
public bool PrePulling { get; set; } = false;
public event EventHandler? InCombatChanged;
public event EventHandler? CountingDownChanged;
public event EventHandler? StartCountingDown;

public void FireStartCountingDown()
{
StartCountingDown?.Invoke(this, EventArgs.Empty);
}
}
Loading

0 comments on commit d71f86d

Please sign in to comment.