using System; using System.IO; using Chernobyl.DesignPatterns.Command; namespace Chernobyl.Resources { /// /// An that holds onto resource /// processing requests until it is told to let them through using the /// or /// methods. /// /// The type of the resource. public class WaitResourceProcessor : ResourceProcessor { /// /// Initializes a new instance of the /// class. /// public WaitResourceProcessor() { FromCommands = new CommandCollection(); ToCommands = new CommandCollection(); } /// /// Allows all of the previously stopped processing requests to be handled. /// public void AllowThrough() { AreBeingAllowedThrough = true; FromCommands.Execute(); FromCommands.Clear(); ToCommands.Execute(); ToCommands.Clear(); } /// /// An event handler that can be assigned to an event. This method does /// the same thing as the method. /// /// The sender of the event. /// The instance containing /// the event data. public void AllowThrough(object sender, EventArgs e) { AllowThrough(); } /// /// Should process the stream or resource that is passed to it. A /// resource processor must call its next resource processor (provided /// it isn't null) if it is unable to generate the resource from the /// passed in stream. If it is able to /// generate it, then it should do so, invoke the /// method, and NOT call the next resource /// processor. If the next resource processor is null, then the resource /// processor should throw an exception stating that the resource could /// not be generated from the stream because no resource processor /// existed that could perform the task. /// /// The callback that will be invoked when the /// resource has been loaded. /// The stream to load the resource from. /// Options for the loading or processing of the /// resource. public override void From(ResourceProcessCallback callback, Stream readFrom, params IOption[] options) { if(AreBeingAllowedThrough == true) CheckedNextFrom(callback, readFrom, options); else FromCommands.Add(new FromRequest(this, callback, readFrom, options)); } /// /// Writes the resource to the stream specified. /// /// The resource to write to the stream. /// The stream to have the resource written to. /// Options for the writing or processing of the resource. public override void To(TResource resource, Stream writeTo, params IOption[] options) { if(AreBeingAllowedThrough == true) CheckedNextTo(resource, writeTo, options); else ToCommands.Add(new ToRequest(this, resource, writeTo, options)); } /// /// True if the requests are being allowed through, false if otherwise. /// public bool AreBeingAllowedThrough { get; private set; } /// /// The 'from' requests to this . /// CommandCollection FromCommands { get; set; } /// /// The 'to' requests to this . /// CommandCollection ToCommands { get; set; } /// /// Represents a request made to an . /// abstract class Request : ICommand { /// /// Initializes a new instance of the /// struct. /// /// The /// that will be used /// to process the request. /// The stream to load or write the resource /// from or to. /// Options for the loading or processing of the /// resource. public Request(IResourceProcessor resourceProcessor, Stream stream, params IOption[] options) { ResourceProcessor = resourceProcessor; Stream = stream; Options = options; } /// /// The that will be used /// to process the request. /// protected IResourceProcessor ResourceProcessor { get; private set; } /// /// The stream to load or write the resource from or to. /// protected Stream Stream { get; private set; } /// /// Options for the loading or processing of the resource. /// protected IOption[] Options { get; private set; } /// /// Performs the command in question. /// public abstract void Execute(); /// /// Causes the command to be reverted if it was previously executed. This /// method only works if is equal to true. /// By default, this method throws an . /// /// Thrown if this /// does not support undo (i.e., /// is false). public virtual void Undo() { throw new CannotUndoException(); } /// /// True if this can be reverted after a call to /// , false if otherwise. By default, this /// property returns false. /// public virtual bool CanUndo { get { return false; } } } /// /// Represents a /// /// request made to an . /// class FromRequest : Request { /// /// Initializes a new instance of the /// class. /// /// The /// that will be used /// to process the request. /// The callback that will be invoked when the /// resource has been loaded. /// The stream to load the resource from. /// Options for the loading or processing of the /// resource. public FromRequest(IResourceProcessor resourceProcessor, ResourceProcessCallback callback, Stream readFrom, params IOption[] options) : base(resourceProcessor, readFrom, options) { Callback = callback; } /// /// Performs the command in question. /// public override void Execute() { ResourceProcessor.From(Callback, Stream, Options); } /// /// The callback that will be invoked when the resource has been /// loaded. /// protected ResourceProcessCallback Callback { get; private set; } } /// /// Represents a /// /// request made to an . /// class ToRequest : Request { /// /// Initializes a new instance of the /// class. /// /// The /// that will be used /// to process the request. /// The resource that is to be written to the /// stream. /// The stream to write the resource to. /// Options for the loading or processing of the /// resource. public ToRequest(IResourceProcessor resourceProcessor, TResource resource, Stream writeTo, params IOption[] options) : base(resourceProcessor, writeTo, options) { Resource = resource; } /// /// Performs the command in question. /// public override void Execute() { ResourceProcessor.To(Resource, Stream, Options); } /// /// The resource that is to be written to the stream. /// protected TResource Resource { get; private set; } } } }