Moved licensing classes to proper namespace; rethought the progression result design (removed outcome reporting entirely); Began implementation of a progression set class for grouping progressions
git-svn-id: file:///srv/devel/repo-conversion/nusu@10 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
2d145ca867
commit
f38a0bc1ea
|
@ -131,9 +131,9 @@
|
||||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||||
<Name>IAbortable</Name>
|
<Name>IAbortable</Name>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Source\Tracking\MultiProgression.cs">
|
<Compile Include="Source\Tracking\SetProgression.cs">
|
||||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||||
<Name>MultiProgression</Name>
|
<Name>SetProgression</Name>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Source\Tracking\Operation.cs">
|
<Compile Include="Source\Tracking\Operation.cs">
|
||||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||||
|
@ -155,6 +155,14 @@
|
||||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||||
<Name>ThreadedMethodOperation</Name>
|
<Name>ThreadedMethodOperation</Name>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\Tracking\WeightedProgression.cs">
|
||||||
|
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||||
|
<Name>WeightedProgression</Name>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Source\Tracking\WeightedProgressionCollection.cs">
|
||||||
|
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||||
|
<Name>WeightedProgressionCollection</Name>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Collections;
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Nuclex.Licensing {
|
namespace Nuclex.Support.Licensing {
|
||||||
|
|
||||||
/// <summary>Unit test for the license key class</summary>
|
/// <summary>Unit test for the license key class</summary>
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
@ -70,6 +70,6 @@ namespace Nuclex.Licensing {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Licensing
|
} // namespace Nuclex.Support.Licensing
|
||||||
|
|
||||||
#endif // UNITTEST
|
#endif // UNITTEST
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Nuclex.Licensing {
|
namespace Nuclex.Support.Licensing {
|
||||||
|
|
||||||
/// <summary>Typical license key with 5x5 alphanumerical characters</summary>
|
/// <summary>Typical license key with 5x5 alphanumerical characters</summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
@ -225,4 +225,4 @@ namespace Nuclex.Licensing {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Licensing
|
} // namespace Nuclex.Support.Licensing
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Nuclex.Support.Tracking {
|
|
||||||
|
|
||||||
public class MultiProgression<ProgressionType> : Progression
|
|
||||||
where ProgressionType : Progression {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Nuclex.Support.Tracking
|
|
|
@ -7,44 +7,9 @@ namespace Nuclex.Support.Tracking {
|
||||||
/// <summary>Base class for observable operations running in the background</summary>
|
/// <summary>Base class for observable operations running in the background</summary>
|
||||||
public abstract class Operation : Progression {
|
public abstract class Operation : Progression {
|
||||||
|
|
||||||
/// <summary>Possible outcomes of an operation</summary>
|
/// <summary>Executes the operation</summary>
|
||||||
public enum Outcomes {
|
public abstract void Execute();
|
||||||
/// <summary>The operation has not ended yet</summary>
|
|
||||||
Pending,
|
|
||||||
/// <summary>The operation has succeeded</summary>
|
|
||||||
Success,
|
|
||||||
/// <summary>The operation has failed</summary>
|
|
||||||
Failure,
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
/// <summary>Begins executing the operation</summary>
|
|
||||||
public abstract void BeginExecute();
|
|
||||||
|
|
||||||
public virtual void Execute() {
|
|
||||||
try {
|
|
||||||
BeginExecute();
|
|
||||||
this.outcome = EndExecute();
|
|
||||||
}
|
|
||||||
catch(Exception exception) {
|
|
||||||
this.outcome = Outcomes.Failure;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Ends the </summary>
|
|
||||||
public virtual Outcomes EndExecute() {
|
|
||||||
WaitHandle.WaitOne();
|
|
||||||
|
|
||||||
return this.outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>The Outcome of the operation when it has finished</summary>
|
|
||||||
public Outcomes Outcome {
|
|
||||||
get { return this.outcome; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Outcome of the operation</summary>
|
|
||||||
protected Outcomes outcome;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Support.Tracking
|
} // namespace Nuclex.Support.Tracking
|
||||||
|
|
|
@ -10,13 +10,13 @@ namespace Nuclex.Support.Tracking {
|
||||||
/// a background thread in a class that's derived from Progression you can wait
|
/// 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
|
/// for the completion of the operation and receive feedback on the achieved
|
||||||
/// progress. This is useful for displaying a progress bar, loading screen or
|
/// progress. This is useful for displaying a progress bar, loading screen or
|
||||||
/// some means of entertaining the user while he waits for the operation to
|
/// 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
|
/// complete. It is also possible to register callbacks which will be fired once
|
||||||
/// the progression has ended.
|
/// the progression has ended.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// This class deliberately does not provide an Execute() or similar method to
|
/// This class deliberately does not provide an Execute() method or anything similar
|
||||||
/// clearly seperate the initiation of an operation from just monitoring it.
|
/// to clearly seperate the initiation of an operation from just monitoring it.
|
||||||
/// By omitting an Execute() method, it also becomes possible to construct a
|
/// By omitting an Execute() method, it also becomes possible to construct a
|
||||||
/// progression just-in-time when it is explicitely asked for.
|
/// progression just-in-time when it is explicitely asked for.
|
||||||
/// </para>
|
/// </para>
|
||||||
|
@ -53,20 +53,27 @@ namespace Nuclex.Support.Tracking {
|
||||||
|
|
||||||
/// <summary>Whether the progression has ended already</summary>
|
/// <summary>Whether the progression has ended already</summary>
|
||||||
public virtual bool Ended {
|
public virtual bool Ended {
|
||||||
get { return ended; }
|
get { return this.ended; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>WaitHandle that can be used to wait for the progression to end</summary>
|
/// <summary>WaitHandle that can be used to wait for the progression to end</summary>
|
||||||
public WaitHandle WaitHandle {
|
public WaitHandle WaitHandle {
|
||||||
get {
|
get {
|
||||||
lock(this) {
|
|
||||||
|
|
||||||
// The WaitHandle will only be created when someone asks for it!
|
// The WaitHandle will only be created when someone asks for it!
|
||||||
|
// See the Double-Check Locking idiom on why the condition is checked twice
|
||||||
|
// (primarily, it avoids an expensive lock when it isn't needed)
|
||||||
|
if(this.doneEvent == null) {
|
||||||
|
|
||||||
|
lock(this.syncRoot) {
|
||||||
|
|
||||||
if(this.doneEvent == null)
|
if(this.doneEvent == null)
|
||||||
this.doneEvent = new ManualResetEvent(this.ended);
|
this.doneEvent = new ManualResetEvent(this.ended);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return this.doneEvent;
|
return this.doneEvent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,9 +109,9 @@ namespace Nuclex.Support.Tracking {
|
||||||
/// seperately.
|
/// seperately.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected virtual void OnAsyncEnded() {
|
protected virtual void OnAsyncEnded() {
|
||||||
lock(this) {
|
this.ended = true;
|
||||||
ended = true;
|
|
||||||
|
|
||||||
|
lock(this.syncRoot) {
|
||||||
if(this.doneEvent != null)
|
if(this.doneEvent != null)
|
||||||
this.doneEvent.Set();
|
this.doneEvent.Set();
|
||||||
}
|
}
|
||||||
|
@ -114,6 +121,8 @@ namespace Nuclex.Support.Tracking {
|
||||||
copy(this, EventArgs.Empty);
|
copy(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Used to synchronize multithreaded accesses to this object</summary>
|
||||||
|
private object syncRoot = new object();
|
||||||
/// <summary>Event that will be set when the progression is completed</summary>
|
/// <summary>Event that will be set when the progression is completed</summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This event is will only be created when it is specifically asked for using
|
/// This event is will only be created when it is specifically asked for using
|
||||||
|
|
24
Source/Tracking/SetProgression.cs
Normal file
24
Source/Tracking/SetProgression.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Nuclex.Support.Collections;
|
||||||
|
|
||||||
|
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
|
||||||
|
where ProgressionType : Progression {
|
||||||
|
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public class SetOperation<OperationType> : Operation
|
||||||
|
where OperationType : OperationType
|
||||||
|
|
||||||
|
QueueOperation
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Tracking
|
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Nuclex.Support.Tracking {
|
namespace Nuclex.Support.Tracking {
|
||||||
|
/*
|
||||||
public class ThreadedMethodOperation : Operation {
|
public class ThreadedMethodOperation : Operation {
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} // namespace Nuclex.Support.Tracking
|
} // namespace Nuclex.Support.Tracking
|
||||||
|
|
74
Source/Tracking/WeightedProgression.cs
Normal file
74
Source/Tracking/WeightedProgression.cs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Tracking {
|
||||||
|
|
||||||
|
/// <summary>Progression with an associated weight for the total progress</summary>
|
||||||
|
internal class WeightedProgression<ProgressionType> : IDisposable
|
||||||
|
where ProgressionType : Progression {
|
||||||
|
|
||||||
|
/// <summary>Initializes a new weighted progression</summary>
|
||||||
|
/// <param name="callback">Callback to pass progress updates on to</param>
|
||||||
|
/// <param name="progression">Progression whose progress to monitor</param>
|
||||||
|
/// <param name="weight">Weighting of the progression's progress</param>
|
||||||
|
public WeightedProgression(
|
||||||
|
ProgressionType progression,
|
||||||
|
EventHandler<ProgressUpdateEventArgs> callback,
|
||||||
|
float weight
|
||||||
|
) {
|
||||||
|
this.progression = progression;
|
||||||
|
this.weight = weight;
|
||||||
|
this.callback = callback;
|
||||||
|
|
||||||
|
progression.AsyncProgressUpdated += new EventHandler<ProgressUpdateEventArgs>(
|
||||||
|
asyncProgressUpdated
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Disposes of the resources used by this instance immediately</summary>
|
||||||
|
public void Dispose() {
|
||||||
|
if(this.progression != null) {
|
||||||
|
progression.AsyncProgressUpdated -= new EventHandler<ProgressUpdateEventArgs>(
|
||||||
|
asyncProgressUpdated
|
||||||
|
);
|
||||||
|
this.progression = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Progression being wrapped by this weighted progression</summary>
|
||||||
|
public ProgressionType Progression {
|
||||||
|
get { return this.progression; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Progress this progression has achieved so far</summary>
|
||||||
|
public float Progress {
|
||||||
|
get { return this.progress; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>The weighting of this progression in the total progress</summary>
|
||||||
|
public float Weight {
|
||||||
|
get { return this.weight; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Handles progress reports by the progression</summary>
|
||||||
|
/// <param name="sender">Progression that has made progress</param>
|
||||||
|
/// <param name="e">Contains the currently achieved progress</param>
|
||||||
|
private void asyncProgressUpdated(object sender, ProgressUpdateEventArgs e) {
|
||||||
|
this.progress = e.Progress;
|
||||||
|
this.callback(sender, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Progression whose progress we're tracking</summary>
|
||||||
|
private ProgressionType progression;
|
||||||
|
/// <summary>Callback to which any progress reports will be passed on</summary>
|
||||||
|
private EventHandler<ProgressUpdateEventArgs> callback;
|
||||||
|
/// <summary>Most recent progress reported by the progression</summary>
|
||||||
|
private volatile float progress;
|
||||||
|
/// <summary>Weighting of this progression in the total progress</summary>
|
||||||
|
private float weight;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Tracking
|
13
Source/Tracking/WeightedProgressionCollection.cs
Normal file
13
Source/Tracking/WeightedProgressionCollection.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Nuclex.Support.Collections;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Tracking {
|
||||||
|
|
||||||
|
internal class WeightedProgressionCollection<ProgressionType>
|
||||||
|
: ObservableCollection<WeightedProgression<ProgressionType>>
|
||||||
|
where ProgressionType : Progression { }
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Tracking
|
Loading…
Reference in New Issue
Block a user