// https://github.com/XtraCube/Reactor/blob/main/Reactor/Utilities/StateMachineWrapper.cs using System; using System.Reflection; using HarmonyLib; #pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. namespace EHR.Modules; /// /// A wrapper for state machine objects to access their parent instance and state. /// /// The type of the parent class that owns the state machine. public class StateMachineWrapper : CompilerGeneratedObjectWrapper { // normally it is fields, but IL2CPP turns them into properties private readonly PropertyInfo _thisProperty; private readonly PropertyInfo _stateProperty; private T? _parentInstance; /// /// Gets the instance of the parent class that owns the state machine. /// public T Instance => _parentInstance ??= (T) _thisProperty.GetValue(GeneratedObject)!; /// /// Gets or sets the current state of the state machine. /// /// The current state as an integer. public int State { get => (int) _stateProperty.GetValue(GeneratedObject)!; set => _stateProperty.SetValue(GeneratedObject, value); } /// /// Initializes a new instance of the class. /// /// The state machine instance to wrap. public StateMachineWrapper(object stateMachine) : base(stateMachine) { _thisProperty = AccessTools.Property(GeneratedType, "__4__this"); _stateProperty = AccessTools.Property(GeneratedType, "__1__state"); if (_thisProperty == null || _stateProperty == null) { throw new MissingMemberException($"Could not find required properties in type '{GeneratedType}'."); } } /// /// Gets a parameter from the state machine by its name. /// /// The name of the parameter to retrieve. /// The type of the parameter to retrieve. /// >The value of the specified parameter. /// Thrown if the specified parameter does not exist. public TField GetParameter(string parameterName) { return GetField(parameterName); } /// /// Sets a parameter in the state machine by its name. /// /// The name of the parameter to set. /// The value to set for the parameter. /// The type of the parameter to set. /// Thrown if the specified parameter does not exist. public void SetParameter(string parameterName, TField value) { SetField(parameterName, value); } }