133 lines
4.0 KiB
C#
133 lines
4.0 KiB
C#
#if UNITY_EDITOR
|
|
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);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif |