// Thread safe cursor creation public MyStateMachineCursor(MyStateMachineNode node, MyStateMachine stateMachine) { m_stateMachine = stateMachine; Id = Interlocked.Increment(ref m_idCounter); m_node = node; m_node.Cursors.Add(this); OnCursorStateChanged = null; }
// Update the state machine, try changing state. public void Update() { if (CurrentNode == null) { m_enqueuedActions.Clear(); return; } int maxPassThrough = 100; MyStateMachineNode nextNode; do { nextNode = null; int transitionId = -1; // enqueued transitions (actions) first if (m_enqueuedActions.Count > 0) { int bestPriority = int.MaxValue; foreach (var transition in CurrentNode.Transitions) { int transitionPriority = transition.Priority ?? int.MaxValue; if (transitionPriority <= bestPriority && m_enqueuedActions.Contains(transition.Name) && (transition.Conditions.Count == 0 || transition.Evaluate())) { transitionId = transition.Id; nextNode = transition.TargetNode; bestPriority = transitionPriority; } } } // transitions checking conditions if (nextNode == null) { nextNode = CurrentNode.QueryNewState(false, out transitionId); } // now try to transfer from one state to another if (nextNode != null) { //var fromNode = CurrentNode; var transitionWithStart = m_transitions[transitionId]; CurrentNode = nextNode; NotifyStateChanged(transitionWithStart); } } while (nextNode != null && // we changed state CurrentNode.PassThrough && // we want to pass through maxPassThrough-- > 0); // safety, prevent infinite loop caused by wrong data m_enqueuedActions.Clear(); if (CurrentNode != null) { CurrentNode.OnUpdate(this); } }
// ------------------------------------------------------------------------------------ #region Node manipulation // Add new node. Node can be instance of MyStateMachineNode subclass. // Parameter must not be null. // Returns false on failure (name collision). public bool AddNode(MyStateMachineNode newNode) { Debug.Assert(newNode != null, "Node added to state machine cannot be null."); if (FindNode(newNode.Name) != null) { Debug.Assert(false, "State machine '" + Name + "' already contains node having name '" + newNode.Name + "'."); return(false); } m_nodes.Add(newNode.Name, newNode); return(true); }
// ------------------------------------------------------------------------------------ #region Node manipulation // Add new node. Node can be instance of MyStateMachineNode subclass. // Parameter must not be null. // Returns false on failure (name collision). public bool AddNode(MyStateMachineNode newNode) { Debug.Assert(newNode != null, "Node added to state machine cannot be null."); if (FindNode(newNode.Name) != null) { Debug.Assert(false, "State machine '" + Name + "' already contains node having name '" + newNode.Name + "'."); return false; } m_nodes.Add(newNode.Name, newNode); return true; }
// ------------------------------------------------------------------------------------ /// <summary> /// Set the current state. Warning - this is not a thing that you would like to normally do, /// state machine should live its own life (based on transition condition). /// Returns true on success. /// </summary> public virtual bool SetState(string nameOfNewState) { var newState = FindNode(nameOfNewState); if (newState != null) { CurrentNode = newState; return(true); } else { return(false); } }
// Update the state machine, try changing state. public void Update() { if (CurrentNode == null) { return; } int transitionId = -1; MyStateMachineNode nextNode = null; // enqueued transitions (actions) first if (m_enqueuedActions.Count > 0) { foreach (var transition in CurrentNode.Transitions) { if (m_enqueuedActions.Contains(transition.Name)) { transitionId = transition.Id; nextNode = transition.TargetNode; break; } } m_enqueuedActions.Clear(); } // transitions checking conditions if (nextNode == null) { nextNode = CurrentNode.QueryNewState(out transitionId); } // now try to transfer from one state to another if (nextNode != null) { //var fromNode = CurrentNode; var transitionWithStart = m_transitions[transitionId]; CurrentNode = nextNode; NotifyStateChanged(transitionWithStart); } if (CurrentNode != null) { CurrentNode.OnUpdate(this); } }
// Update the state machine, try changing state. public void Update() { if (CurrentNode == null) { m_enqueuedActions.Clear(); return; } int maxPassThrough = 100; MyStateMachineNode nextNode; do { nextNode = null; int transitionId = -1; // enqueued transitions (actions) first if (m_enqueuedActions.Count > 0) { int bestPriority = int.MaxValue; foreach (var transition in CurrentNode.Transitions) { int transitionPriority = transition.Priority ?? int.MaxValue; if (transitionPriority <= bestPriority && m_enqueuedActions.Contains(transition.Name)) { transitionId = transition.Id; nextNode = transition.TargetNode; bestPriority = transitionPriority; } } } // transitions checking conditions if (nextNode == null) { nextNode = CurrentNode.QueryNewState(out transitionId); } // now try to transfer from one state to another if (nextNode != null) { //var fromNode = CurrentNode; var transitionWithStart = m_transitions[transitionId]; CurrentNode = nextNode; NotifyStateChanged(transitionWithStart); } } while (nextNode != null // we changed state && CurrentNode.PassThrough // we want to pass through && maxPassThrough-- > 0); // safety, prevent infinite loop caused by wrong data m_enqueuedActions.Clear(); if (CurrentNode != null) CurrentNode.OnUpdate(this); }
// ------------------------------------------------------------------------------------ /// <summary> /// Set the current state. Warning - this is not a thing that you would like to normally do, /// state machine should live its own life (based on transition condition). /// Returns true on success. /// </summary> public virtual bool SetState(string nameOfNewState) { var newState = FindNode(nameOfNewState); if (newState != null) { CurrentNode = newState; return true; } else { return false; } }
// Update the state machine, try changing state. public void Update() { if (CurrentNode == null) return; int transitionId = -1; MyStateMachineNode nextNode = null; // enqueued transitions (actions) first if (m_enqueuedActions.Count > 0) { foreach (var transition in CurrentNode.Transitions) if (m_enqueuedActions.Contains(transition.Name)) { transitionId = transition.Id; nextNode = transition.TargetNode; break; } m_enqueuedActions.Clear(); } // transitions checking conditions if (nextNode == null) { nextNode = CurrentNode.QueryNewState(out transitionId); } // now try to transfer from one state to another if (nextNode != null) { //var fromNode = CurrentNode; var transitionWithStart = m_transitions[transitionId]; CurrentNode = nextNode; NotifyStateChanged(transitionWithStart); } if (CurrentNode != null) CurrentNode.OnUpdate(this); }
/// <summary> /// Full constructor. /// </summary> public MyStateMachineTransitionWithStart(MyStateMachineNode startNode, MyStateMachineTransition transition) { StartNode = startNode; Transition = transition; }