Renamed ProgressUpdated event to ProgressChanged in order to conform with the status report naming convention; removed progress reporting from the Progression class; moved progress reporting into its own interface which is now optional to implement for any background task; renamed Progression to Waitable since it no longer has anything to do with progress; fixed unit tests
git-svn-id: file:///srv/devel/repo-conversion/nusu@64 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
1161ef8f25
commit
7dbfc3c422
|
@ -147,9 +147,10 @@
|
|||
<Compile Include="Source\Tracking\IdleStateEventArgs.cs" />
|
||||
<Compile Include="Source\Tracking\Internal\ObservedWeightedProgression.cs" />
|
||||
<Compile Include="Source\Tracking\Internal\WeightedProgressionWrapperCollection.cs" />
|
||||
<Compile Include="Source\Tracking\IProgressReporter.cs" />
|
||||
<Compile Include="Source\Tracking\IStatusReporter.cs" />
|
||||
<Compile Include="Source\Tracking\Request.cs" />
|
||||
<Compile Include="Source\Tracking\Progression.cs" />
|
||||
<Compile Include="Source\Tracking\Waitable.cs" />
|
||||
<Compile Include="Source\Tracking\ProgressionTracker.cs" />
|
||||
<Compile Include="Source\Tracking\ProgressionTracker.Test.cs">
|
||||
<DependentUpon>ProgressionTracker.cs</DependentUpon>
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// <summary>Called when the queue operations's progress changes</summary>
|
||||
/// <param name="sender">Queue operation whose progress has changed</param>
|
||||
/// <param name="e">Contains the new progress achieved</param>
|
||||
void ProgressUpdated(object sender, ProgressUpdateEventArgs e);
|
||||
void ProgressChanged(object sender, ProgressReportEventArgs e);
|
||||
|
||||
/// <summary>Called when the queue operation has ended</summary>
|
||||
/// <param name="sender">Queue operation that as ended</param>
|
||||
|
@ -61,7 +61,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
|
||||
/// <summary>Initializes a new ProgressUpdateEventArgsMatcher </summary>
|
||||
/// <param name="expected">Expected progress update event arguments</param>
|
||||
public ProgressUpdateEventArgsMatcher(ProgressUpdateEventArgs expected) {
|
||||
public ProgressUpdateEventArgsMatcher(ProgressReportEventArgs expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// True if the actual value matches the expected value; otherwise false
|
||||
/// </returns>
|
||||
public override bool Matches(object actualAsObject) {
|
||||
ProgressUpdateEventArgs actual = (actualAsObject as ProgressUpdateEventArgs);
|
||||
ProgressReportEventArgs actual = (actualAsObject as ProgressReportEventArgs);
|
||||
if(actual == null)
|
||||
return false;
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
}
|
||||
|
||||
/// <summary>Expected progress update event args value</summary>
|
||||
private ProgressUpdateEventArgs expected;
|
||||
private ProgressReportEventArgs expected;
|
||||
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,10 @@ namespace Nuclex.Support.Scheduling {
|
|||
#region class TestOperation
|
||||
|
||||
/// <summary>Progression used for testing in this unit test</summary>
|
||||
private class TestOperation : Operation {
|
||||
private class TestOperation : Operation, IProgressReporter {
|
||||
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressChanged;
|
||||
|
||||
/// <summary>Begins executing the operation. Yeah, sure :)</summary>
|
||||
public override void Start() { }
|
||||
|
@ -118,7 +121,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// New progress to be reported by the testing progression
|
||||
/// </param>
|
||||
public void ChangeProgress(float progress) {
|
||||
OnAsyncProgressUpdated(progress);
|
||||
OnAsyncProgressChanged(progress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -130,6 +133,29 @@ namespace Nuclex.Support.Scheduling {
|
|||
throw this.exception;
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressChanged;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
/// <summary>Exception that has occured in the background process</summary>
|
||||
private volatile Exception exception;
|
||||
|
||||
|
@ -159,22 +185,22 @@ namespace Nuclex.Support.Scheduling {
|
|||
testQueueOperation.Start();
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(QueueOperation<TestOperation>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.25f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.25f))
|
||||
}
|
||||
);
|
||||
|
||||
operation1.ChangeProgress(0.5f);
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(QueueOperation<TestOperation>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.5f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.5f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -191,8 +217,8 @@ namespace Nuclex.Support.Scheduling {
|
|||
this.mockery.NewMock<IQueueOperationSubscriber>();
|
||||
|
||||
operation.AsyncEnded += new EventHandler(mockedSubscriber.Ended);
|
||||
operation.AsyncProgressUpdated +=
|
||||
new EventHandler<ProgressUpdateEventArgs>(mockedSubscriber.ProgressUpdated);
|
||||
(operation as IProgressReporter).AsyncProgressChanged +=
|
||||
new EventHandler<ProgressReportEventArgs>(mockedSubscriber.ProgressChanged);
|
||||
|
||||
return mockedSubscriber;
|
||||
}
|
||||
|
|
|
@ -32,15 +32,8 @@ namespace Nuclex.Support.Scheduling {
|
|||
public class QueueOperation<OperationType> : Operation
|
||||
where OperationType : Operation {
|
||||
|
||||
/// <summary>Initializes a new queue operation</summary>
|
||||
private QueueOperation() {
|
||||
this.asyncOperationEndedDelegate = new EventHandler(asyncOperationEnded);
|
||||
this.asyncOperationProgressUpdatedDelegate = new EventHandler<ProgressUpdateEventArgs>(
|
||||
asyncOperationProgressUpdated
|
||||
);
|
||||
|
||||
this.children = new List<WeightedProgression<OperationType>>();
|
||||
}
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressUpdated;
|
||||
|
||||
/// <summary>Initializes a new queue operation with default weights</summary>
|
||||
/// <param name="childs">Child operations to execute in this operation</param>
|
||||
|
@ -74,6 +67,16 @@ namespace Nuclex.Support.Scheduling {
|
|||
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new queue operation</summary>
|
||||
private QueueOperation() {
|
||||
this.asyncOperationEndedDelegate = new EventHandler(asyncOperationEnded);
|
||||
this.asyncOperationProgressChangedDelegate = new EventHandler<ProgressReportEventArgs>(
|
||||
asyncOperationProgressChanged
|
||||
);
|
||||
|
||||
this.children = new List<WeightedProgression<OperationType>>();
|
||||
}
|
||||
|
||||
/// <summary>Provides access to the child operations of this queue</summary>
|
||||
public IList<WeightedProgression<OperationType>> Children {
|
||||
get { return this.children; }
|
||||
|
@ -93,6 +96,29 @@ namespace Nuclex.Support.Scheduling {
|
|||
throw this.exception;
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressUpdated;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
/// <summary>Prepares the current operation and calls its Begin() method</summary>
|
||||
/// <remarks>
|
||||
/// This subscribes the queue to the events of to the current operation
|
||||
|
@ -102,7 +128,10 @@ namespace Nuclex.Support.Scheduling {
|
|||
OperationType operation = this.children[this.currentOperationIndex].Progression;
|
||||
|
||||
operation.AsyncEnded += this.asyncOperationEndedDelegate;
|
||||
operation.AsyncProgressUpdated += this.asyncOperationProgressUpdatedDelegate;
|
||||
|
||||
IProgressReporter progressReporter = operation as IProgressReporter;
|
||||
if(progressReporter != null)
|
||||
progressReporter.AsyncProgressChanged += this.asyncOperationProgressChangedDelegate;
|
||||
|
||||
operation.Start();
|
||||
}
|
||||
|
@ -118,7 +147,10 @@ namespace Nuclex.Support.Scheduling {
|
|||
|
||||
// Disconnect from the operation's events
|
||||
operation.AsyncEnded -= this.asyncOperationEndedDelegate;
|
||||
operation.AsyncProgressUpdated -= this.asyncOperationProgressUpdatedDelegate;
|
||||
|
||||
IProgressReporter progressReporter = operation as IProgressReporter;
|
||||
if(progressReporter != null)
|
||||
progressReporter.AsyncProgressChanged -= this.asyncOperationProgressChangedDelegate;
|
||||
|
||||
try {
|
||||
operation.Join();
|
||||
|
@ -127,7 +159,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
this.completedWeight += this.children[this.currentOperationIndex].Weight;
|
||||
|
||||
// Trigger another progress update
|
||||
OnAsyncProgressUpdated(this.completedWeight / this.totalWeight);
|
||||
OnAsyncProgressChanged(this.completedWeight / this.totalWeight);
|
||||
}
|
||||
catch(Exception exception) {
|
||||
this.exception = exception;
|
||||
|
@ -165,7 +197,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// <summary>Called when currently executing operation makes progress</summary>
|
||||
/// <param name="sender">Operation that has achieved progress</param>
|
||||
/// <param name="e">Not used</param>
|
||||
private void asyncOperationProgressUpdated(object sender, ProgressUpdateEventArgs e) {
|
||||
private void asyncOperationProgressChanged(object sender, ProgressReportEventArgs e) {
|
||||
|
||||
// Determine the completed weight of the currently executing operation
|
||||
float currentOperationCompletedWeight =
|
||||
|
@ -176,14 +208,14 @@ namespace Nuclex.Support.Scheduling {
|
|||
(this.completedWeight + currentOperationCompletedWeight) / this.totalWeight;
|
||||
|
||||
// Done, we can send the actual progress to any event subscribers
|
||||
OnAsyncProgressUpdated(progress);
|
||||
OnAsyncProgressChanged(progress);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Delegate to the asyncOperationEnded() method</summary>
|
||||
private EventHandler asyncOperationEndedDelegate;
|
||||
/// <summary>Delegate to the asyncOperationProgressUpdated() method</summary>
|
||||
private EventHandler<ProgressUpdateEventArgs> asyncOperationProgressUpdatedDelegate;
|
||||
private EventHandler<ProgressReportEventArgs> asyncOperationProgressChangedDelegate;
|
||||
/// <summary>Operations being managed in the queue</summary>
|
||||
private List<WeightedProgression<OperationType>> children;
|
||||
/// <summary>Summed weight of all operations in the queue</summary>
|
||||
|
|
34
Source/Tracking/IProgressReporter.cs
Normal file
34
Source/Tracking/IProgressReporter.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
#region CPL License
|
||||
/*
|
||||
Nuclex Framework
|
||||
Copyright (C) 2002-2008 Nuclex Development Labs
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the IBM Common Public License as
|
||||
published by the IBM Corporation; either version 1.0 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
IBM Common Public License for more details.
|
||||
|
||||
You should have received a copy of the IBM Common Public
|
||||
License along with this library
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Nuclex.Support.Tracking {
|
||||
|
||||
/// <summary>Interface for processes that report their progress</summary>
|
||||
public interface IProgressReporter {
|
||||
|
||||
/// <summary>Triggered when the status of the process changes</summary>
|
||||
event EventHandler<ProgressReportEventArgs> AsyncProgressChanged;
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Support.Tracking
|
|
@ -27,7 +27,7 @@ namespace Nuclex.Support.Tracking {
|
|||
public interface IStatusReporter {
|
||||
|
||||
/// <summary>Triggered when the status of the process changes</summary>
|
||||
event EventHandler<StatusReportEventArgs> StatusChanged;
|
||||
event EventHandler<StatusReportEventArgs> AsyncStatusChanged;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// Type of the progression that is being observed
|
||||
/// </typeparam>
|
||||
internal class ObservedWeightedProgression<ProgressionType> : IDisposable
|
||||
where ProgressionType : Progression {
|
||||
where ProgressionType : Waitable {
|
||||
|
||||
/// <summary>Delegate for reporting progress updates</summary>
|
||||
public delegate void ReportDelegate();
|
||||
|
@ -69,8 +69,16 @@ namespace Nuclex.Support.Tracking {
|
|||
if(weightedProgression.Progression.Ended) {
|
||||
this.progress = 1.0f;
|
||||
} else {
|
||||
this.weightedProgression.Progression.AsyncProgressUpdated +=
|
||||
new EventHandler<ProgressUpdateEventArgs>(asyncProgressUpdated);
|
||||
this.progressReporter = this.weightedProgression.Progression as IProgressReporter;
|
||||
|
||||
if(this.progressReporter != null) {
|
||||
this.asyncProgressChangedEventHandler = new EventHandler<ProgressReportEventArgs>(
|
||||
asyncProgressChanged
|
||||
);
|
||||
|
||||
this.progressReporter.AsyncProgressChanged +=
|
||||
this.asyncProgressChangedEventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -119,7 +127,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Called when the progress of the observed progression changes</summary>
|
||||
/// <param name="sender">Progression whose progress has changed</param>
|
||||
/// <param name="e">Contains the updated progress</param>
|
||||
private void asyncProgressUpdated(object sender, ProgressUpdateEventArgs e) {
|
||||
private void asyncProgressChanged(object sender, ProgressReportEventArgs e) {
|
||||
this.progress = e.Progress;
|
||||
this.progressUpdateCallback();
|
||||
}
|
||||
|
@ -138,8 +146,12 @@ namespace Nuclex.Support.Tracking {
|
|||
this.weightedProgression.Progression.AsyncEnded -=
|
||||
new EventHandler(asyncEnded);
|
||||
|
||||
this.weightedProgression.Progression.AsyncProgressUpdated -=
|
||||
new EventHandler<ProgressUpdateEventArgs>(asyncProgressUpdated);
|
||||
if(this.progressReporter != null) {
|
||||
this.progressReporter.AsyncProgressChanged -=
|
||||
this.asyncProgressChangedEventHandler;
|
||||
|
||||
this.asyncProgressChangedEventHandler = null;
|
||||
}
|
||||
|
||||
this.endedCallback = null;
|
||||
this.progressUpdateCallback = null;
|
||||
|
@ -150,6 +162,9 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
}
|
||||
|
||||
private EventHandler<ProgressReportEventArgs> asyncProgressChangedEventHandler;
|
||||
/// <summary>The observed progression's progress reporting interface</summary>
|
||||
private IProgressReporter progressReporter;
|
||||
/// <summary>The weighted progression that is being observed</summary>
|
||||
private WeightedProgression<ProgressionType> weightedProgression;
|
||||
/// <summary>Callback to invoke when the progress updates</summary>
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Nuclex.Support.Tracking {
|
|||
TransformingReadOnlyCollection<
|
||||
ObservedWeightedProgression<ProgressionType>, WeightedProgression<ProgressionType>
|
||||
>
|
||||
where ProgressionType : Progression {
|
||||
where ProgressionType : Waitable {
|
||||
|
||||
/// <summary>Initializes a new weighted progression collection wrapper</summary>
|
||||
/// <param name="items">Items to be exposed as weighted progressions</param>
|
||||
|
|
|
@ -24,11 +24,11 @@ using System.Collections.Generic;
|
|||
namespace Nuclex.Support.Tracking {
|
||||
|
||||
/// <summary>Event arguments for a progress update notification</summary>
|
||||
public class ProgressUpdateEventArgs : EventArgs {
|
||||
public class ProgressReportEventArgs : EventArgs {
|
||||
|
||||
/// <summary>Initializes the progress update informations</summary>
|
||||
/// <param name="progress">Achieved progress ranging from 0.0 to 1.0</param>
|
||||
public ProgressUpdateEventArgs(float progress) {
|
||||
public ProgressReportEventArgs(float progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Called when the progression tracker's progress changes</summary>
|
||||
/// <param name="sender">Progression tracker whose progress has changed</param>
|
||||
/// <param name="e">Contains the new progress achieved</param>
|
||||
void ProgressUpdated(object sender, ProgressUpdateEventArgs e);
|
||||
void ProgressUpdated(object sender, ProgressReportEventArgs e);
|
||||
|
||||
/// <summary>Called when the progression tracker's idle state changes</summary>
|
||||
/// <param name="sender">Progression tracker whose idle state has changed</param>
|
||||
|
@ -59,7 +59,7 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
/// <summary>Initializes a new ProgressUpdateEventArgsMatcher </summary>
|
||||
/// <param name="expected">Expected progress update event arguments</param>
|
||||
public ProgressUpdateEventArgsMatcher(ProgressUpdateEventArgs expected) {
|
||||
public ProgressUpdateEventArgsMatcher(ProgressReportEventArgs expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// True if the actual value matches the expected value; otherwise false
|
||||
/// </returns>
|
||||
public override bool Matches(object actualAsObject) {
|
||||
ProgressUpdateEventArgs actual = (actualAsObject as ProgressUpdateEventArgs);
|
||||
ProgressReportEventArgs actual = (actualAsObject as ProgressReportEventArgs);
|
||||
if(actual == null)
|
||||
return false;
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace Nuclex.Support.Tracking {
|
|||
}
|
||||
|
||||
/// <summary>Expected progress update event args value</summary>
|
||||
private ProgressUpdateEventArgs expected;
|
||||
private ProgressReportEventArgs expected;
|
||||
|
||||
}
|
||||
|
||||
|
@ -94,14 +94,17 @@ namespace Nuclex.Support.Tracking {
|
|||
#region class TestProgression
|
||||
|
||||
/// <summary>Progression used for testing in this unit test</summary>
|
||||
private class TestProgression : Progression {
|
||||
private class TestProgression : Waitable {
|
||||
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressChanged;
|
||||
|
||||
/// <summary>Changes the testing progression's indicated progress</summary>
|
||||
/// <param name="progress">
|
||||
/// New progress to be reported by the testing progression
|
||||
/// </param>
|
||||
public void ChangeProgress(float progress) {
|
||||
OnAsyncProgressUpdated(progress);
|
||||
OnAsyncProgressChanged(progress);
|
||||
}
|
||||
|
||||
/// <summary>Transitions the progression into the ended state</summary>
|
||||
|
@ -109,6 +112,29 @@ namespace Nuclex.Support.Tracking {
|
|||
OnAsyncEnded();
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressChanged;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion // class TestProgression
|
||||
|
@ -135,7 +161,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.0f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.0f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -149,7 +175,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.25f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.25f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -181,7 +207,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.0f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.0f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -195,7 +221,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.25f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.25f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -206,7 +232,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.75f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.75f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -220,7 +246,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(1.0f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(1.0f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -243,7 +269,7 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
IProgressionTrackerSubscriber mockedSubscriber = mockSubscriber(tracker);
|
||||
|
||||
tracker.Track(Progression.EndedDummy);
|
||||
tracker.Track(Waitable.EndedDummy);
|
||||
|
||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||
}
|
||||
|
@ -267,7 +293,7 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.0f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.0f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -279,18 +305,18 @@ namespace Nuclex.Support.Tracking {
|
|||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.5f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.5f))
|
||||
}
|
||||
);
|
||||
|
||||
tracker.Track(Progression.EndedDummy);
|
||||
tracker.Track(Waitable.EndedDummy);
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(ProgressionTracker)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(1.0f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(1.0f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -316,7 +342,7 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
tracker.AsyncIdleStateChanged +=
|
||||
(EventHandler<IdleStateEventArgs>)delegate(object sender, IdleStateEventArgs arguments) {
|
||||
tracker.Track(Progression.EndedDummy);
|
||||
tracker.Track(Waitable.EndedDummy);
|
||||
};
|
||||
|
||||
test1.End();
|
||||
|
@ -333,7 +359,7 @@ namespace Nuclex.Support.Tracking {
|
|||
new EventHandler<IdleStateEventArgs>(mockedSubscriber.IdleStateChanged);
|
||||
|
||||
tracker.AsyncProgressUpdated +=
|
||||
new EventHandler<ProgressUpdateEventArgs>(mockedSubscriber.ProgressUpdated);
|
||||
new EventHandler<ProgressReportEventArgs>(mockedSubscriber.ProgressUpdated);
|
||||
|
||||
return mockedSubscriber;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// the specified progression
|
||||
/// </summary>
|
||||
/// <param name="toMatch">Progression to match against</param>
|
||||
public ProgressionMatcher(Progression toMatch) {
|
||||
public ProgressionMatcher(Waitable toMatch) {
|
||||
this.toMatch = toMatch;
|
||||
}
|
||||
|
||||
|
@ -59,12 +59,12 @@ namespace Nuclex.Support.Tracking {
|
|||
/// progression of the instance
|
||||
/// </summary>
|
||||
/// <param name="other">Progression to match to the comparison progression</param>
|
||||
public bool Matches(ObservedWeightedProgression<Progression> other) {
|
||||
public bool Matches(ObservedWeightedProgression<Waitable> other) {
|
||||
return ReferenceEquals(other.WeightedProgression.Progression, this.toMatch);
|
||||
}
|
||||
|
||||
/// <summary>Progression this instance compares against</summary>
|
||||
private Progression toMatch;
|
||||
private Waitable toMatch;
|
||||
|
||||
}
|
||||
|
||||
|
@ -80,18 +80,18 @@ namespace Nuclex.Support.Tracking {
|
|||
public event EventHandler<IdleStateEventArgs> AsyncIdleStateChanged;
|
||||
|
||||
/// <summary>Triggered when the total progress has changed</summary>
|
||||
public event EventHandler<ProgressUpdateEventArgs> AsyncProgressUpdated;
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressUpdated;
|
||||
|
||||
/// <summary>Initializes a new progression tracker</summary>
|
||||
public ProgressionTracker() {
|
||||
|
||||
this.trackedProgressions = new List<ObservedWeightedProgression<Progression>>();
|
||||
this.trackedProgressions = new List<ObservedWeightedProgression<Waitable>>();
|
||||
this.idle = true;
|
||||
|
||||
this.asyncEndedDelegate =
|
||||
new ObservedWeightedProgression<Progression>.ReportDelegate(asyncEnded);
|
||||
new ObservedWeightedProgression<Waitable>.ReportDelegate(asyncEnded);
|
||||
this.asyncProgressUpdatedDelegate =
|
||||
new ObservedWeightedProgression<Progression>.ReportDelegate(asyncProgressUpdated);
|
||||
new ObservedWeightedProgression<Waitable>.ReportDelegate(asyncProgressUpdated);
|
||||
|
||||
}
|
||||
|
||||
|
@ -115,14 +115,14 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
/// <summary>Begins tracking the specified progression</summary>
|
||||
/// <param name="progression">Progression to be tracked</param>
|
||||
public void Track(Progression progression) {
|
||||
public void Track(Waitable progression) {
|
||||
Track(progression, 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>Begins tracking the specified progression</summary>
|
||||
/// <param name="progression">Progression to be tracked</param>
|
||||
/// <param name="weight">Weight to assign to this progression</param>
|
||||
public void Track(Progression progression, float weight) {
|
||||
public void Track(Waitable progression, float weight) {
|
||||
|
||||
// Add the new progression into the tracking list. This has to be done
|
||||
// inside a lock to prevent issues with the progressUpdate callback, which could
|
||||
|
@ -150,8 +150,8 @@ namespace Nuclex.Support.Tracking {
|
|||
// receive them. The lock eliminates the risk of processing a progress update
|
||||
// before the progression has been added to the tracked progressions list.
|
||||
this.trackedProgressions.Add(
|
||||
new ObservedWeightedProgression<Progression>(
|
||||
new WeightedProgression<Progression>(progression, weight),
|
||||
new ObservedWeightedProgression<Waitable>(
|
||||
new WeightedProgression<Waitable>(progression, weight),
|
||||
this.asyncProgressUpdatedDelegate,
|
||||
this.asyncEndedDelegate
|
||||
)
|
||||
|
@ -167,9 +167,9 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
// Construct a new progression observer and add the progression to our
|
||||
// list of tracked progressions.
|
||||
ObservedWeightedProgression<Progression> observedProgression =
|
||||
new ObservedWeightedProgression<Progression>(
|
||||
new WeightedProgression<Progression>(progression, weight),
|
||||
ObservedWeightedProgression<Waitable> observedProgression =
|
||||
new ObservedWeightedProgression<Waitable>(
|
||||
new WeightedProgression<Waitable>(progression, weight),
|
||||
this.asyncProgressUpdatedDelegate,
|
||||
this.asyncEndedDelegate
|
||||
);
|
||||
|
@ -202,12 +202,12 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
/// <summary>Stops tracking the specified progression</summary>
|
||||
/// <param name="progression">Progression to stop tracking of</param>
|
||||
public void Untrack(Progression progression) {
|
||||
public void Untrack(Waitable progression) {
|
||||
lock(this.trackedProgressions) {
|
||||
|
||||
// Locate the object to be untracked in our collection
|
||||
int removeIndex = this.trackedProgressions.FindIndex(
|
||||
new Predicate<ObservedWeightedProgression<Progression>>(
|
||||
new Predicate<ObservedWeightedProgression<Waitable>>(
|
||||
new ProgressionMatcher(progression).Matches
|
||||
)
|
||||
);
|
||||
|
@ -216,7 +216,7 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
// Remove and dispose the progression the user wants to untrack
|
||||
{
|
||||
ObservedWeightedProgression<Progression> wrappedProgression =
|
||||
ObservedWeightedProgression<Waitable> wrappedProgression =
|
||||
this.trackedProgressions[removeIndex];
|
||||
|
||||
this.trackedProgressions.RemoveAt(removeIndex);
|
||||
|
@ -266,9 +266,9 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Fires the AsyncProgressUpdated event</summary>
|
||||
/// <param name="progress">New progress to report</param>
|
||||
protected virtual void OnAsyncProgressUpdated(float progress) {
|
||||
EventHandler<ProgressUpdateEventArgs> copy = AsyncProgressUpdated;
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressUpdated;
|
||||
if(copy != null)
|
||||
copy(this, new ProgressUpdateEventArgs(progress));
|
||||
copy(this, new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Recalculates the total progress of the tracker</summary>
|
||||
|
@ -351,11 +351,11 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Total weight of all progressions being tracked</summary>
|
||||
private volatile float totalWeight;
|
||||
/// <summary>Progressions being tracked by this tracker</summary>
|
||||
private List<ObservedWeightedProgression<Progression>> trackedProgressions;
|
||||
private List<ObservedWeightedProgression<Waitable>> trackedProgressions;
|
||||
/// <summary>Delegate for the asyncEnded() method</summary>
|
||||
private ObservedWeightedProgression<Progression>.ReportDelegate asyncEndedDelegate;
|
||||
private ObservedWeightedProgression<Waitable>.ReportDelegate asyncEndedDelegate;
|
||||
/// <summary>Delegate for the asyncProgressUpdated() method</summary>
|
||||
private ObservedWeightedProgression<Progression>.ReportDelegate asyncProgressUpdatedDelegate;
|
||||
private ObservedWeightedProgression<Waitable>.ReportDelegate asyncProgressUpdatedDelegate;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// OnAsyncEnded(), no matter what the outcome of your background operation is.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public abstract class Request : Progression {
|
||||
public abstract class Request : Waitable {
|
||||
|
||||
#region class EndedDummyRequest
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Called when the set progression's progress changes</summary>
|
||||
/// <param name="sender">Set progression whose progress has changed</param>
|
||||
/// <param name="e">Contains the new progress achieved</param>
|
||||
void ProgressUpdated(object sender, ProgressUpdateEventArgs e);
|
||||
void ProgressChanged(object sender, ProgressReportEventArgs e);
|
||||
|
||||
/// <summary>Called when the set progression has ended</summary>
|
||||
/// <param name="sender">Set progression that as ended</param>
|
||||
|
@ -59,7 +59,7 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
/// <summary>Initializes a new ProgressUpdateEventArgsMatcher </summary>
|
||||
/// <param name="expected">Expected progress update event arguments</param>
|
||||
public ProgressUpdateEventArgsMatcher(ProgressUpdateEventArgs expected) {
|
||||
public ProgressUpdateEventArgsMatcher(ProgressReportEventArgs expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// True if the actual value matches the expected value; otherwise false
|
||||
/// </returns>
|
||||
public override bool Matches(object actualAsObject) {
|
||||
ProgressUpdateEventArgs actual = (actualAsObject as ProgressUpdateEventArgs);
|
||||
ProgressReportEventArgs actual = (actualAsObject as ProgressReportEventArgs);
|
||||
if(actual == null)
|
||||
return false;
|
||||
|
||||
|
@ -85,23 +85,26 @@ namespace Nuclex.Support.Tracking {
|
|||
}
|
||||
|
||||
/// <summary>Expected progress update event args value</summary>
|
||||
private ProgressUpdateEventArgs expected;
|
||||
private ProgressReportEventArgs expected;
|
||||
|
||||
}
|
||||
|
||||
#endregion // class ProgressUpdateEventArgsMatcher
|
||||
|
||||
#region class TestProgression
|
||||
#region class TestWaitable
|
||||
|
||||
/// <summary>Progression used for testing in this unit test</summary>
|
||||
private class TestProgression : Progression {
|
||||
private class TestWaitable : Waitable, IProgressReporter {
|
||||
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressChanged;
|
||||
|
||||
/// <summary>Changes the testing progression's indicated progress</summary>
|
||||
/// <param name="progress">
|
||||
/// New progress to be reported by the testing progression
|
||||
/// </param>
|
||||
public void ChangeProgress(float progress) {
|
||||
OnAsyncProgressUpdated(progress);
|
||||
OnAsyncProgressChanged(progress);
|
||||
}
|
||||
|
||||
/// <summary>Transitions the progression into the ended state</summary>
|
||||
|
@ -109,9 +112,32 @@ namespace Nuclex.Support.Tracking {
|
|||
OnAsyncEnded();
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
#endregion // class TestProgression
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressChanged;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion // class TestWaitable
|
||||
|
||||
/// <summary>Initialization routine executed before each test is run</summary>
|
||||
[SetUp]
|
||||
|
@ -122,19 +148,19 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Validates that the set progression properly sums the progress</summary>
|
||||
[Test]
|
||||
public void TestSummedProgress() {
|
||||
SetProgression<TestProgression> testSetProgression =
|
||||
new SetProgression<TestProgression>(
|
||||
new TestProgression[] { new TestProgression(), new TestProgression() }
|
||||
SetProgression<TestWaitable> testSetProgression =
|
||||
new SetProgression<TestWaitable>(
|
||||
new TestWaitable[] { new TestWaitable(), new TestWaitable() }
|
||||
);
|
||||
|
||||
ISetProgressionSubscriber mockedSubscriber = mockSubscriber(testSetProgression);
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(SetProgression<TestProgression>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.25f))
|
||||
new NMock2.Matchers.TypeMatcher(typeof(SetProgression<TestWaitable>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.25f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -146,33 +172,33 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Validates that the set progression respects the weights</summary>
|
||||
[Test]
|
||||
public void TestWeightedSummedProgress() {
|
||||
SetProgression<TestProgression> testSetProgression =
|
||||
new SetProgression<TestProgression>(
|
||||
new WeightedProgression<TestProgression>[] {
|
||||
new WeightedProgression<TestProgression>(new TestProgression(), 1.0f),
|
||||
new WeightedProgression<TestProgression>(new TestProgression(), 2.0f)
|
||||
SetProgression<TestWaitable> testSetProgression =
|
||||
new SetProgression<TestWaitable>(
|
||||
new WeightedProgression<TestWaitable>[] {
|
||||
new WeightedProgression<TestWaitable>(new TestWaitable(), 1.0f),
|
||||
new WeightedProgression<TestWaitable>(new TestWaitable(), 2.0f)
|
||||
}
|
||||
);
|
||||
|
||||
ISetProgressionSubscriber mockedSubscriber = mockSubscriber(testSetProgression);
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(SetProgression<TestProgression>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.5f / 3.0f))
|
||||
new NMock2.Matchers.TypeMatcher(typeof(SetProgression<TestWaitable>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.5f / 3.0f))
|
||||
}
|
||||
);
|
||||
|
||||
testSetProgression.Children[0].Progression.ChangeProgress(0.5f);
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(SetProgression<TestProgression>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.5f))
|
||||
new NMock2.Matchers.TypeMatcher(typeof(SetProgression<TestWaitable>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.5f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -186,9 +212,9 @@ namespace Nuclex.Support.Tracking {
|
|||
/// </summary>
|
||||
[Test]
|
||||
public void TestEndedEvent() {
|
||||
SetProgression<TestProgression> testSetProgression =
|
||||
new SetProgression<TestProgression>(
|
||||
new TestProgression[] { new TestProgression(), new TestProgression() }
|
||||
SetProgression<TestWaitable> testSetProgression =
|
||||
new SetProgression<TestWaitable>(
|
||||
new TestWaitable[] { new TestWaitable(), new TestWaitable() }
|
||||
);
|
||||
|
||||
ISetProgressionSubscriber mockedSubscriber = mockSubscriber(testSetProgression);
|
||||
|
@ -210,13 +236,13 @@ namespace Nuclex.Support.Tracking {
|
|||
/// <summary>Mocks a subscriber for the events of a progression</summary>
|
||||
/// <param name="progression">Progression to mock an event subscriber for</param>
|
||||
/// <returns>The mocked event subscriber</returns>
|
||||
private ISetProgressionSubscriber mockSubscriber(Progression progression) {
|
||||
private ISetProgressionSubscriber mockSubscriber(Waitable progression) {
|
||||
ISetProgressionSubscriber mockedSubscriber =
|
||||
this.mockery.NewMock<ISetProgressionSubscriber>();
|
||||
|
||||
progression.AsyncEnded += new EventHandler(mockedSubscriber.Ended);
|
||||
progression.AsyncProgressUpdated +=
|
||||
new EventHandler<ProgressUpdateEventArgs>(mockedSubscriber.ProgressUpdated);
|
||||
(progression as IProgressReporter).AsyncProgressChanged +=
|
||||
new EventHandler<ProgressReportEventArgs>(mockedSubscriber.ProgressChanged);
|
||||
|
||||
return mockedSubscriber;
|
||||
}
|
||||
|
|
|
@ -28,13 +28,11 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
/// <summary>Forms a single progression from a set of progressions</summary>
|
||||
/// <typeparam name="ProgressionType">Type of progressions to manage as a set</typeparam>
|
||||
public class SetProgression<ProgressionType> : Progression, IDisposable
|
||||
where ProgressionType : Progression {
|
||||
public class SetProgression<ProgressionType> : Waitable, IDisposable, IProgressReporter
|
||||
where ProgressionType : Waitable {
|
||||
|
||||
/// <summary>Performs common initialization for the public constructors</summary>
|
||||
private SetProgression() {
|
||||
this.children = new List<ObservedWeightedProgression<ProgressionType>>();
|
||||
}
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressChanged;
|
||||
|
||||
/// <summary>Initializes a new set progression</summary>
|
||||
/// <param name="childs">Progressions to track with this set</param>
|
||||
|
@ -85,6 +83,11 @@ namespace Nuclex.Support.Tracking {
|
|||
|
||||
}
|
||||
|
||||
/// <summary>Performs common initialization for the public constructors</summary>
|
||||
private SetProgression() {
|
||||
this.children = new List<ObservedWeightedProgression<ProgressionType>>();
|
||||
}
|
||||
|
||||
/// <summary>Immediately releases all resources owned by the object</summary>
|
||||
public void Dispose() {
|
||||
|
||||
|
@ -124,6 +127,29 @@ namespace Nuclex.Support.Tracking {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressChanged;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the progress of one of the observed progressions changes
|
||||
/// </summary>
|
||||
|
@ -142,7 +168,7 @@ namespace Nuclex.Support.Tracking {
|
|||
totalProgress /= this.totalWeight;
|
||||
|
||||
// Send out the progress update
|
||||
OnAsyncProgressUpdated(totalProgress);
|
||||
OnAsyncProgressChanged(totalProgress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -23,33 +23,34 @@ using System.Threading;
|
|||
|
||||
namespace Nuclex.Support.Tracking {
|
||||
|
||||
/// <summary>Base class for actions that give an indication of their progress</summary>
|
||||
/// <summary>Base class for actions on which that give an indication of their progress</summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// By encapsulating long-running operations which will ideally be running in
|
||||
/// a background thread in a class that's derived from Progression you can wait
|
||||
/// for the completion of the operation and receive feedback on the achieved
|
||||
/// progress. This is useful for displaying a progress bar, loading screen or
|
||||
/// some other means of entertaining the user while he waits for the operation to
|
||||
/// complete. It is also possible to register callbacks which will be fired once
|
||||
/// the progression has ended.
|
||||
/// a background thread in a class that's derived from <see cref="Waitable" />
|
||||
/// you can wait for the completion of the operation and optionally even receive
|
||||
/// feedback on the achieved progress. This is useful for displaying a progress
|
||||
/// bar, loading screen or some other means of entertaining the user while he
|
||||
/// waits for the task to complete.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This class deliberately does not provide an Execute() method or anything similar
|
||||
/// to clearly seperate the initiation of an operation from just monitoring it.
|
||||
/// By omitting an Execute() method, it also becomes possible to construct a
|
||||
/// progression just-in-time when it is explicitely asked for.
|
||||
/// You can register callbacks which will be fired once the <see cref="Waitable" />
|
||||
/// task has completed. This class deliberately does not provide an Execute()
|
||||
/// method or anything similar to clearly seperate the initiation of an operation
|
||||
/// from just monitoring it. By omitting an Execute() method, it also becomes
|
||||
/// possible to construct a progression just-in-time when it is explicitely being
|
||||
/// asked for.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public abstract class Progression {
|
||||
public abstract class Waitable {
|
||||
|
||||
#region class EndedDummyProgression
|
||||
|
||||
/// <summary>Dummy progression which always is in the 'ended' state</summary>
|
||||
private class EndedDummyProgression : Progression {
|
||||
private class EndedDummyWaitable : Waitable {
|
||||
|
||||
/// <summary>Initializes a new ended dummy progression</summary>
|
||||
public EndedDummyProgression() {
|
||||
public EndedDummyWaitable() {
|
||||
OnAsyncEnded();
|
||||
}
|
||||
|
||||
|
@ -63,10 +64,7 @@ namespace Nuclex.Support.Tracking {
|
|||
/// when a progression that's lazily created is accessed after the original
|
||||
/// operation has ended already.
|
||||
/// </remarks>
|
||||
public static readonly Progression EndedDummy = new EndedDummyProgression();
|
||||
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressUpdateEventArgs> AsyncProgressUpdated;
|
||||
public static readonly Waitable EndedDummy = new EndedDummyWaitable();
|
||||
|
||||
/// <summary>Will be triggered when the progression has ended</summary>
|
||||
public event EventHandler AsyncEnded;
|
||||
|
@ -102,29 +100,6 @@ namespace Nuclex.Support.Tracking {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressUpdated(float progress) {
|
||||
OnAsyncProgressUpdated(new ProgressUpdateEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressUpdated(ProgressUpdateEventArgs eventArguments) {
|
||||
EventHandler<ProgressUpdateEventArgs> copy = AsyncProgressUpdated;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
/// <summary>Fires the AsyncEnded event</summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
|
@ -24,7 +24,7 @@ using System.Collections.Generic;
|
|||
namespace Nuclex.Support.Tracking {
|
||||
|
||||
/// <summary>Progression with an associated weight for the total progress</summary>
|
||||
public class WeightedProgression<ProgressionType> where ProgressionType : Progression {
|
||||
public class WeightedProgression<ProgressionType> where ProgressionType : Waitable {
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new weighted progression with a default weight of 1.0
|
||||
|
|
Loading…
Reference in New Issue
Block a user