use try..finally to make sure rented arrays are returned

This commit is contained in:
Jesse Plamondon-Willard 2022-10-08 17:42:32 -04:00
parent 48d0f70ffd
commit 40d5cd7c05
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
2 changed files with 81 additions and 66 deletions

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using StardewValley; using StardewValley;
@ -64,7 +63,8 @@ namespace StardewModdingAPI.Framework.Content
{ {
int pixelCount = areaWidth * areaHeight; int pixelCount = areaWidth * areaHeight;
sourceData = ArrayPool<Color>.Shared.Rent(pixelCount); sourceData = ArrayPool<Color>.Shared.Rent(pixelCount);
try
{
// slower copying, line by line // slower copying, line by line
for (int y = areaY, maxY = areaY + areaHeight; y < maxY; y++) for (int y = areaY, maxY = areaY + areaHeight; y < maxY; y++)
{ {
@ -75,12 +75,14 @@ namespace StardewModdingAPI.Framework.Content
// apply // apply
this.PatchImageImpl(sourceData, source.Width, source.Height, sourceArea.Value, targetArea.Value, patchMode); this.PatchImageImpl(sourceData, source.Width, source.Height, sourceArea.Value, targetArea.Value, patchMode);
}
// return finally
{
ArrayPool<Color>.Shared.Return(sourceData); ArrayPool<Color>.Shared.Return(sourceData);
} }
} }
} }
}
/// <inheritdoc /> /// <inheritdoc />
public void PatchImage(Texture2D source, Rectangle? sourceArea = null, Rectangle? targetArea = null, PatchMode patchMode = PatchMode.Replace) public void PatchImage(Texture2D source, Rectangle? sourceArea = null, Rectangle? targetArea = null, PatchMode patchMode = PatchMode.Replace)
@ -98,14 +100,16 @@ namespace StardewModdingAPI.Framework.Content
// get source data // get source data
int pixelCount = sourceArea.Value.Width * sourceArea.Value.Height; int pixelCount = sourceArea.Value.Width * sourceArea.Value.Height;
Color[] sourceData = ArrayPool<Color>.Shared.Rent(pixelCount); Color[] sourceData = ArrayPool<Color>.Shared.Rent(pixelCount);
try
{
source.GetData(0, sourceArea, sourceData, 0, pixelCount); source.GetData(0, sourceArea, sourceData, 0, pixelCount);
// apply
this.PatchImageImpl(sourceData, source.Width, source.Height, sourceArea.Value, targetArea.Value, patchMode); this.PatchImageImpl(sourceData, source.Width, source.Height, sourceArea.Value, targetArea.Value, patchMode);
}
// return finally
{
ArrayPool<Color>.Shared.Return(sourceData); ArrayPool<Color>.Shared.Return(sourceData);
} }
}
/// <inheritdoc /> /// <inheritdoc />
public bool ExtendImage(int minWidth, int minHeight) public bool ExtendImage(int minWidth, int minHeight)
@ -207,6 +211,8 @@ namespace StardewModdingAPI.Framework.Content
// get target data // get target data
Color[] mergedData = ArrayPool<Color>.Shared.Rent(pixelCount); Color[] mergedData = ArrayPool<Color>.Shared.Rent(pixelCount);
try
{
target.GetData(0, targetArea, mergedData, 0, pixelCount); target.GetData(0, targetArea, mergedData, 0, pixelCount);
// merge pixels // merge pixels
@ -241,8 +247,12 @@ namespace StardewModdingAPI.Framework.Content
} }
target.SetData(0, targetArea, mergedData, 0, pixelCount); target.SetData(0, targetArea, mergedData, 0, pixelCount);
}
finally
{
ArrayPool<Color>.Shared.Return(mergedData); ArrayPool<Color>.Shared.Return(mergedData);
} }
} }
} }
} }
}

View File

@ -395,6 +395,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
// premultiply pixels // premultiply pixels
int count = texture.Width * texture.Height; int count = texture.Width * texture.Height;
Color[] data = ArrayPool<Color>.Shared.Rent(count); Color[] data = ArrayPool<Color>.Shared.Rent(count);
try
{
texture.GetData(data, 0, count); texture.GetData(data, 0, count);
bool changed = false; bool changed = false;
@ -411,10 +413,13 @@ namespace StardewModdingAPI.Framework.ContentManagers
if (changed) if (changed)
texture.SetData(data, 0, count); texture.SetData(data, 0, count);
// return
ArrayPool<Color>.Shared.Return(data);
return texture; return texture;
} }
finally
{
ArrayPool<Color>.Shared.Return(data);
}
}
/// <summary>Fix custom map tilesheet paths so they can be found by the content manager.</summary> /// <summary>Fix custom map tilesheet paths so they can be found by the content manager.</summary>
/// <param name="map">The map whose tilesheets to fix.</param> /// <param name="map">The map whose tilesheets to fix.</param>