rjw-quirks/RJW-Quirks/Modules/Shared/Events/RjwEventManager.cs

98 lines
3.1 KiB
C#

using RimWorld;
using rjw.Modules.Shared.Logs;
using System;
using System.Collections.Generic;
using System.Text;
using Verse;
namespace rjwquirks.Modules.Shared.Events
{
public static class RjwEventManager
{
private static readonly Dictionary<RjwEventDef, List<RjwEventHandler>> _handlers = BuildHandlerDictionary();
private static readonly ILog _logger = LogManager.GetLogger("RjwEventManager");
/// <summary>
/// Routes RJW events to the relevant event handlers based on the def subscriptions
/// </summary>
public static void NotifyEvent(RjwEvent ev)
{
//implement own settings later
if (Prefs.DevMode)
{
_logger.Message($"RJW Event {ev.def}{SignalArgsToString(ev.args)}");
}
if (!_handlers.TryGetValue(ev.def, out List<RjwEventHandler> eventHandlers))
{
return;
}
if (Prefs.DevMode)
{
// Since event args are filled in C#, no reason to waste time checking them outside of the actual mod developement
CheckObligatoryArgs(ev);
}
foreach (RjwEventHandler handler in eventHandlers)
{
try
{
handler.HandleEvent(ev);
}
catch (Exception e)
{
// suppress exceptions so one bad mod wouldn't break everything
_logger.Error($"Handler exception when handling {ev.def}", e);
}
}
}
private static Dictionary<RjwEventDef, List<RjwEventHandler>> BuildHandlerDictionary()
{
Dictionary<RjwEventDef, List<RjwEventHandler>> handlers = new Dictionary<RjwEventDef, List<RjwEventHandler>>();
foreach (RjwEventHandlerDef handlerDef in DefDatabase<RjwEventHandlerDef>.AllDefsListForReading)
{
foreach (RjwEventDef eventDef in handlerDef.handlesEvents)
{
if (handlers.ContainsKey(eventDef))
{
handlers[eventDef].Add(handlerDef.Worker);
}
else
{
handlers[eventDef] = new List<RjwEventHandler> { handlerDef.Worker };
}
}
}
return handlers;
}
private static void CheckObligatoryArgs(RjwEvent ev)
{
foreach (string argName in ev.def.obligatoryArgs)
{
if (!ev.args.TryGetArg(argName, out _))
{
_logger.Error($"Got a {ev.def} event without the obligatory argument '{argName}'");
}
}
}
private static string SignalArgsToString(SignalArgs args)
{
StringBuilder message = new StringBuilder();
foreach (var arg in args.Args)
{
message.Append(", ");
message.Append(arg);
}
return message.ToString();
}
}
}