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));
}
}