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