Browse Source

use callbacks instead of overrides

af/merge-core
Scott Williams 9 years ago
parent
commit
1ce4005e88
  1. 46
      src/ImageSharp/Image/IImageCallbacks.cs
  2. 12
      src/ImageSharp/Image/ImageBase{TColor}.cs
  3. 35
      src/ImageSharp/Image/Image{TColor}.cs
  4. 20
      tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs
  5. 13
      tests/ImageSharp.Tests/Image/SaveWatchingImage.cs

46
src/ImageSharp/Image/IImageCallbacks.cs

@ -0,0 +1,46 @@
// <copyright file="Image{TColor}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ImageSharp.Processing;
/// <summary>
/// Provides a set of methods that are called as part of the images lifetime/processes.
/// </summary>
internal interface IImageCallbacks
{
/// <summary>
/// Invoked before the image is saved.
/// </summary>
/// <typeparam name="TColor">The color</typeparam>
/// <param name="image">The image</param>
/// <param name="stream">The destination stream</param>
/// <param name="encoder">The encoder</param>
/// <param name="options">The options</param>
/// <returns>
/// return true if the processor should be applied otherwise false.
/// </returns>
bool OnSaving<TColor>(ImageBase<TColor> image, Stream stream, Formats.IImageEncoder encoder, IEncoderOptions options)
where TColor : struct, IPixel<TColor>;
/// <summary>
/// Invoked before the image is processed.
/// </summary>
/// <typeparam name="TColor">The color</typeparam>
/// <param name="image">The image</param>
/// <param name="processor">The processor.</param>
/// <param name="rectangle">The rectangle.</param>
/// <returns>
/// return true if the processor should be applied otherwise false.
/// </returns>
bool OnProcessing<TColor>(ImageBase<TColor> image, IImageProcessor<TColor> processor, Rectangle rectangle)
where TColor : struct, IPixel<TColor>;
}
}

12
src/ImageSharp/Image/ImageBase{TColor}.cs

@ -116,6 +116,11 @@ namespace ImageSharp
/// </summary> /// </summary>
public Configuration Configuration { get; private set; } public Configuration Configuration { get; private set; }
/// <summary>
/// Gets or sets the callbacks item which will be called during the lifetime of the image being processed.
/// </summary>
internal IImageCallbacks Callbacks { get; set; }
/// <summary> /// <summary>
/// Applies the processor. /// Applies the processor.
/// </summary> /// </summary>
@ -123,7 +128,12 @@ namespace ImageSharp
/// <param name="rectangle">The rectangle.</param> /// <param name="rectangle">The rectangle.</param>
public virtual void ApplyProcessor(IImageProcessor<TColor> processor, Rectangle rectangle) public virtual void ApplyProcessor(IImageProcessor<TColor> processor, Rectangle rectangle)
{ {
processor.Apply(this, rectangle); // this will be null true or false, if its null or true then apply the processor
// thus is not false then apply the processors (allows for tests to save time and not actually run the prcessor is required)
if (this.Callbacks?.OnProcessing(this, processor, rectangle) != false)
{
processor.Apply(this, rectangle);
}
} }
/// <inheritdoc /> /// <inheritdoc />

35
src/ImageSharp/Image/Image{TColor}.cs

@ -560,22 +560,6 @@ namespace ImageSharp
return target; return target;
} }
/// <summary>
/// Internally saves the image to the given stream using the given image encoder and options.
/// Can be used by overridden by tests to verify save opperations.
/// </summary>
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The encoder to save the image with.</param>
/// <param name="options">The options for the encoder.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream or encoder is null.</exception>
internal virtual void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options)
{
Guard.NotNull(stream, nameof(stream));
Guard.NotNull(encoder, nameof(encoder));
encoder.Encode(this, stream, options);
}
/// <summary> /// <summary>
/// Creates a new <see cref="ImageFrame{TColor}"/> from this instance /// Creates a new <see cref="ImageFrame{TColor}"/> from this instance
/// </summary> /// </summary>
@ -597,6 +581,25 @@ namespace ImageSharp
base.Dispose(disposing); base.Dispose(disposing);
} }
/// <summary>
/// Internally saves the image to the given stream using the given image encoder and options.
/// Can be used by overridden by tests to verify save opperations.
/// </summary>
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The encoder to save the image with.</param>
/// <param name="options">The options for the encoder.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream or encoder is null.</exception>
private void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options)
{
Guard.NotNull(stream, nameof(stream));
Guard.NotNull(encoder, nameof(encoder));
if (this.Callbacks?.OnSaving(this, stream, encoder, options) != false)
{
encoder.Encode(this, stream, options);
}
}
/// <summary> /// <summary>
/// Copies the properties from the other <see cref="IImage"/>. /// Copies the properties from the other <see cref="IImage"/>.
/// </summary> /// </summary>

20
tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs

@ -6,31 +6,35 @@ namespace ImageSharp.Tests.Drawing.Paths
using ImageSharp; using ImageSharp;
using Processing; using Processing;
using System.Collections.Generic; using System.Collections.Generic;
using ImageSharp.Formats;
/// <summary> /// <summary>
/// Watches but does not actually run the processors against the image. /// Watches but does not actually run the processors against the image.
/// </summary> /// </summary>
/// <seealso cref="ImageSharp.Image{ImageSharp.Color}" /> /// <seealso cref="ImageSharp.Image{ImageSharp.Color}" />
public class ProcessorWatchingImage : Image<Color> public class ProcessorWatchingImage : Image<Color>, IImageCallbacks
{ {
public List<ProcessorDetails> ProcessorApplications { get; } = new List<ProcessorDetails>(); public List<ProcessorDetails> ProcessorApplications { get; } = new List<ProcessorDetails>();
public ProcessorWatchingImage(int width, int height) public ProcessorWatchingImage(int width, int height)
: base(width, height, Configuration.CreateDefaultInstance()) : base(width, height, Configuration.CreateDefaultInstance())
{ {
this.Callbacks = this;
} }
public override void ApplyProcessor(IImageProcessor<Color> processor, Rectangle rectangle) public bool OnSaving<TColor>(ImageBase<TColor> image, Stream stream, IImageEncoder encoder, IEncoderOptions options) where TColor : struct, IPixel<TColor>
{ {
ProcessorApplications.Add(new ProcessorDetails return true;
}
public bool OnProcessing<TColor>(ImageBase<TColor> image, IImageProcessor<TColor> processor, Rectangle rectangle) where TColor : struct, IPixel<TColor>
{
this.ProcessorApplications.Add(new ProcessorDetails
{ {
processor = processor, processor = (IImageProcessor<Color>)processor,
rectangle = rectangle rectangle = rectangle
}); });
return false;// do not really apply the processor to speed up testing
// doesn't really apply the processor to the fake images as this is supposed
// to be just used to test which processor was finally applied and to interogate
// its settings
} }
public struct ProcessorDetails public struct ProcessorDetails

13
tests/ImageSharp.Tests/Image/SaveWatchingImage.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Tests
/// Watches but does not actually run the processors against the image. /// Watches but does not actually run the processors against the image.
/// </summary> /// </summary>
/// <seealso cref="ImageSharp.Image{ImageSharp.Color}" /> /// <seealso cref="ImageSharp.Image{ImageSharp.Color}" />
public class SaveWatchingImage : Image<Color> public class SaveWatchingImage : Image<Color>, IImageCallbacks
{ {
public List<OperationDetails> Saves { get; } = new List<OperationDetails>(); public List<OperationDetails> Saves { get; } = new List<OperationDetails>();
@ -22,9 +22,11 @@ namespace ImageSharp.Tests
{ {
//switch out the file system for tests //switch out the file system for tests
this.Configuration.FileSystem = fs ?? this.Configuration.FileSystem; this.Configuration.FileSystem = fs ?? this.Configuration.FileSystem;
this.Callbacks = this;
} }
internal override void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options) public bool OnSaving<TColor>(ImageBase<TColor> image, Stream stream, IImageEncoder encoder, IEncoderOptions options) where TColor : struct, IPixel<TColor>
{ {
this.Saves.Add(new OperationDetails this.Saves.Add(new OperationDetails
{ {
@ -32,6 +34,13 @@ namespace ImageSharp.Tests
options = options, options = options,
stream = stream stream = stream
}); });
return false;
}
public bool OnProcessing<TColor>(ImageBase<TColor> image, IImageProcessor<TColor> processor, Rectangle rectangle) where TColor : struct, IPixel<TColor>
{
return false;
} }
public struct OperationDetails public struct OperationDetails

Loading…
Cancel
Save