Files
Performance-Fish/Source/PerformanceFish/Events/ThingEvents.cs
T

167 lines
5.4 KiB
C#

// Copyright (c) 2023 bradson
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
using PerformanceFish.Prepatching;
namespace PerformanceFish.Events;
public sealed class ThingEvents : ClassWithFishPrepatches
{
public static event Action<Thing>?
Initialized,
Destroyed;
public sealed class Instanced
{
public event ThingGridEvents.EventHandler?
RegisteredAtThingGrid,
DeregisteredAtThingGrid;
public event Action<Thing, Map>? Spawned;
public event Action<Thing>?
DeSpawning,
DeSpawned,
Destroying,
Destroyed;
internal void OnSpawned(Thing thing, Map map) => Spawned?.Invoke(thing, map);
internal void OnDeSpawning(Thing thing) => DeSpawning?.Invoke(thing);
internal void OnDeSpawned(Thing thing) => DeSpawned?.Invoke(thing);
internal void OnDestroying(Thing thing) => Destroying?.Invoke(thing);
internal void OnDestroyed(Thing thing) => Destroyed?.Invoke(thing);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnRegisteredAtThingGrid(Thing thing, Map map, in IntVec3 cell)
=> RegisteredAtThingGrid?.Invoke(thing, map, cell);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnDeregisteredAtThingGrid(Thing thing, Map map, in IntVec3 cell)
=> DeregisteredAtThingGrid?.Invoke(thing, map, cell);
}
public sealed class SpawnSetupPatch : FishPrepatch
{
public override string? Description { get; }
= "Hook to invoke an event whenever things spawn. Does nothing by itself, but certain functions require "
+ "this.";
public override bool Enabled => true;
public override bool ShowSettings => false;
public override MethodBase TargetMethodBase { get; }
= AccessTools.DeclaredMethod(typeof(Thing), nameof(Thing.SpawnSetup));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Postfix(Thing __instance, Map map) => __instance.Events().OnSpawned(__instance, map);
}
public sealed class DeSpawnPatch : FishPrepatch
{
public override string? Description { get; }
= "Hook to invoke an event whenever things despawn. Does nothing by itself, but certain functions require "
+ "this.";
public override bool Enabled => true;
public override bool ShowSettings => false;
public override MethodBase TargetMethodBase { get; }
= AccessTools.DeclaredMethod(typeof(Thing), nameof(Thing.DeSpawn));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Prefix(Thing __instance) => __instance.Events().OnDeSpawning(__instance);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Postfix(Thing __instance) => __instance.Events().OnDeSpawned(__instance);
}
public sealed class DestroyPatch : FishPrepatch
{
public override string? Description { get; }
= "Hook to invoke an event whenever things get destroyed. Does nothing by itself, but certain functions "
+ "require this.";
public override bool Enabled => true;
public override bool ShowSettings => false;
public override MethodBase TargetMethodBase { get; }
= AccessTools.DeclaredMethod(typeof(Thing), nameof(Thing.Destroy));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Prefix(Thing __instance) => __instance.Events().OnDestroying(__instance);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Postfix(Thing __instance)
{
__instance.Events().OnDestroyed(__instance);
Destroyed?.Invoke(__instance);
}
}
public sealed class ExposeDataInitializePatch : FishPrepatch
{
public override string? Description { get; }
= "Hook to invoke an event when things finish loading from a save file. Does nothing by itself, but "
+ "certain functions require this.";
public override bool Enabled => true;
public override bool ShowSettings => false;
public override MethodBase TargetMethodBase { get; }
= AccessTools.DeclaredMethod(typeof(Thing), nameof(Thing.ExposeData));
public static void Postfix(Thing __instance)
{
if (Scribe.mode == LoadSaveMode.LoadingVars && __instance is not ThingWithComps)
OnThingInitialized(__instance);
}
}
public sealed class PostMakePatch : FishPrepatch
{
public override string? Description { get; }
= "Hook to invoke an event when things get created. Does nothing by itself, but certain functions require "
+ "this.";
public override bool Enabled => true;
public override bool ShowSettings => false;
public override MethodBase TargetMethodBase { get; }
= AccessTools.DeclaredMethod(typeof(Thing), nameof(Thing.PostMake));
public static void Postfix(Thing __instance)
{
if (__instance is not ThingWithComps)
OnThingInitialized(__instance);
}
}
public sealed class InitializeCompsPatch : FishPrepatch
{
public override string? Description { get; }
= "Hook to invoke an event when things with comps get initialized. Does nothing by itself, but certain "
+ "functions require this.";
public override bool Enabled => true;
public override bool ShowSettings => false;
public override MethodBase TargetMethodBase { get; }
= AccessTools.DeclaredMethod(typeof(ThingWithComps), nameof(ThingWithComps.InitializeComps));
public static void Postfix(ThingWithComps __instance) => OnThingInitialized(__instance);
}
private static void OnThingInitialized(Thing thing) => Initialized?.Invoke(thing);
}