171 lines
6.0 KiB
C#
171 lines
6.0 KiB
C#
|
//------------------------------------------------------------------------------
|
|||
|
// <copyright file="StateMachineEventManager.cs" company="Microsoft">
|
|||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
// </copyright>
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
|
|||
|
namespace System.Activities.Statements
|
|||
|
{
|
|||
|
using System;
|
|||
|
using System.Activities;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Collections.ObjectModel;
|
|||
|
using System.Diagnostics.CodeAnalysis;
|
|||
|
using System.Globalization;
|
|||
|
using System.Linq;
|
|||
|
using System.Runtime.Serialization;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// StateMachineEventManager is used to manage triggered events globally.
|
|||
|
/// </summary>
|
|||
|
[SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
|
|||
|
Justification = "This type is actually used in LINQ expression and FxCop didn't detect that.")]
|
|||
|
[DataContract]
|
|||
|
class StateMachineEventManager
|
|||
|
{
|
|||
|
// To avoid out of memory, set a fixed length of event queue.
|
|||
|
const int MaxQueueLength = 1 << 25;
|
|||
|
|
|||
|
// queue is used to store triggered events
|
|||
|
Queue<TriggerCompletedEvent> queue;
|
|||
|
|
|||
|
// If a state is running, its condition evaluation bookmark will be added in to activityBookmarks.
|
|||
|
// If a state is completed, its bookmark will be removed.
|
|||
|
Collection<Bookmark> activeBookmarks;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Constructor to do initialization.
|
|||
|
/// </summary>
|
|||
|
public StateMachineEventManager()
|
|||
|
{
|
|||
|
this.queue = new Queue<TriggerCompletedEvent>();
|
|||
|
this.activeBookmarks = new Collection<Bookmark>();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets or sets the trigger index of current being processed event.
|
|||
|
/// </summary>
|
|||
|
[DataMember(EmitDefaultValue = false)]
|
|||
|
public TriggerCompletedEvent CurrentBeingProcessedEvent
|
|||
|
{
|
|||
|
get;
|
|||
|
set;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets or sets the CurrentConditionIndex denotes the index of condition is being evaluated.
|
|||
|
/// </summary>
|
|||
|
[DataMember(EmitDefaultValue = false)]
|
|||
|
public int CurrentConditionIndex
|
|||
|
{
|
|||
|
get;
|
|||
|
set;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets or sets a value indicating whether StateMachine is on the way of transition.
|
|||
|
/// </summary>
|
|||
|
[DataMember(EmitDefaultValue = false)]
|
|||
|
public bool OnTransition
|
|||
|
{
|
|||
|
get;
|
|||
|
set;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets the EventManager queue.
|
|||
|
/// </summary>
|
|||
|
public IEnumerable<TriggerCompletedEvent> Queue
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return this.queue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets a value indicating whether StateMachineManger is ready to process an event immediately.
|
|||
|
/// </summary>
|
|||
|
bool CanProcessEventImmediately
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return this.CurrentBeingProcessedEvent == null && !this.OnTransition && this.queue.Count == 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[DataMember(EmitDefaultValue = false, Name = "queue")]
|
|||
|
internal Queue<TriggerCompletedEvent> SerializedQueue
|
|||
|
{
|
|||
|
get { return this.queue; }
|
|||
|
set { this.queue = value; }
|
|||
|
}
|
|||
|
|
|||
|
[DataMember(EmitDefaultValue = false, Name = "activeBookmarks")]
|
|||
|
internal Collection<Bookmark> SerializedActiveBookmarks
|
|||
|
{
|
|||
|
get { return this.activeBookmarks; }
|
|||
|
set { this.activeBookmarks = value; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// When StateMachine enters a state, condition evaluation bookmark of that state would be added to activeBookmarks collection.
|
|||
|
/// </summary>
|
|||
|
/// <param name="bookmark">Bookmark reference.</param>
|
|||
|
public void AddActiveBookmark(Bookmark bookmark)
|
|||
|
{
|
|||
|
this.activeBookmarks.Add(bookmark);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets next completed events queue.
|
|||
|
/// </summary>
|
|||
|
/// <returns>Top TriggerCompletedEvent item in the queue.</returns>
|
|||
|
public TriggerCompletedEvent GetNextCompletedEvent()
|
|||
|
{
|
|||
|
while (this.queue.Any())
|
|||
|
{
|
|||
|
TriggerCompletedEvent completedEvent = this.queue.Dequeue();
|
|||
|
if (this.activeBookmarks.Contains(completedEvent.Bookmark))
|
|||
|
{
|
|||
|
this.CurrentBeingProcessedEvent = completedEvent;
|
|||
|
return completedEvent;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This method is used to denote whether a given bookmark is referred by currently processed event.
|
|||
|
/// </summary>
|
|||
|
/// <param name="bookmark">Bookmark reference.</param>
|
|||
|
/// <returns>True is the bookmark references to the event being processed.</returns>
|
|||
|
public bool IsReferredByBeingProcessedEvent(Bookmark bookmark)
|
|||
|
{
|
|||
|
return this.CurrentBeingProcessedEvent != null && this.CurrentBeingProcessedEvent.Bookmark == bookmark;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Register a completed event and returns whether the event could be processed immediately.
|
|||
|
/// </summary>
|
|||
|
/// <param name="completedEvent">TriggerCompletedEvent reference.</param>
|
|||
|
/// <param name="canBeProcessedImmediately">True if the Condition can be evaluated.</param>
|
|||
|
public void RegisterCompletedEvent(TriggerCompletedEvent completedEvent, out bool canBeProcessedImmediately)
|
|||
|
{
|
|||
|
canBeProcessedImmediately = this.CanProcessEventImmediately;
|
|||
|
this.queue.Enqueue(completedEvent);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// When StateMachine leaves a state, condition evaluation bookmark of that state would be removed from activeBookmarks collection.
|
|||
|
/// </summary>
|
|||
|
/// <param name="bookmark">Bookmark reference.</param>
|
|||
|
public void RemoveActiveBookmark(Bookmark bookmark)
|
|||
|
{
|
|||
|
this.activeBookmarks.Remove(bookmark);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|