-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loader/Asset API Ergonomics #15
Comments
I like the builder pattern! Though I think that the storage selection might be a bit difficult, as you can load meshes, textures, material files, .... with the same method at the moment. In order to solve that problem, maybe we can introduce specialized methods? vnodes.insert(
"/assets/dummy/texture",
loader.texture("/io/assets/path/to/texture.png").load()?
);
vnodes.insert(
"/assets/dummy/mesh",
loader.mesh("/io/assets/path/to/mesh.gltf").load()?
);
// ...
world
.create_entity()
.with(vnodes.get("/assets/dummy/texture")?.clone())
.with(vnodes.get("/assets/dummy/mesh")?.clone())
/* ... */
.build()
; As for deciding on the format, I think we might learn a bit from how Assimp does that. |
I don't see a way that we could add the storage lookup inside Loader, without mutably borrowing World, which you don't have access to in the Systems. I believe that if we want to do something like this we should build it on top of Loader to do proper separation of concerns. Dynamic lookup of formats is also quite hard without boxing. |
Yeah :/ I don't know what the right way to do this is.
If you box the let texture_formats: HashMap<String, Box<Format<Texture>>> = hashmap! {
"jpg" => Box::new(JpegFormat),
"png" => Box::new(PngFormat),
// ...
};
// `asset` is unboxed
let asset = formats[file.file_extension()].import(name, file, ...); So, Options could work by using some trait Format<A: Asset> {
fn import(&self, options: &Any, /*...*/)
-> Result<FormatValue<A>>;
}
impl Format<Texture> for JpegFormat {
fn import(&self, options: &Any, /*...*/) {
let options = options.downcast_ref::<JpegOptions>().or_else(|| {
error!("mismatched option type");
Default::default()
});
// ...
} This is a pretty awkward api, but it does work, and won't be used by users too often unless they implement their own formats. (It's unclear to me whether the added complexity is worth it here tbh.) |
I think we already improved this with the prefab system. Do you still see an issue here @kazimuth? I share your concerns that this needs a couple of lines, but I wanted things to be very flexible and that's just the best way I found. I think what's more important than the number of lines is how easy it is to grasp, and I think that we're good here. |
By providing wrapper "Formats" like |
I tried to do that last month, and it didn't work very well... |
Regarding the amount of resources requested, we can't add all the storages inside the loader. However, we can have the loader inside every asset storages, and we would have |
I think a key insight is that you will get much simpler runtime game code by offloading parameters such as format and options to a build step, With persistent asset identifiers and a multi-stage asset build pipeline you can reduce the game code to a load of an asset identifer. The runtime asset representation can then fill in the rest. |
Moving this to RFC repo |
The current loader API is (subjectively) a little heavy.
For example, to load a GLTF file:
And to load a GLTF file from a custom source:
I think this API could be made slightly cleaner by doing (any subset of) a few things:
vnodes
system)Then, a simple asset load can look like just:
And a complex load can look like:
Since loading assets is something that you do a lot, I think it's worth it to make the API nice to use.
Downsides:
The text was updated successfully, but these errors were encountered: