diff --git a/UXAssist/Common/GameEvent.cs b/UXAssist/Common/GameEvent.cs new file mode 100644 index 0000000..74d7096 --- /dev/null +++ b/UXAssist/Common/GameEvent.cs @@ -0,0 +1,27 @@ +using System; +using BepInEx.Logging; + +namespace UXAssist.Common; + +/// +/// Provides safe invocation helpers for game events. +/// +public static class GameEvent +{ + /// + /// Invokes each handler in the action's invocation list individually, + /// logging a warning if any handler throws an exception. + /// + /// The action to invoke. + /// The logger to use for warnings. + /// The name of the event for diagnostic messages. + public static void InvokeSafe(this Action action, ManualLogSource logger, string name) + { + if (action == null) return; + foreach (var d in action.GetInvocationList()) + { + try { d.DynamicInvoke(); } + catch (Exception ex) { logger?.LogWarning($"GameEvent '{name}' handler failed: {ex}"); } + } + } +} diff --git a/UXAssist/Common/GameLogic.cs b/UXAssist/Common/GameLogic.cs index 2c551bc..99a8921 100644 --- a/UXAssist/Common/GameLogic.cs +++ b/UXAssist/Common/GameLogic.cs @@ -1,49 +1,58 @@ -using System; +using System; using HarmonyLib; -using UnityEngine; namespace UXAssist.Common; +/// +/// Provides game lifecycle events for UXAssist and dependent mods. +/// public class GameLogic : PatchImpl { + /// + /// Raised after game data has finished loading. + /// public static Action OnDataLoaded; + + /// + /// Raised when a game session begins. + /// public static Action OnGameBegin; + + /// + /// Raised when a game session ends. + /// public static Action OnGameEnd; - private static void InvokeSafe(Action action) - { - if (action == null) return; - foreach (var handler in action.GetInvocationList()) - { - try - { - ((Action)handler)(); - } - catch (Exception ex) - { - Debug.LogException(ex); - } - } - } - + /// + /// Harmony postfix for . + /// Raises . + /// [HarmonyPostfix] [HarmonyPatch(typeof(VFPreload), nameof(VFPreload.InvokeOnLoadWorkEnded))] public static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { - InvokeSafe(OnDataLoaded); + OnDataLoaded.InvokeSafe(UXAssist.Logger, nameof(OnDataLoaded)); } + /// + /// Harmony postfix for . + /// Raises . + /// [HarmonyPostfix, HarmonyPriority(Priority.First)] [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] public static void GameMain_Begin_Postfix() { - InvokeSafe(OnGameBegin); + OnGameBegin.InvokeSafe(UXAssist.Logger, nameof(OnGameBegin)); } + /// + /// Harmony postfix for . + /// Raises . + /// [HarmonyPostfix, HarmonyPriority(Priority.Last)] [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] public static void GameMain_End_Postfix() { - InvokeSafe(OnGameEnd); + OnGameEnd.InvokeSafe(UXAssist.Logger, nameof(OnGameEnd)); } }