using System.Linq; using Code.StateMachine; using Unity.VisualScripting; using UnityEditor; using UnityCodeGen; using UnityEngine; namespace Code.Generators { [Generator] public class StateMachineGenerator : ICodeGenerator { public void Execute(GeneratorContext context) { var stateMachines = TypeCache.GetTypesWithAttribute(); foreach (var sm in stateMachines) { var attribute = sm.GetAttribute(); var states = TypeCache.GetTypesWithAttribute() .Where(st => st.GetAttribute().StateMachineContextType.FullName == attribute.StateMachineContextType.FullName); var statesCode = ""; var statesNamespacesCode = ""; foreach (var st in states) { var stateAttribute = st.GetAttribute(); statesNamespacesCode += $@" using {st.Namespace}; "; statesCode += $@" var state{st.Name} = new {st.Name}(StateMachineContext); States.Add(state{st.Name}.myState, state{st.Name}); "; } var stateMachineCode = $@" // using Code.StateMachine; {statesNamespacesCode} namespace {sm.Namespace} {{ public partial class {sm.Name} : AbstractStateMachine<{attribute.StateMachineEnumType.FullName},{attribute.StateMachineContextType.FullName}> {{ public {sm.Name}() {{ {statesCode} CurrentBaseState = States[default({attribute.StateMachineEnumType.FullName})]; }} 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; }} }} }} "; // var publicFields = t.GetFields() // .Where(x => x.IsPublic && !x.IsStatic) // .Select(x => $"{x.Name}:{{{x.Name}}}"); // var toString = string.Join(", ", publicFields); // var code = // $@"// // partial class {t.Name} // {{ // public override string ToString() // {{ // return $""{toString}""; // }} // }}"; context.AddCode($"{sm.FullName}.Generated.cs", stateMachineCode); } } } }