Initial commit

This commit is contained in:
ThomasCharester committed 2025-12-12 23:11:01 +03:00
commit 662f4a1d05
89 files changed
+8008

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3487788d480845039f84f7aa89195d0b
timeCreated: 1765564013
+19
View File
@@ -0,0 +1,19 @@
using Reflex.Core;
namespace Code.Debug
{
public class DebugInstaller : IInstaller
{
public void InstallBindings(ContainerBuilder containerBuilder)
{
containerBuilder.AddSingleton(typeof(DebugStateMachine));
containerBuilder.OnContainerBuilt += Bootstrap;
}
private void Bootstrap(Container container)
{
container.Resolve<DebugStateMachine>();
}
}
}
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 35352cf8cf4f4b638e1a1693a704f052
timeCreated: 1765565958
+20
View File
@@ -0,0 +1,20 @@
using System;
using Code.StateMachine;
namespace Code.Debug
{
public enum DebugStates
{
First,
Second,
Third
}
public class DebugStateMachineContext
{
public int SomeValue;
}
[Generators.StateMachine(typeof(DebugStateMachineContext), typeof(DebugStates))]
public partial class DebugStateMachine
{ }
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 71d501bd1540463496c6df3fa0bbb0ca
timeCreated: 1765564028
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6e84c82fd2ce4c449bee71acf27ed874
timeCreated: 1765566284
+24
View File
@@ -0,0 +1,24 @@
using Code.Generators;
using Code.StateMachine;
namespace Code.Debug.States
{
[State(typeof(DebugStateMachineContext) )]
public partial class FirstState : BaseState<DebugStates, DebugStateMachineContext>
{
public FirstState(DebugStateMachineContext context) : base(context)
{
}
public override DebugStates myState => DebugStates.First;
}
[State(typeof(DebugStateMachineContext) )]
public partial class SecondState : BaseState<DebugStates, DebugStateMachineContext>
{
public SecondState(DebugStateMachineContext context) : base(context)
{
}
public override DebugStates myState => DebugStates.First;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 24af5a4d2545481589242a5945bbafa5
timeCreated: 1765566292
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 56928494c304465d8dea6fe4bac75de2
timeCreated: 1765563811
+26
View File
@@ -0,0 +1,26 @@
using System;
namespace Code.Generators
{
public class StateMachine : Attribute
{
public Type StateMachineContextType;
public Type StateMachineEnumType;
public StateMachine(Type stateMachineContextType, Type stateMachineEnumType)
{
StateMachineContextType = stateMachineContextType;
StateMachineEnumType = stateMachineEnumType;
}
}
public class State : Attribute
{
public Type StateMachineContextType;
public State (Type stateMachineContextType )
{
StateMachineContextType = stateMachineContextType;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 03e07712b53c4a3d8f6c8033af003369
timeCreated: 1765563884
@@ -0,0 +1,95 @@
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<StateMachine>();
foreach (var sm in stateMachines)
{
var attribute = sm.GetAttribute<StateMachine>();
var states = TypeCache.GetTypesWithAttribute<State>()
.Where(st =>
st.GetAttribute<State>().StateMachineContextType.FullName ==
attribute.StateMachineContextType.FullName);
var statesCode = "";
var statesNamespacesCode = "";
foreach (var st in states)
{
var stateAttribute = st.GetAttribute<State>();
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/>
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 =
// $@"// <auto-generated/>
// partial class {t.Name}
// {{
// public override string ToString()
// {{
// return $""{toString}"";
// }}
// }}";
context.AddCode($"{sm.FullName}.Generated.cs", stateMachineCode);
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9fb4b6961cd0471d8183511316c15000
timeCreated: 1765563824
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f1c4dc7e83794f978e68900a1be81bc2
timeCreated: 1765563491
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using UnityEngine;
namespace Code.StateMachine
{
public abstract class AbstractStateMachine<TStateEnum, TStateMachineContext>
where TStateMachineContext : new()
{
public TStateEnum CurrentState { get; protected set; }
public BaseState<TStateEnum, TStateMachineContext> CurrentBaseState { get; protected set; }
private BaseState<TStateEnum, TStateMachineContext> _previousBaseState;
protected Dictionary<TStateEnum, BaseState<TStateEnum, TStateMachineContext>> States = new();
public TStateEnum AllowedStates { get; set; }
public TStateMachineContext StateMachineContext { get; protected set; } = new();
// protected virtual void Update()
// {
// CurrentBaseState.Tick();
// }
//
// protected void LateUpdate()
// {
// CurrentBaseState.LateTick();
// }
// Костыли 2 шт. для флагового енама в шаблонах
protected abstract bool CheckTransitionAllowed(TStateEnum nextState);
protected abstract void ResetAllowedTransitions();
// TODO Если в EnterState вызывается ExitState, то будет гарантированная поломка
public virtual AbstractStateMachine<TStateEnum, TStateMachineContext> SwitchState(TStateEnum nextState)
{
if (!CheckTransitionAllowed(nextState))
{
return null;
}
ResetAllowedTransitions();
_previousBaseState = CurrentBaseState;
CurrentBaseState = States[nextState];
if (_previousBaseState != null)
{
_previousBaseState.OnExited += CurrentBaseState.EnterState;
_previousBaseState.OnExited += FinishBaseStateTransition;
_previousBaseState.ExitState();
}
else
{
CurrentBaseState.EnterState();
}
CurrentState = nextState;
return this;
}
protected virtual void FinishBaseStateTransition()
{
_previousBaseState.OnExited -= CurrentBaseState.EnterState;
_previousBaseState.OnExited -= FinishBaseStateTransition;
_previousBaseState = null;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8f6ce15c93464753a99851fc5d46440f
timeCreated: 1765563731
+22
View File
@@ -0,0 +1,22 @@
namespace Code.StateMachine
{
public abstract class BaseState<TEnum, TStateMachineContext>
{
public abstract TEnum myState { get; }
public delegate void Entered();
public event Entered OnEntered;
public delegate void Exited();
public event Exited OnExited;
protected BaseState(TStateMachineContext context)
{
Context = context;
}
public TStateMachineContext Context { get; protected set; }
public virtual void EnterState() => OnEntered?.Invoke();
public virtual void ExitState() => OnExited?.Invoke();
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0c348c251b644c3c941d2bd91bbb290c
timeCreated: 1765563748