using System; using System.IO; using System.Threading; using Chernobyl.Collections.Generic; namespace Chernobyl.Resources { /// /// An interface for handling the individual nodes of a resource pipeline. /// The resource processor generates or writes out a resource to or from /// a stream by passing the resource and the stream through a linked list /// like structure of other resource processors. /// /// The type of resource to generate or write /// out. public interface IResourceProcessor : ILinkedEnumerable> { /// /// 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 resource can be accessed through the /// property of the /// passed to the /// (it will need to be casted to ). /// The stream to load the resource from. /// Options for the loading or processing of the /// resource. void From(ResourceProcessCallback callback, Stream readFrom, params IOption[] options); /// /// 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 write out the resources data to /// the passed in stream. If /// it is able to write it out, then it should do so and /// NOT call the next resource processor. If the next /// resource processor is null, then the resource processor /// should write out a message to the Console stating that /// the resource could not be written out to the stream /// because no resource processor existed that could perform /// the task (note: has /// methods to make this error checking easier and cleaner). /// /// The resource to write out. /// The stream to write the resource to. /// Options for the writing or processing of the resource. void To(TResource resource, Stream writeTo, params IOption[] options); /// /// The next resource processor in the pipeline. If a resource processor /// is unable to generate/write out the resource, then it must call the /// corresponding function on this resource (provided it isn't null). /// IResourceProcessor NextResourceProcessor { get; set; } } /// /// References a method to be called when a corresponding resource processing /// operation completes. /// public delegate void ResourceProcessCallback(IResourceProcessResult result); /// /// Represents the status of the processing of a resource. /// /// /// /// The type of the resource that was loaded. public interface IResourceProcessResult : IAsyncResult { /// /// The resource that was loaded. This should just return the /// casted to /// . /// TResource Resource { get; } } /// /// A default implementation of the /// interface. /// /// The type of the resource that was loaded. public class ResourceProcessResult : IResourceProcessResult { /// /// Initializes a new instance of the class. /// /// The resource that was loaded. /// A that is used /// to wait for an asynchronous operation to complete. /// True if the operation was /// completed synchronously, false if otherwise. /// True if the operation is completed, false /// if otherwise. public ResourceProcessResult(TResource resource, WaitHandle waitHandle, bool completedSynchronously, bool isCompleted) { AsyncState = resource; AsyncWaitHandle = waitHandle; CompletedSynchronously = completedSynchronously; IsCompleted = isCompleted; } /// /// The resource that was loaded. This should just return the /// casted to /// . /// public TResource Resource { get { return (TResource)AsyncState; } } /// /// Gets a user-defined object that qualifies or contains information /// about an asynchronous operation. /// /// A user-defined object that qualifies or contains information /// about an asynchronous operation. public object AsyncState { get; private set; } /// /// Gets a that is used to wait for an /// asynchronous operation to complete. /// /// A that is used to wait for an /// asynchronous operation to complete. public WaitHandle AsyncWaitHandle { get; private set; } /// /// Gets an indication of whether the asynchronous operation completed /// synchronously. /// /// true if the asynchronous operation completed synchronously; /// otherwise, false. public bool CompletedSynchronously { get; private set; } /// /// Gets an indication whether the asynchronous operation has completed. /// /// true if the operation is complete; otherwise, false. public bool IsCompleted { get; private set; } } }