Skip to content

Multi-stage asset loading #1833

@ndarilek

Description

@ndarilek

What problem does this solve or what need does it fill?

Often, the result of an asset load that I'd like to pass around isn't just raw bytes, or some struct created by another library. For instance, I have a plugin that loads byes from the array and does some calculation--determines how many channels an audio file contains. My plugin then creates some sort of audio context, which in turn will load the bytes and create a buffer which my systems will later use directly.

Right now, my asset system loads the bytes, does any processing, and marks the asset as loaded. Then, a system listens to events, using the context resource and modifying the created struct with the type introduced by the context.

Unfortunately, this doesn't interact well with the asset loading system. Assets are marked as loaded, even though the real data I want hasn't been created yet. The startup system rushes to instantiate everything, and usually succeeds. But sometimes it fails, and while I can avoid a crash, I can't access the asset in the way I'd like. There's no easy way to tell whether an entire group of assets is fully loaded, in the same way I can with regular asset loaders.

What usually ends up happening is that the bytes of my game's background audio fully load, and the asset is marked complete. My startup OpenAL system detects the new asset and creates an OpenAL buffer. This almost always succeeds before the background audio starts playing, but occasionally it doesn't, and the game starts but my background audio doesn't play. I'm currently rolling my own custom Web Audio backend, and I expect this problem to be even worse given the general latency of loading things from the web.

What solution would you like?

Two possibilities:

  1. Make resources available to asset loaders somehow, so the loader can instantiate the asset in its final desired form. Alternately, create a different asset loader that has access to resources.
  2. Create some sort of partial-loaded state which the asset loader can use to signal that it's done with the asset, but which doesn't report that the asset is fully loaded when groups are queried. Add an event for partial loads, and let systems indicate that they've either partially or completely finished an asset load in a way that integrates with the current load checks. Then the loader marks the asset as partially loaded, and systems can detect PartialLoad events and either finish the load or perform another step and re-emit the event to even more systems for processing.

What alternative(s) have you considered?

I imagine I'll have to emit a custom event when I've loaded all my assets, but this further complicates the already non-straight-forward asset-loading process by requiring me to manually track when my custom processing step finishes. Given that I'm doing this in a plugin, whatever mechanism I create will be specific to that plugin. I'm open to other possibilities that I may be missing.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-AssetsLoad files from disk to use for things like images, models, and soundsC-FeatureA new feature, making something new possible

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions