-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Handle Serialization and Deserialization #2306
Conversation
We need still need a way of pointing to static handles like Edit: Done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening this PR!!
Handle
serialization is definitely something we need to support 😄
I know that there is work to incorporate distill for our asset library.
This would also be nice, as distill supports handle (de)serialization already.
However, I'm not sure how long that will take, so I'm more than happy to support our own version of handle (de)serialization :)
I left some initial comments, please let me know if I need to clarify anything!
Could you also add some tests for this? |
|
||
use crate::{Asset, AssetServer, Handle, HandleId, HandleUntyped}; | ||
|
||
/////////////////////////////////////////////////////////////////////////////// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/////////////////////////////////////////////////////////////////////////////// |
I'm using it elsewhere, so maybe later;
I'm not sure if panic or not to panic, maybe a warning/error log will be better Any weird behavior the game makes because of a missing asset or this will better than a crash; |
Not quite sure what this means haha 😅
Yea I'm not sure either. |
It's possible to reduce the amount of locks needed to query the asset paths down to 1 |
{ | ||
ASSET_SERVER.with(|key| { | ||
key.replace(Some(self.clone())); | ||
let result = T::deserialize(deserializer); | ||
let result = (f)(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example use case of how this API is better than the previous one?
It worries me here that T
is not constrained on Serialize
or Deserialize
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the last API didn't allow to de::DeserializeSeed
to be used for stateful de-serialization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that makes sense.
However, I'm still not a big fan of just having the parameter be f: impl FnOnce() -> T
.
you could give this any f
that returns any type, which as a user of the function, isn't very informative.
If we could come up with some way to constrain T
to better express that T
needs to be serializable/deserializable via the AssetServer
context, that would be best IMO.
value: &T, | ||
) -> Result<S::Ok, S::Error> | ||
/// Enables asset references to be serialized or deserialized | ||
pub fn with_asset_refs_serialization<F, T>(&self, f: F) -> T |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you give f
a more descriptive name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
f
, func
are commonly used in this situations, anything in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like serde_func
(that expresses the functions does some sort of (de)serialization) would be nice.
This PR makes me wish |
But it does! but it you must do it manually implement it (witch is hard), that's why no one think it supports I guess, but you can find it on the docs. This PR is motivated by this prefab plugin (https://github.com/lassade/bevy_prefab) it uses only stateful de-serialization to describe prefabs and entities and it's a WIP btw |
Oh? I was aware of Perhaps I was conflating the word stateful with context. More specifically I would like it to be able to have some handle.seralze(&mut serializer, &asset_server); So we can avoid the global state. |
In that case you can do: (&my_data, &mut my_state).serialize(serializer);
impl<'a> Serialize for (&'a MyData, &'a mut MyState) { ... } But again, it must be impl down the chain to work, many types lets say Thats just too much work to ask from users I think |
.with(|cell| { | ||
let server = cell.replace(None); | ||
let path = server.as_ref().and_then(|server| { | ||
// TODO: `get_handle_path` does absolutely nothing issue #1290 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts
I think the foundations of this are good, but it needs clean up.
I would like to see:
- docs for
AssetRef
- an example or two for how this works
- cleanup of the small nits
- a trait bound on the serialization method
Due to the age, I'm going to apply the Adopt-Me
label.
I wonder if this should instead be achieved through reflection, using something like #5923. Reflection would probably better integrate with scenes and such, as well as allow better control over these assets. For example, the type registry could contain more metadata about an asset that is inserted on load, such as external URLs, dependencies, etc.— either in |
Yep, I agree with your analysis there. Closing this out, but we can learn from this going forward. |
Objective
Add serialization for
Handle
this will allows every type of bevy to implementSerialize
andDeserialize
this will also allows for scene and others data to also load all the dependencies with ease;Usage
will result in:
Requiriments
get_handle_path()
#1290Solves
Allow #2216 to be merged