bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
32.97k stars 3.2k forks source link

Implementation of `temp://` Asset Source #13406

Open bushrat011899 opened 2 weeks ago

bushrat011899 commented 2 weeks ago

Objective

Solution

Created a new temp:// asset source which can be configured through the AssetPlugin via a new optional field temporary_file_path. If a path is provided, it will be considered as a persistent temporary directory, otherwise a directory is created in a platform appropriate location which will be automatically deleted on application exit.

Example Usage

A typical use for a temporary directory is the storage of data which you may need at some point, but don't right now (e.g., pre-fetching a map from a game server). In the below example, we create an asset my_text_asset, save it to the temp:// source, and later retrieve it.

// This is the asset we will attempt to save.
let my_text_asset = TextAsset("Hello World!".to_owned());

// To ensure the `Task` can outlive this function, we must provide owned versions
// of the `AssetServer` and our desired path.
let path = AssetPath::from("temp://message.txt").into_owned();
let server = assets.clone();

// Pass to the IoTaskPool to complete in the background
IoTaskPool::get().spawn(async move {
    save_asset(my_text_asset, path, server, TextSaver)
        .await
        .unwrap();
}).detach();

// ...

// Can later retrieve the saved asset
let my_text_asset = assets.load("temp://message.txt");

Since the temp:// source is on-disk, the unloaded asset will free memory for the rest of the application to use. In the above example, the memory used is trivial, but in a more complex game, a pre-fetched level could be significantly larger.

Testing


Changelog

Migration Guide

bushrat011899 commented 1 week ago

Converting to draft as I have a rough implementation of this now working on WASM as well as desktop (mobile is not something I am equipped to test so that is still outside of my scope). WASM support is built on top of the Origin Private File System, which provides a file-level API in the browser. I have implemented an AssetReader and an AssetWriter which are suitable for use with the proposed temp:// asset source.

I'm marking this as draft because while I have these implementations working in the browser (tested on Firefox using temp_asset example), I believe there is room for improvement in the exact implementations, and the potential for an AssetWatcher as well for completeness.

I would encourage anyone with wasm-bindgen experience (especially if you've worked with the OPFS API!) to leave any remarks as I will gladly accept and greatly appreciate any feedback!