Net State Machine
v0.4.0
Eine Zustandsmaschinen-Builder-Bibliothek für .NET.
Das folgende Beispiel zeigt einige Funktionen der Zustandsmaschine.
using Enderlook.StateMachine;public class Character{private static StateMachineFactory<States, Events, Character>? Factory;private readonly Random rnd = new();private readonly StateMachine<States, Events, Character> stateMachine;private int health = 100;private int food = 100;private enum States{Sleep,Play,GettingFood,Hunt,Gather,} private enum Events{HasFullHealth,LowHealth,IsHungry,IsNoLongerHungry,}public static async Task Main(){Character Character = new();while (true){Console.Clear();// Führt einen Aktualisierungsaufruf der Zustandsmaschine aus und übergibt ihr einen beliebigen Parameter.// Der Parameter ist generisch, also ist er generisch Kann keine Werttypen zuweisen.// Dieser Parameter wird an den abonnierten Delegaten übergeben, der den generischen Argumenttyp in seiner Signatur akzeptiert.// Wenn Sie keinen Parameter übergeben möchten, können Sie den Methodenaufruf .With() entfernen./ / Dieses Parametersystem kann auch kann mit Feuerereignismethoden verwendet werden.character.stateMachine.With(character.rnd.NextSingle()).Update();Console.WriteLine($"State: {character.stateMachine.CurrentState}.");Console.WriteLine($ "Health: {character.health}.");Console.WriteLine($"Food: {character.food}.");await Task.Delay(10).ConfigureAwait(false);}}public Character(){// Erstellt eine Instanz des Zustands machine.stateMachine = GetStateMachineFactory().Create(this); // Alternativ können Sie Folgendes tun, wenn Sie Parameter an die Initialisierung der Zustandsmaschine übergeben möchten: // stateMachine = GetStateMachineFactory().With(parameter).Create(this). // Die Methode „.With(parameter)“ kann beliebig oft verkettet werden. // Das Muster „stateMachine.With(p1).With(p2)...With(pn).SomeMethod(...)“ ist auch für die Methoden „Fire()“, „FireImmediately()“ und „Update“ gültig ()`.}private static StateMachineFactory<States, Events, Character> GetStateMachineFactory(){if (factory is not null)returnfactory;StateMachineFactory<States, Ereignisse, Charakter>? Factory_ = StateMachine<States, Events, Character>// Zustandsmaschinen werden aus Fabriken erstellt, was die Erstellung mehrerer Instanzen// sowohl in der CPU als auch im Speicher kostengünstiger macht, da die Berechnung einmal durchgeführt und zwischen den erstellten Instanzen geteilt wird..CreateFactoryBuilder()// Bestimmt den Anfangszustand der Zustandsmaschine. // Der zweite Parameter bestimmt, wie OnEntry-Delegierte während der Initialisierung der Zustandsmaschine ausgeführt werden sollen. // InitializationPolicy.Ignore bedeutet, dass sie ausgeführt werden sollten nicht ausgeführt werden..SetInitialState(States.Sleep, InitializationPolicy.Ignore)// Konfiguriert einen Status..In(States.Sleep)// Wird jedes Mal ausgeführt, wenn wir in diesen Status wechseln..OnEntry(() => Console.WriteLine( „Ins Bett gehen.“))// Wird jedes Mal ausgeführt, wenn wir diesen Zustand verlassen..OnExit(() => Console.WriteLine(“Aufstehen.“))// Wird jedes Mal ausgeführt, wenn die Aktualisierungsmethode (entweder Update() oder With<T>(T).Update()) ausgeführt wird und sich in diesem Zustand befindet.// Alle Ereignisse stellen eine Überladung zur Übergabe eines Empfängers bereit, sodass sie während des Builds parametrisiert werden kann von konkreten Instanzen.// Bietet außerdem eine Überladung zum Übergeben eines Parameters eines beliebigen Typs, sodass er während des Aufrufs von With<T>(T).Update() parametisiert werden kann.// Bietet außerdem eine Überladung zum Übergeben sowohl eines Empfängers als auch ein Parameter eines beliebigen Typs.// Diese Überladung gilt auch zu den Methoden OnEntry(...), OnExit(...), If(...) und Do(...)..OnUpdate(@this => @this.OnUpdateSleep()).On(Events.HasFullHealth )// Wird jedes Mal ausgeführt, wenn dieses Ereignis in diesem Zustand ausgelöst wird..Do(() => Console.WriteLine("Spielzeug auswählen."))// Neuer Zustand für den Übergang..Goto(States.Play)// Alternativ, Sie können die Ereignisausführungsrichtlinie während des konfigurieren Transition.// Der obige Methodenaufruf entspricht: // .OnEntryPolicy(TransitionPolicy.ChildFirstWithCulling).OnExitPolicy(TransitionPolicy.ParentFirstWithCulling).Goto(States.Play)..On(Events.IsHungry)// Führen Sie nur den nächsten Aufruf aus wenn die Bedingung wahr ist..If(@this => @this.IsVeryWounded())// Wir bleiben in unserem aktuellen Zustand, ohne ihn auszuführen OnEntry- und OnExit-Delegaten..StaySelf()// Die obige Methode ist eine Abkürzung von:// .OnEntryPolicy(TransitionPolicy.Ignore).OnExitPolicy(TransitionPolicy.Ignore).Goto(States.Sleep).// Wenn wir sie ausführen wollten Diese Delegaten können wir verwenden:// .GotoSelf(false)// Das ist die Abkürzung von:// .OnEntryPolicy(TransitionPolicy.ChildFirstWithCullingInclusive).OnExitPolicy(TransitionPolicy.ParentFirstWithCullingInclusive).Goto(States.Sleep).// Wenn wir zusätzlich Übergangsdelegaten aus den übergeordneten Zuständen ausführen wollten (was in diesem Beispiel nicht nützlich ist, da State.Sleep ist kein Unterzustand) können wir tun: // .GotoSelf(true)// Das ist die Abkürzung of:// .OnEntryPolicy(TransitionPolicy.ChildFirst).OnExitPolicy(TransitionPolicy.ParentFirst).Goto(States.Sleep).// Sonst den nächsten Aufruf ausführen, wenn die Bedingung wahr ist..If(@this => @this.IsWounded ()).Goto(States.Gather)// Else bedingungslos ausführen..Goto(States.Hunt)// Dieses Ereignis in diesem Fall ignorieren Transition.// (Wenn wir dies nicht hinzufügen und dieses Ereignis versehentlich auslösen, wird eine Ausnahme ausgelöst)..Ignore(Events.LowHealth)// Das ist die Abkürzung von:// .On(Events.LowHealth).OnEntryPolicy (TransitionPolicy.Ignore).OnExitPolicy(TransitionPolicy.Ignore).Goto(States.Sleep)..In(States.Play).OnUpdate(@this => @this.OnUpdatePlay()).On(Events.IsHungry).If(@this => @this.IsWounded()).Goto(States.Gather).Goto(States.Hunt).In(States.GettingFood). OnEntry(() => Console.WriteLine("Essen holen gehen.")).OnExit(() => Console.WriteLine("Essen holen gehen.")).In(States.Gather)// Bestimmt dass dieser Status ein Unterstatus eines anderen ist.// Dies bedeutet, dass OnUpdate-Delegates im übergeordneten Status ebenfalls ausgeführt werden.// Abhängig von der konfigurierten OnEntryPolicy und OnExitPolicy während Übergängen// können auch die in diesem Status abonnierten OnEntry- und OnExit-Delegates ausgeführt werden bei Übergängen in Unterzuständen ausgeführt werden..IsSubStateOf(States.GettingFood).OnUpdate((Character @this, float-Parameter) => @this.OnUpdateGather(parameter)).On(Events.IsNoLongerHungry).If(@this => @this.IsWounded()).Goto(States.Sleep).Goto(States.Play).On(Events.HasFullHealth) .Goto(States.Hunt).In(States.Hunt).IsSubStateOf(States.GettingFood).OnEntry(() => Console.WriteLine("Take Bogen.")).OnExit(() => Console.WriteLine("Drop Bow.")).OnUpdate((Character @this, float Parameter) => @this.OnUpdateHunt(parameter)).On(Events.IsNoLongerHungry ).Goto(States.Sleep).On(Events.LowHealth).Goto(States.Sleep).Finalize();// Die Verriegelung ist nützlich, um die Speichernutzung beim Multithreading zu reduzieren Situationen.// Das liegt daran, dass die Factory gemeinsame Daten zwischen Instanzen enthält. // Wenn also zwei Instanzen aus zwei verschiedenen Factorys erstellt werden, verbraucht dies mehr Speicher // als zwei Instanzen, die aus derselben Factory erstellt wurden.Interlocked.CompareExchange(ref Factory, Factory_, Null);Return Factory;}Private Bool IsVeryWounded() => Gesundheit <= 50;Private Bool IsWounded() => Gesundheit <= 75;Private Leere OnUpdateHunt(float Luck){food += (int)MathF.Round(rnd.Next(8) * Luck);if (food >= 100){food = 100;stateMachine.Fire(Events.IsNoLongerHungry); // Alternativ können Sie Folgendes tun, wenn Sie Parameter an die Initialisierung der Zustandsmaschine übergeben möchten: // stateMachine.With(paramter).Fire(Events.IsNoLongerHungry);}health -= (int)MathF.Round(rnd.Next(6) * (1 - Luck));if (health <= 20)stateMachine. Fire(Events.LowHealth);}private void OnUpdateGather(float Luck){food += (int)MathF.Round(rnd.Next(3) *luck);if (food >= 100){food = 100;stateMachine.Fire(Events.IsNoLongerHungry);}if (rnd.Next(1) % 1 = = 0){health++;if (health >= 100){health = 100;stateMachine.Fire(Events.HasFullHealth);}}}private void OnUpdatePlay(){food -= 3;if (food <= 0){food = 0;stateMachine.Fire(Events.IsHungry);}}private void OnUpdateSleep(){health++;if (health >= 100){health = 100;stateMachine.Fire(Events.HasFullHealth);}food -= 2;if (food <= 0){food = 0;stateMachine.Fire(Events.IsHungry);}}}
öffentliche versiegelte Klasse StateMachine<TState, TEvent, TRecipient>where TState : notnullwhere TEvent : notnull{/// Aktuellen (Unter-)Zustand dieser Zustandsmaschine abrufen.public TState CurrentState { get; }/// Aktuellen (Unter-)Zustand und alle seine übergeordneten Zustände abrufen hierarchy.public ReadOnlySlice<TState> CurrentStateHierarchy { get; }/// Get akzeptiert Ereignisse nach aktuellem (Unter-)Zustand.public ReadOnlySlice<TEvent> CurrentAcceptedEvents { get; }/// Erstellt eine Fabrik builder.public static StateMachineBuilder<TState, TEvent, TRecipient> CreateFactoryBuilder();/// Ruft den übergeordneten Status des angegebenen Status ab./// Wenn state kein Unterstatus ist, wird false.public bool zurückgegeben GetParentStateOf(TState state, [NotNullWhen(true)] out TState? parentState);/// Holen Sie sich die übergeordnete Hierarchie des angegebenen Status. Wenn state kein Unterstatus ist, wird empty zurückgegeben.public ReadOnlySlice<TState> GetParentHierarchyOf(TState state);/// Ruft die Ereignisse ab, die vom angegebenen state akzeptiert werden.public ReadOnlySlice<TEvent> GetAcceptedEventsBy(TState state);/// Bestimmt wenn der aktuelle Zustand der angegebene Zustand oder ein (verschachtelter) Unterzustand dieses angegebenen Zustands ist.public bool IsInState(TState state);/// Ein Ereignis an den Zustandsautomaten auslösen./// Wenn der Zustandsautomat bereits einen Zustand auslöst, wird er zur Ausführung nach Abschluss des aktuellen Ereignisses eingereiht.public void Fire(TEvent @event);/// Ein Ereignis an die Zustandsmaschine auslösen./// Das Ereignis wird nicht in die Warteschlange gestellt, sondern tatsächlich ausgeführt, wobei zuvor in die Warteschlange gestellte Ereignisse ignoriert werden./// Wenn nachfolgende Ereignisse während der Ausführung der Rückrufe dieses Ereignisses in die Warteschlange gestellt werden, Sie werden auch nach Abschluss dieses Ereignisses ausgeführt.public void FireImmediately(TEvent @event);/// Führt die im aktuellen Status registrierten Update-Rückrufe aus.public void Update();/// Speichert einen oder mehrere Parameter, die Kann an abonnierte Delegaten übergeben werden.public ParametersBuilder With<T>(T-Parameter);public readonly struct ParametersBuilder{/// Speichert einen Parameter, der an callbacks.public ParametersBuilder übergeben werden kann With<TParameter>(TParameter-Parameter);/// Identisch mit Fire(TEvent) in der übergeordneten Klasse, enthält jedoch alle gespeicherten Werte, die an abonnierte Delegaten übergeben werden können.public void Fire(TEvent);/// Identisch mit FireImmediately(TEvent ) in der übergeordneten Klasse, enthält jedoch alle gespeicherten Werte, die an abonnierte Delegaten übergeben werden können.public void FireImmediately(TEvent);/// Identisch mit Update(TEvent) in der übergeordneten Klasse, enthält jedoch alle gespeicherten Werte, die übergeben werden können an abonnierte Delegates.public void Update(TEvent);}public readonly struct InitializeParametersBuilder{/// Speichert einen Parameter, der an callbacks.public InitializeParametersBuilder With<TParameter>(TParameter parameter);/// Erstellt den Zustand machine.public StateMachine<TState, TEvent, TRecipient> Create(TRecipient Receiver);}}öffentliche versiegelte Klasse StateMachineFactory<TState, TEvent, TRecipient>where TState : notnullwhere TEvent : notnull{/// Erstellt eine konfigurierte und initialisierte Zustandsmaschine unter Verwendung der von dieser Fabrik bereitgestellten Konfiguration.public StateMachine<TState, TEvent, TRecipient> Create(TRecipient Receiver);/// Speichert einen Parameter( s), die an abonnierte Delegaten übergeben werden können.public StateMachine<TState, TEvent, TRecipient>.InitializeParametersBuilder With<T>(T-Parameter);}öffentliche versiegelte Klasse StateMachineBuilder<TState, TEvent, TRecipient> : IFinalizablewhere TState : notnullwhere TEvent : notnull{/// Bestimmt den Anfangszustand der Zustandsmaschine./// `initializationPolicy` bestimmt, wie Abonnierte Delegaten für die OnEntry-Öfen des angegebenen Zustands (und der übergeordneten Zustände) werden während der Initialisierung des Zustands machine.public ausgeführt StateMachineBuilder<TState, TEvent, TRecipient> SetInitialState(TState state, ExecutionPolicy initializationPolicy = ExecutionPolicy.ChildFirst);/// Einen neuen Zustand hinzufügen oder einen zuvor hinzugefügten Zustand laden.public StateBuilder<TState, TEvent, TRecipient> In(TState state); /// Erstellt eine Factory unter Verwendung von builder.public als Konfiguration StateMachineFactory<TState, TEvent, TRecipient> Finalize();}öffentliche versiegelte Klasse StateBuilder<TState, TEvent, TRecipient> : IFinalizablewhere TState : notnullwhere TEvent : notnull{/// Leitet Aufruf an StateMachineBuilder<TState, TEvent, TRecipient> weiter.In( TState state).public StateBuilder<TState, TEvent, TRecipient> In(TState state);/// Leitet den Aufruf an StateMachineBuilder<TState, TEvent, TRecipient> weiter.Finalize();public StateMachineFactory<TState, TEvent, TRecipient> Finalize();/// Markiert diesen Zustand als Unterzustand des angegebenen state.public StateBuilder<TState, TEvent, TRecipient> IsSubStateOf(TState state);/// Bestimmt eine auszuführende Aktion beim Eintritt in diesen Zustand.public StateBuilder<TState, TEvent, TRecipient> OnEntry(Action action);/// Gleich wie OnEntry(Action), aber den Empfänger als Parameter übergeben.public StateBuilder<TState, TEvent, TRecipient> OnEntry(Action< TRecipient> action);/// Identisch mit OnEntry(Action), aber übergeben Sie alle während des Aufrufs übergebenen Parameter, die mit dem generischen Parametertyp übereinstimmen, an den Delegaten./// Wenn nein Wenn der mit dem angegebenen generischen Parameter übergebene Parameter gefunden wird, wird er ignoriert.public StateBuilder<TState, TEvent, TRecipient> OnEntry<TParameter>(Action<TParameter> action);/// Kombinierte Version von OnEntry(Action<TRecipient>) und OnEntry( Action<TParameter>).public StateBuilder<TState, TEvent, TRecipient> OnEntry<TParameter>(Action<TRecipient, TParameter> action);/// Bestimmt eine Aktion, die beim Verlassen dieses Zustands ausgeführt werden soll.public StateBuilder<TState, TEvent, TRecipient> OnExit(Action action);/// Gleich wie OnExit(Action), aber übergibt den Empfänger als Parameter.public StateBuilder <TState, TEvent, TRecipient> OnExit(Action<TRecipient> action);/// Gleich wie OnExit(Action), aber übergeben Sie alle dabei übergebenen Parameter an den Delegaten der Aufruf, der dem generischen Parametertyp entspricht./// Wenn kein mit dem angegebenen generischen Parameter übergebener Parameter gefunden wird, wird er ignoriert.public StateBuilder<TState, TEvent, TRecipient> OnExit<TParameter>(Action<TParameter> action);// / Kombinierte Version von OnExit(Action<TRecipient>) und OnExit(Action<TParameter>).public StateBuilder<TState, TEvent, TRecipient> OnExit<TParameter>(Action<TRecipient, TParameter> action);/// Bestimmt eine Aktion, die bei der Aktualisierung dieses Zustands ausgeführt werden soll.public StateBuilder<TState, TEvent, TRecipient> OnUpdate(Action action);/// Gleich wie OnUpdate( Aktion), aber übergeben Sie den Empfänger als Parameter.public StateBuilder<TState, TEvent, TRecipient> OnUpdate(Action<TRecipient> action);/// Das Gleiche wie OnUpdate(Action), aber übergeben Sie an den Delegaten alle während des Aufrufs übergebenen Parameter, die mit dem generischen Parameter type.public StateBuilder<TState, TEvent, TRecipient> OnUpdate<TParameter>(Action<TParameter> action);/// Kombinierte Version von OnUpdate übereinstimmen (Action<TRecipient>) und OnUpdate(Action<TParameter>)./// Wenn kein mit dem angegebenen generischen Parameter übergebener Parameter gefunden wird, wird er ignoriert.public StateBuilder<TState, TEvent, TRecipient> OnUpdate<TParameter>(Action<TRecipient, TParameter> action);/// Ein Verhalten hinzufügen, das während der Auslösung des angegebenen Ereignisses ausgeführt wird.public TransitionBuilder<TState, TEvent, TRecipient, StateBuilder<TState, TEvent, TRecipient>> On(TEvent @event);/// Ignoriert das angegebene Ereignis./// Wenn einem Ereignis kein Verhalten hinzugefügt und es ausgelöst wird, wird es ausgelöst werfen. Dies verhindert das Auslösen, indem der Aufruf überhaupt ignoriert wird.public StateBuilder<TState, TEvent, TRecipient> Ignore(TEvent @event);}public versiegelte Klasse TransitionBuilder<TState, TEvent, TRecipient, TParent> : IFinalizable, ITransitionBuilder<TState>wobei TState : notnullwhere TEvent: notnull{/// Fügen Sie einen Unterübergang hinzu, der ausgeführt wird, wenn der Delegat true.public zurückgibt TransitionBuilder<TState, TEvent, TRecipient, TransitionBuilder<TState, TEvent, TRecipient, TParent>> If(Func<bool> Guard);/// Gleich wie If(Func<bool>), aber übergeben Sie den Empfänger als Parameter.public TransitionBuilder< TState, TEvent, TRecipient, TransitionBuilder<TState, TEvent, TRecipient, TParent>> If(Func<TRecipient, bool> guard);/// Identisch mit If(Func<bool>), aber übergeben Sie an den Delegaten alle während des Aufrufs übergebenen Parameter, die mit dem generischen Parameter type.public TransitionBuilder<TState, TEvent, TRecipient, übereinstimmen. TransitionBuilder<TState, TEvent, TRecipient, TParent>> If<TParameter>(Func<TParameter, bool> Guard);/// Kombinierte Version von If(Func<TRecipient, bool>) und If(Func<TParameter, bool>).public TransitionBuilder<TState, TEvent, TRecipient, TransitionBuilder<TState, TEvent, TRecipient, TParent>> If<TParameter>(Func<TParameter, bool > Guard);/// Bestimmt eine Aktion, die ausgeführt werden soll, wenn das Ereignis ausgelöst wird.public TransitionBuilder<TState, TEvent, TRecipient, TParent> Do(Action action);/// Gleich wie Do(Action), aber übergeben Sie den Empfänger als Parameter.public TransitionBuilder<TState, TEvent, TRecipient, TParent> Do(Action<TRecipient> action);/// Gleiches wie Do(Action), aber alle während des Aufrufs übergebenen Parameter, die mit dem generischen Parametertyp übereinstimmen, werden an den Delegaten übergeben./// Wenn kein mit dem angegebenen generischen Parameter übergebener Parameter gefunden wird, wird er ignoriert.public TransitionBuilder<TState, TEvent, TRecipient, TParent> Do<TParameter>(Action<TParameter> action);/// Kombinierte Version von Do(Action<TRecipient>) und Do(Action<TParameter>).public TransitionBuilder<TState, TEvent , TRecipient, TParent> Do<TParameter>(Action<TRecipient, TParameter> action);/// Konfiguriert die Richtlinie, wie abonnierte Delegierte an on Entry Hook sollte ausgeführt werden./// Wenn diese Methode nicht ausgeführt wird, lautet die Standardrichtlinie TransitionPolicy.ParentFirstWithCulling.public GotoBuilder<TState, TEvent, TRecipient, TParent> OnEntryPolicy(TransitionPolicy Policy);/// Konfiguriert die Richtlinie, wie Abonnierte Delegaten für den Exit-Hook sollten ausgeführt werden./// Wenn diese Methode nicht ausgeführt wird, gilt die Standardrichtlinie TransitionPolicy.ChildFirstWithCulling.public GotoBuilder<TState, TEvent, TRecipient, TParent> OnExitPolicy(TransitionPolicy Policy);/// Bestimmt, in welchen Zustand dieser Übergang geht./// Dies ist äquivalent zu: OnEntryPolicy(TransitionPolicy.ChildFirstWithCulling).OnExitPolicy(TransitionPolicy .ParentFirstWithCulling).Goto(state).public TParent Goto(TState state);/// Bestimmt den Übergang zum aktuellen Status./// Wenn runParentsActions wahr ist: OnExit- und OnEntry-Aktionen des aktuellen Status (jedoch nicht der übergeordneten Status, falls der aktuelle Status ein Unterstatus ist) werden ausgeführt ./// Dies ist äquivalent zu OnEntryPolicy(TransitionPolicy.ChildFirstWithCullingInclusive).OnExitPolicy(TransitionPolicy.ParentFirstWithCullingInclusive).Goto(currentState)./// Wenn runParentActions falsch ist: OnExit- und OEntry-Aktionen des aktuellen Status (und übergeordneter Status, falls der aktuelle Status ein Unterstatus ist) werden ausgeführt ./// Dies ist äquivalent zu OnEntryPolicy(TransitionPolicy.ChildFirst).OnExitPolicy(TransitionPolicy.ParentFirst).Goto(currentState).public TParent GotoSelf(bool runParentsActions = false);/// Legt fest, dass es keinen Übergang in einen beliebigen Zustand gibt, also kein OnEntry- oder OnExit-Ereignis angehoben./// Dies ist äquivalent zu OnEntryPolicy(TransitionPolicy.Ignore).OnExitPolicy(TransitionPolicy.Ignore).GotoSelf().public TParent StaySelf();}public versiegelte Klasse GotoBuilder<TState, TEvent, TRecipient, TParent> : IGoto<TState>where TState : notnullwhere TEvent : notnull {/// Konfiguriert die Richtlinie, wie abonnierte Delegierte beim Einstiegs-Hook vorgehen sollte ausgeführt werden./// Wenn diese Methode nicht ausgeführt wird, lautet die Standardrichtlinie TransitionPolicy.ParentFirstWithCulling.public GotoBuilder<TState, TEvent, TRecipient, TParent> OnEntryPolicy(TransitionPolicy Policy);/// Konfiguriert die Richtlinie, wie abonnierte Delegaten an on-Exit-Hook sollte ausgeführt werden./// Wenn diese Methode nicht ausgeführt wird, ist die Standardrichtlinie TransitionPolicy.ChildrenFirstWithCulling.public GotoBuilder<TState, TEvent, TRecipient, TParent> OnExitPolicy(TransitionPolicy Policy);/// Bestimmt, in welchen Zustand dieser Übergang geht.public TParent Goto(TState state);/// Bestimmt, in den aktuellen Zustand überzugehen./// Dies ist eine Abkürzung von Goto(currentState).public TParent GotoSelf();}/// Bestimmt die Übergangsrichtlinie zwischen zwei Zuständen./// Dies Konfiguriert, wie abonnierte Delegaten für Zustände während des Übergangs zwischen Staaten ausgeführt werden.public enum TransitionPolicy{/// Legt fest, dass abonnierte Delegaten nicht ausgeführt werden sollen.Ignore = 0,/// Legt fest, dass abonnierte Delegaten für übergeordnete Staaten zuerst ausgeführt werden.ParentFirst = 1,/ // Bestimmt, dass abonnierte Delegaten für untergeordnete Elemente zuerst ausgeführt werden.ChildFirst = 2,/// Bestimmt, dass abonnierte Delegaten für übergeordnete Elemente zuerst vom letzten gemeinsamen übergeordneten Element (ausgenommen) ausgeführt werden zwischen den beiden Zuständen.ParentFirstWithCulling = 3,/// Bestimmt, dass abonnierte Delegaten für untergeordnete Elemente zuerst ausgeführt werden, bis das letzte gemeinsame übergeordnete Element zwischen den beiden Zuständen (ausgenommen) erreicht wird.ChildFirstWithCulling = 4,/// Bestimmt, dass abonnierte Delegaten für übergeordnete Elemente ausgeführt werden zuerst vom (einschließlich) des letzten gemeinsamen übergeordneten Elements zwischen den beiden Zuständen.ParentFirstWithCullingInclusive = 5,/// Legt fest, dass abonnierte Delegaten für untergeordnete Elemente zuerst ausgeführt werden, bis sie erreicht sind (einschließlich) des letzten gemeinsamen übergeordneten Elements zwischen den beiden Zuständen.ChildFirstWithCullingInclusive = 6,}/// Stellt ein Datensegment dar.public readonly struct ReadOnlySlice<T> : IReadOnlyList<T>{/// Ruft das am Index angegebene Element ab. public T this[int index] { get; }/// Holen Sie sich die Anzahl der Slice.public int Count { get; }/// Holen Sie sich einen <see cref="ReadOnlyMemory{T}"/> dieses Slice.public ReadOnlyMemory<T> Memory { get; }/// Holen Sie sich einen <see cref="ReadOnlySpan{T}"/> dieses Slice.public ReadOnlySpan<T> Span { get; }/// Den Enumerator des Slice abrufen.public Enumerator GetEnumerator();/// Enumerator von <see cref="ReadOnlySlice{T}"/>.public struct Enumerator: IEnumerator<T>{/// Aktuelles Element abrufen des enumerator.public T Current { get; }/// Geht zum nächsten Element von enumeration.public bool MoveNext();/// Setzt enumeration.public zurück void Reset();}}