Skip to content

Commit

Permalink
Improved UiParser.ParseImage with locks and a callback action
Browse files Browse the repository at this point in the history
  • Loading branch information
Ellpeck committed Mar 30, 2024
1 parent 2310361 commit 60af21a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Improvements
- Allow dropdowns to have scrolling panels
- Improved Panel performance when adding and removing a lot of children
- Don't reset the caret position of a text field when selecting or deselecting it
- Improved UiParser.ParseImage with locks and a callback action

Fixes
- Fixed panels updating their relevant children too much when the scroll bar is hidden
Expand Down
28 changes: 22 additions & 6 deletions MLEM.Ui/Parsers/UiParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#if NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER
using System.Net.Http;

#else
using System.Net;
#endif
Expand Down Expand Up @@ -138,22 +139,32 @@ void Action(Element e) {
/// This method invokes an asynchronouns action, meaning the <see cref="Image"/>'s <see cref="Image.Texture"/> will likely not have loaded in when this method returns.
/// </summary>
/// <param name="path">The absolute, relative or web path to the image.</param>
/// <param name="onImageFetched">An action that is invoked with the loaded image once it is fetched. Note that this action will be invoked asynchronously.</param>
/// <returns>The loaded image.</returns>
/// <exception cref="NullReferenceException">Thrown if <see cref="GraphicsDevice"/> is null, or if there is an <see cref="Exception"/> loading the image and <see cref="ImageExceptionHandler"/> is unset.</exception>
protected Image ParseImage(string path) {
protected Image ParseImage(string path, Action<TextureRegion> onImageFetched = null) {
if (this.GraphicsDevice == null)
throw new NullReferenceException("A UI parser requires a GraphicsDevice for parsing images");

var imageLock = new object();
TextureRegion image = null;
return new Image(Anchor.AutoLeft, Vector2.One, _ => image) {
return new Image(Anchor.AutoLeft, Vector2.One, _ => {
lock (imageLock)
return image;
}) {
SetHeightBasedOnAspect = true,
OnAddedToUi = e => {
if (image == null)
bool imageNull;
lock (imageLock)
imageNull = image == null;
if (imageNull)
LoadImageAsync();
},
OnRemovedFromUi = e => {
image?.Texture.Dispose();
image = null;
lock (imageLock) {
image?.Texture.Dispose();
image = null;
}
}
};

Expand All @@ -178,7 +189,12 @@ async void LoadImageAsync() {
using (var stream = Path.IsPathRooted(path) ? File.OpenRead(path) : TitleContainer.OpenStream(path))
tex = Texture2D.FromStream(this.GraphicsDevice, stream);
}
image = new TextureRegion(tex);
lock (imageLock) {
if (image == null) {
image = new TextureRegion(tex);
onImageFetched?.Invoke(image);
}
}
} catch (Exception e) {
if (this.ImageExceptionHandler != null) {
this.ImageExceptionHandler.Invoke(path, e);
Expand Down

0 comments on commit 60af21a

Please sign in to comment.