The current status quo of having to explicitly dispose of all temporary image handles is extremely unergonomic, especially as the logic becomes more complex.
Have you considered providing an arena object to manage the lifetimes of images as a single scope, similar to what Java's version of vips does?
I have experimented with this myself and implementation seems surprisingly easy, but requires upstream update of Image constructor:
public sealed class VipsArena : IDisposable
{
private static readonly AsyncLocal<VipsArena?> Current = new AsyncLocal<VipsArena?>();
private readonly List<Image> _images = new List<Image>();
private readonly VipsArena? _parent;
private bool _disposed;
public VipsArena()
{
_parent = Current.Value;
Current.Value = this;
}
/// <summary>
/// Track an image in the current arena. Called automatically from Image constructor.
/// </summary>
internal static void Track(Image image)
{
Current.Value?._images.Add(image);
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
// Restore parent scope
Current.Value = _parent;
for (var i = _images.Count - 1; i >= 0; i--)
{
try
{
_images[i].Dispose();
}
catch (Exception e)
{
Console.WriteLine("Error disposing image: {0}", e);
}
}
_images.Clear();
}
}
internal Image(nint pointer) : base(pointer)
{
VipsArena.Track(this);
}
This substantially improves ergonomics, as you can now use any logic constructs without worrying about leaving dangling temp images behind:
using (var arena = new VipsArena())
{
// no using needed here
var image = Image.NewFromFile("input.png");
// Conditionals
if (image.HasAlpha())
{
image = image.Flatten();
}
// Method chaining
image
.Resize(0.5)
.Gaussblur(1.5)
.WriteToFile("output-1.png");
// Multiple operators
(image * 1.2 + 10).WriteToFile("output-2.png");
}
Would integrating something like this be possible in net-vips? As I understand it, this is not a breaking change, as you'll still be able to manage images the old way.
The current status quo of having to explicitly dispose of all temporary image handles is extremely unergonomic, especially as the logic becomes more complex.
Have you considered providing an arena object to manage the lifetimes of images as a single scope, similar to what Java's version of vips does?
I have experimented with this myself and implementation seems surprisingly easy, but requires upstream update of Image constructor:
This substantially improves ergonomics, as you can now use any logic constructs without worrying about leaving dangling temp images behind:
Would integrating something like this be possible in
net-vips? As I understand it, this is not a breaking change, as you'll still be able to manage images the old way.