Maze / Library /PackageCache /com.unity.visualscripting@1.8.0 /Runtime /VisualScripting.State /State.cs
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using UnityEngine; | |
| namespace Unity.VisualScripting | |
| { | |
| public abstract class State : GraphElement<StateGraph>, IState | |
| { | |
| public class Data : IGraphElementData | |
| { | |
| public bool isActive; | |
| public bool hasEntered; | |
| } | |
| public class DebugData : IStateDebugData | |
| { | |
| public int lastEnterFrame { get; set; } | |
| public float lastExitTime { get; set; } | |
| public Exception runtimeException { get; set; } | |
| } | |
| public IGraphElementData CreateData() | |
| { | |
| return new Data(); | |
| } | |
| public IGraphElementDebugData CreateDebugData() | |
| { | |
| return new DebugData(); | |
| } | |
| [] | |
| public bool isStart { get; set; } | |
| [] | |
| public virtual bool canBeSource => true; | |
| [] | |
| public virtual bool canBeDestination => true; | |
| public override void BeforeRemove() | |
| { | |
| base.BeforeRemove(); | |
| Disconnect(); | |
| } | |
| public override void Instantiate(GraphReference instance) | |
| { | |
| base.Instantiate(instance); | |
| var data = instance.GetElementData<Data>(this); | |
| if (this is IGraphEventListener listener && data.isActive) | |
| { | |
| listener.StartListening(instance); | |
| } | |
| else if (isStart && !data.hasEntered && graph.IsListening(instance)) | |
| { | |
| using (var flow = Flow.New(instance)) | |
| { | |
| OnEnter(flow, StateEnterReason.Start); | |
| } | |
| } | |
| } | |
| public override void Uninstantiate(GraphReference instance) | |
| { | |
| if (this is IGraphEventListener listener) | |
| { | |
| listener.StopListening(instance); | |
| } | |
| base.Uninstantiate(instance); | |
| } | |
| protected void CopyFrom(State source) | |
| { | |
| base.CopyFrom(source); | |
| isStart = source.isStart; | |
| width = source.width; | |
| } | |
| public IEnumerable<IStateTransition> outgoingTransitions => graph?.transitions.WithSource(this) ?? Enumerable.Empty<IStateTransition>(); | |
| public IEnumerable<IStateTransition> incomingTransitions => graph?.transitions.WithDestination(this) ?? Enumerable.Empty<IStateTransition>(); | |
| protected List<IStateTransition> outgoingTransitionsNoAlloc => graph?.transitions.WithSourceNoAlloc(this) ?? Empty<IStateTransition>.list; | |
| public IEnumerable<IStateTransition> transitions => LinqUtility.Concat<IStateTransition>(outgoingTransitions, incomingTransitions); | |
| public void Disconnect() | |
| { | |
| foreach (var transition in transitions.ToArray()) | |
| { | |
| graph.transitions.Remove(transition); | |
| } | |
| } | |
| public virtual void OnEnter(Flow flow, StateEnterReason reason) | |
| { | |
| var data = flow.stack.GetElementData<Data>(this); | |
| if (data.isActive) // Prevent re-entry from Any State | |
| { | |
| return; | |
| } | |
| data.isActive = true; | |
| data.hasEntered = true; | |
| foreach (var transition in outgoingTransitionsNoAlloc) | |
| { | |
| // Start listening for the transition's events | |
| // before entering the state in case OnEnterState | |
| // actually instantly triggers a transition via event | |
| // http://support.ludiq.io/topics/261-event-timing-issue/ | |
| (transition as IGraphEventListener)?.StartListening(flow.stack); | |
| } | |
| if (flow.enableDebug) | |
| { | |
| var editorData = flow.stack.GetElementDebugData<DebugData>(this); | |
| editorData.lastEnterFrame = EditorTimeBinding.frame; | |
| } | |
| OnEnterImplementation(flow); | |
| foreach (var transition in outgoingTransitionsNoAlloc) | |
| { | |
| try | |
| { | |
| transition.OnEnter(flow); | |
| } | |
| catch (Exception ex) | |
| { | |
| transition.HandleException(flow.stack, ex); | |
| throw; | |
| } | |
| } | |
| } | |
| public virtual void OnExit(Flow flow, StateExitReason reason) | |
| { | |
| var data = flow.stack.GetElementData<Data>(this); | |
| if (!data.isActive) | |
| { | |
| return; | |
| } | |
| OnExitImplementation(flow); | |
| data.isActive = false; | |
| if (flow.enableDebug) | |
| { | |
| var editorData = flow.stack.GetElementDebugData<DebugData>(this); | |
| editorData.lastExitTime = EditorTimeBinding.time; | |
| } | |
| foreach (var transition in outgoingTransitionsNoAlloc) | |
| { | |
| try | |
| { | |
| transition.OnExit(flow); | |
| } | |
| catch (Exception ex) | |
| { | |
| transition.HandleException(flow.stack, ex); | |
| throw; | |
| } | |
| } | |
| } | |
| protected virtual void OnEnterImplementation(Flow flow) { } | |
| protected virtual void UpdateImplementation(Flow flow) { } | |
| protected virtual void FixedUpdateImplementation(Flow flow) { } | |
| protected virtual void LateUpdateImplementation(Flow flow) { } | |
| protected virtual void OnExitImplementation(Flow flow) { } | |
| public virtual void OnBranchTo(Flow flow, IState destination) { } | |
| public const float DefaultWidth = 170; | |
| [] | |
| public Vector2 position { get; set; } | |
| [] | |
| public float width { get; set; } = DefaultWidth; | |
| public override AnalyticsIdentifier GetAnalyticsIdentifier() | |
| { | |
| var aid = new AnalyticsIdentifier | |
| { | |
| Identifier = GetType().FullName, | |
| Namespace = GetType().Namespace, | |
| }; | |
| aid.Hashcode = aid.Identifier.GetHashCode(); | |
| return aid; | |
| } | |
| } | |
| } | |