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; }
}
}
}