Files
Infratest/Assets/Code/Infrastructure/Generators/StateMachineGenerator.cs
T
ThomasCharester 5f5ace1b52 Essentials + extra crap
Loadings
Startups
Movement
Camera
2026-01-12 18:43:51 +03:00

131 lines
3.9 KiB
C#

using System.Linq;
using Unity.VisualScripting;
using UnityCodeGen;
using UnityEditor;
namespace Code.Infrastructure.Generators
{
[Generator]
public class StateMachineGenerator : ICodeGenerator
{
public void Execute(GeneratorContext context)
{
GenerateStates(context);
GenerateStateMachine(context);
}
private void GenerateStateMachine(GeneratorContext context)
{
var stateMachines = TypeCache.GetTypesWithAttribute<StateMachine>();
foreach (var sm in stateMachines)
{
var attribute = sm.GetAttribute<StateMachine>();
var states = TypeCache.GetTypesWithAttribute<State>()
.Where(st =>
st.GetAttribute<State>().StateMachineContext.FullName ==
attribute.StateMachineContextType.FullName);
var statesCode = "";
var statesNamespacesCode = "";
foreach (var st in states)
{
statesNamespacesCode += $@"
using {st.Namespace};
";
statesCode += $@"
var state{st.Name} = new {st.Name}(StateMachineContext,eventBus);
States.Add(state{st.Name}.myState, state{st.Name});
";
}
var stateMachineCode =
$@"
// <auto-generated/>
#pragma warning disable CS0105
using Code.Infrastructure.StateMachine;
{statesNamespacesCode}
#pragma warning restore CS0105
namespace {sm.Namespace}
{{
public partial class {sm.Name} : AbstractStateMachine<{attribute.StateMachineEnumType.FullName},{attribute.StateMachineContextType.FullName}>
{{
public {sm.Name}({attribute.StateMachineContextType.FullName} context, EventBus.EventBus eventBus) : base(context)
{{
{statesCode}
}}
protected override bool CheckTransitionAllowed({attribute.StateMachineEnumType.FullName} nextState) => AllowedStates.HasFlag(nextState);
protected override void ResetAllowedTransitions() => AllowedStates = 0;
}}
public static class {sm.Name}Extensions
{{
public static AbstractStateMachine<{attribute.StateMachineEnumType.FullName}, {attribute.StateMachineContextType.FullName}> AllowStateTransition(
this AbstractStateMachine<{attribute.StateMachineEnumType.FullName}, {attribute.StateMachineContextType.FullName}> stateMachine, {attribute.StateMachineEnumType.FullName} state)
{{
if (stateMachine == null) return null;
stateMachine.AllowedStates |= state;
return stateMachine;
}}
}}
}}
";
context.AddCode($"{sm.FullName}.Generated.cs", stateMachineCode);
}
}
private void GenerateStates(GeneratorContext context)
{
var states = TypeCache.GetTypesWithAttribute<State>();
var statesCode = "";
foreach (var st in states)
{
var attribute = st.GetAttribute<State>();
var fireStatesCode = "";
if(st.HasAttribute<StateRaisingEvent>()) fireStatesCode = $@"
protected override void _fireEnterState()
{{
EventBus.RaiseEvent<IEnterStateHandle<{st.FullName}>>(h => h.EnterState());
}}
protected override void _fireExitState()
{{
EventBus.RaiseEvent<IExitStateHandle<{st.FullName}>>(h => h.ExitState());
}}
";
var genetics = "";
if(!attribute.SilentBitch) genetics = $@" : BaseState<{attribute.StateEnum.FullName}, {attribute.StateMachineContext.FullName}>";
statesCode = $@"
// retard-generated
using Code.Infrastructure.StateMachine;
namespace {st.Namespace}
{{
public partial class {st.Name} {genetics}
{{
{fireStatesCode}
}}
}}
";
context.AddCode($"{st.FullName}.Generated.cs", statesCode);
}
}
}
}