Files
Hasebe/Assets/Code/Infrastructure/Generators/StateMachineGenerator.cs
T
2026-09-20 15:26:03 +03:00

105 lines
2.7 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);
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) : base(context)
{{
{statesCode}
}}
}}
}}
";
context.AddCode($"{sm.FullName}.Generated.cs", stateMachineCode);
}
}
private void GenerateStates(GeneratorContext context)
{
var states = TypeCache.GetTypesWithAttribute<State>();
foreach (var st in states)
{
var attribute = st.GetAttribute<State>();
var genetics = "";
if (!attribute.ManualInherit)
genetics =
$@" : BaseState<{attribute.StateEnum.FullName}, {attribute.StateMachineContext.FullName}>";
var statesCode = $@"
// retard-generated
using Code.Infrastructure.StateMachine;
namespace {st.Namespace}
{{
public partial class {st.Name} {genetics}
{{
}}
}}
";
context.AddCode($"{st.FullName}.Generated.cs", statesCode);
}
}
}
}
#endif