You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,268 @@
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Workflow.Runtime.Hosting;
|
||||
|
||||
#endregion Using directives
|
||||
|
||||
namespace System.Workflow.Activities
|
||||
{
|
||||
[Serializable]
|
||||
internal class StateMachineExecutionState
|
||||
{
|
||||
#region Member Variables
|
||||
|
||||
internal const string StateMachineExecutionStateKey = "StateMachineExecutionState";
|
||||
private StateMachineSubscriptionManager _subscriptionManager;
|
||||
private Queue<StateMachineAction> _actions;
|
||||
private string _currentStateName;
|
||||
private string _previousStateName;
|
||||
private string _nextStateName;
|
||||
private bool _completed = false;
|
||||
private bool _queueLocked = false;
|
||||
private bool _schedulerBusy = false;
|
||||
|
||||
#endregion Member Variables
|
||||
|
||||
#region Properties
|
||||
|
||||
internal StateMachineSubscriptionManager SubscriptionManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return _subscriptionManager;
|
||||
}
|
||||
}
|
||||
|
||||
private Queue<StateMachineAction> Actions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_actions == null)
|
||||
_actions = new Queue<StateMachineAction>();
|
||||
return _actions;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool SchedulerBusy
|
||||
{
|
||||
get
|
||||
{
|
||||
return _schedulerBusy;
|
||||
}
|
||||
set
|
||||
{
|
||||
_schedulerBusy = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string CurrentStateName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentStateName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_currentStateName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string PreviousStateName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _previousStateName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_previousStateName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string NextStateName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nextStateName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_nextStateName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Completed
|
||||
{
|
||||
get
|
||||
{
|
||||
return _completed;
|
||||
}
|
||||
set
|
||||
{
|
||||
_completed = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasEnqueuedActions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Actions.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal StateMachineExecutionState(Guid instanceId)
|
||||
{
|
||||
_subscriptionManager = new StateMachineSubscriptionManager(this, instanceId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal void LockQueue()
|
||||
{
|
||||
_queueLocked = true;
|
||||
}
|
||||
|
||||
internal void EnqueueAction(StateMachineAction action)
|
||||
{
|
||||
Debug.Assert(!this._queueLocked);
|
||||
this.Actions.Enqueue(action);
|
||||
}
|
||||
|
||||
internal StateMachineAction DequeueAction()
|
||||
{
|
||||
StateMachineAction action = this.Actions.Dequeue();
|
||||
if (this.Actions.Count == 0)
|
||||
_queueLocked = false;
|
||||
return action;
|
||||
}
|
||||
|
||||
internal void ProcessActions(ActivityExecutionContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException("context");
|
||||
|
||||
if (this.SchedulerBusy)
|
||||
return;
|
||||
|
||||
StateActivity state = (StateActivity)context.Activity;
|
||||
|
||||
if (this.Actions.Count == 0)
|
||||
{
|
||||
this.SubscriptionManager.ProcessQueue(context);
|
||||
return;
|
||||
}
|
||||
|
||||
StateMachineAction action = this.Actions.Peek();
|
||||
while (action.StateName.Equals(state.QualifiedName))
|
||||
{
|
||||
action = DequeueAction();
|
||||
action.Execute(context);
|
||||
|
||||
// If the previous action just
|
||||
// requested something to the runtime
|
||||
// scheduler, then we quit, since
|
||||
// the scheduler takes precedence.
|
||||
// we'll pick up the processing of actions
|
||||
// after the scheduler return the control to us.
|
||||
if (this.SchedulerBusy)
|
||||
return;
|
||||
|
||||
if (this.Actions.Count == 0)
|
||||
break;
|
||||
|
||||
action = this.Actions.Peek();
|
||||
}
|
||||
|
||||
if (this.Actions.Count > 0)
|
||||
{
|
||||
StateActivity rootState = StateMachineHelpers.GetRootState(state);
|
||||
StateActivity nextActionState = StateMachineHelpers.FindDynamicStateByName(rootState, action.StateName);
|
||||
if (nextActionState == null)
|
||||
throw new InvalidOperationException(SR.GetInvalidStateMachineAction(action.StateName));
|
||||
|
||||
nextActionState.RaiseProcessActionEvent(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SubscriptionManager.ProcessQueue(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal void ProcessTransitionRequest(ActivityExecutionContext context)
|
||||
{
|
||||
if (String.IsNullOrEmpty(this.NextStateName))
|
||||
return;
|
||||
|
||||
StateActivity currentState = StateMachineHelpers.GetCurrentState(context);
|
||||
CalculateStateTransition(currentState, this.NextStateName);
|
||||
LockQueue();
|
||||
this.NextStateName = null;
|
||||
}
|
||||
|
||||
internal void CalculateStateTransition(StateActivity currentState, string targetStateName)
|
||||
{
|
||||
if (currentState == null)
|
||||
throw new ArgumentNullException("currentState");
|
||||
if (String.IsNullOrEmpty(targetStateName))
|
||||
throw new ArgumentNullException("targetStateName");
|
||||
|
||||
while (currentState != null && (currentState.QualifiedName.Equals(targetStateName) || !StateMachineHelpers.ContainsState(currentState, targetStateName)))
|
||||
{
|
||||
CloseStateAction action = new CloseStateAction(currentState.QualifiedName);
|
||||
this.Actions.Enqueue(action);
|
||||
currentState = currentState.Parent as StateActivity;
|
||||
}
|
||||
if (currentState == null)
|
||||
throw new InvalidOperationException(SR.GetUnableToTransitionToState(targetStateName));
|
||||
|
||||
while (!currentState.QualifiedName.Equals(targetStateName))
|
||||
{
|
||||
foreach (Activity childActivity in currentState.EnabledActivities)
|
||||
{
|
||||
StateActivity childState = childActivity as StateActivity;
|
||||
if (childState != null)
|
||||
{
|
||||
//
|
||||
if (StateMachineHelpers.ContainsState(childState, targetStateName))
|
||||
{
|
||||
ExecuteChildStateAction action = new ExecuteChildStateAction(currentState.QualifiedName, childState.QualifiedName);
|
||||
this.Actions.Enqueue(action);
|
||||
currentState = childState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!StateMachineHelpers.IsLeafState(currentState))
|
||||
throw new InvalidOperationException(SR.GetInvalidStateTransitionPath());
|
||||
}
|
||||
|
||||
#region Static Methods
|
||||
|
||||
internal static StateMachineExecutionState Get(StateActivity state)
|
||||
{
|
||||
Debug.Assert(StateMachineHelpers.IsRootState(state));
|
||||
StateMachineExecutionState executionState = (StateMachineExecutionState)state.GetValue(StateActivity.StateMachineExecutionStateProperty);
|
||||
Debug.Assert(executionState != null);
|
||||
return executionState;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user