Skip to content

feat: Added method Images.ready()#1441

Merged
spydon merged 14 commits intoflame-engine:mainfrom
st-pasha:ps/images
Mar 23, 2022
Merged

feat: Added method Images.ready()#1441
spydon merged 14 commits intoflame-engine:mainfrom
st-pasha:ps/images

Conversation

@st-pasha
Copy link
Copy Markdown
Contributor

Description

Added method Images.ready() to await for all images that are currently loading. For example, this allows the user to write

@override
Future<void> onLoad() async {
  images.load('sprite1.png');
  images.load('sprite2.png');
  ...
  images.load('something-else.png');
  await images.ready();
}

In addition, multiple small improvements to the Images class:

  • Renamed private field _loadedFiles -> _assets, which reflects the fact that this map also contains images that have not been loaded yet.
  • Added a second constructor for _ImageAsset that does not require a future.
  • Improved doc-strings for several methods.
  • Added private method _ImageAsset.dispose() for more thorough disposal: now if there is a pending future to load the image, that image will get disposed as well when the future completes.
  • Better error message in Images.fromCache(): now it distinguishes between image not added to the cache, or image added but not loaded yet.
  • When an images finishes loading, its _future will be garbage-collected, leaving only the image behind.

Checklist

  • The title of my PR starts with a Conventional Commit prefix (fix:, feat:, docs: etc).
  • I have read the Contributor Guide and followed the process outlined for submitting PRs.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • [-] I have updated/added relevant examples in examples.

Breaking Change

  • No, this is not a breaking change.

Related Issues

Copy link
Copy Markdown
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, docs are missing though

@luanpotter
Copy link
Copy Markdown
Member

Can't you just use loadAll for this? eg

@override
Future<void> onLoad() async {
  await images.loadAll('sprite1.png', 'sprite2.png', 'something-else.png');
}

@st-pasha
Copy link
Copy Markdown
Contributor Author

Can't you just use loadAll for this?

You can. But that requires all images to be loaded up-front from a single place, whereas it could be more convenient to split loading into multiple parts. So, images.ready() is more of a convenience method rather than solving any insurmountable obstacle.

@wolfenrain
Copy link
Copy Markdown
Contributor

You can. But that requires all images to be loaded up-front from a single place, whereas it could be more convenient to split loading into multiple parts. So, images.ready() is more of a convenience method rather than solving any insurmountable obstacle.

loadAll does not required them to be loaded up-front, yes you can use it to load a list of images right there and then but you can also use it to ensure they are loaded, even if they were loaded somewhere else first.

But I get that it might feel bit strange to use it like that. But I dont think this is the way to go either. ready will wait for all loads, even for images that are being loaded on different components than your own, which might be a valid use-case but that really sounds more like a niche than a feature.

Also I think the name ready isn't the right name for what it does, it indicates to me that it means the ImageAssets is ready for use but it isn't about him but instead about the images it can potentially contain. And because ready waits for all the images that it currently has, there could still be other images loading from a different component that gets added a fraction later. So then it never really was "ready" (I know that is just semantics but I am a firm believer that semantics matter haha).

It is more of a areAllImagesThatIHadThisVeryMomentLoaded? method which as I mentioned before can also be done with loadAll, with the added benefit that you can specific which images with the loadAll.

@st-pasha
Copy link
Copy Markdown
Contributor Author

One problem with loadAll() is that it requires knowing the names of all images you need to load, which breaks encapsulation. For example, consider the following pattern:

Future<void> onLoad() async {
  add(Background());
  add(Player());
  add(Enemy());
  add(Hud());
  await images.ready();
}

Here the Background class knows the name of the image used for the background, and Player class knows the path to the player-related images, and so on. Each of those classes would only schedule loading of the corresponding resource, and then a single await at the end of the Game.onLoad would ensure that those images are all ready to be used.

Also I think the name ready isn't the right name for what it does, it indicates to me that it means the ImageAssets is ready for use but it isn't about him but instead about the images it can potentially contain.

You're right that if we think of Images class as an entity per se, then .ready() is not guaranteed to make that class "ready". However, if you think about the class as a simple "bag of images", where only the images are important and not the "bag" itself, then images.ready() makes sense: it means "make all current images ready". The fact that there may be some other images added into the same bag in the future is not relevant: you're simply taking the current set of images and readying them.

@st-pasha st-pasha mentioned this pull request Mar 17, 2022

It has to be png files and they can have transparency.
Images can be in any format supported by Flutter, which include: JPEG, WebP, PNG, GIF, animated GIF,
animated WebP, BMP, and WBMP. Other formats would require additional libraries. For example, SVG
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this true of all platforms? (mobile, web, desktop)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's what the Flutter docs say:

// Update this list when changing the list of supported codecs.
/// {@template dart.ui.imageFormats}
/// JPEG, PNG, GIF, Animated GIF, WebP, Animated WebP, BMP, and WBMP. Additional
/// formats may be supported by the underlying platform. Flutter will
/// attempt to call platform API to decode unrecognized formats, and if the
/// platform API supports decoding the image Flutter will be able to render it.
/// {@endtemplate}

So this looks like a minimal set that's supported on all platforms, plus some additional formats may be supported on each specific platform.

Copy link
Copy Markdown
Member

@luanpotter luanpotter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@st-pasha I see, good point.

LGTM

@spydon spydon enabled auto-merge (squash) March 23, 2022 09:53
@spydon spydon merged commit f81254c into flame-engine:main Mar 23, 2022
@st-pasha st-pasha deleted the ps/images branch March 23, 2022 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants