-
-
Notifications
You must be signed in to change notification settings - Fork 256
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
Fix string serialization for broadphase multisap #675
Conversation
#[cfg_attr( | ||
feature = "serde-serialize", | ||
serde( | ||
serialize_with = "parry::utils::hashmap::serialize_hashmap_capacity", | ||
deserialize_with = "parry::utils::hashmap::deserialize_hashmap_capacity" | ||
) | ||
)] | ||
colliders_proxy_ids: HashMap<ColliderHandle, BroadPhaseProxyIndex>, |
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 doesn’t look correct. serialize_hashmap_capacity
serializes the hashmap as a single value (its capacity) but doesn’t actually serialize its content. So deserialization will result in an emptied collidiers_proxy_id
which is invalid.
I’m surprised this breaks string serialization though. Is it failing to serialize ColliderHandle
or BroadPhaseProxyIndex
?
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.
It was failing on the key ; I'll dig more ; I updated the PR description
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 believe that's the root issue: serde-rs/json#887. I'm surprised there is not a workaround provided in the issue :(
I imagine we could serialize to Vec, and deserialize to HashMap ? But I'm not sure how that would get implemented. And where, because we should keep the same hashmap serialization logic for bincode.
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.
Mmh, yeah, I’m surprised no alternative was suggested in the serde issue.
I imagine we could serialize to Vec, and deserialize to HashMap ?
That sounds reasonable. Implementing this would be somewhat similar to de/serialize_hashmap_capacity
. The serialization functions would look something like that:
/// Serializes a hash-map as a `Vec<(K, V)>`.
#[cfg(feature = "serde-serialize")]
pub fn serialize_hashmap_as_vec<S: serde::Serializer, K, V, H: std::hash::BuildHasher>(
map: &StdHashMap<K, V, H>,
s: S,
) -> Result<S::Ok, S::Error> {
let hashmap_as_vec = /* convert the hashmap to a vec */;
hashmap_as_vec.serialize(s);
}
/// Deserializes a hash-map from a `Vec<(K, V)>`.
#[cfg(feature = "serde-serialize")]
pub fn deserialize_hashmap_from_vec<
'de,
D: serde::Deserializer<'de>,
K,
V,
H: std::hash::BuildHasher + Default,
>(
d: D,
) -> Result<StdHashMap<K, V, H>, D::Error> {
let hashmap_as_vec: Vec<(K, V)> = Deserialize::deserialize(deserializer)?;
/* Convert the hashmap_as_vec to a hashmap */
}
because we should keep the same hashmap serialization logic for bincode
It’s fine if we don’t keep the same logic for bincode.
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.
Looking good, thanks!
src/utils.rs
Outdated
/// | ||
/// Useful for [`std::collections::HashMap`] with a non-string key, | ||
/// which is unsupported by [`serde_json`]. | ||
#[cfg(feature = "serde-serialize")] |
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.
Not needed since the pub mod serde
is already feature-gated.
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 was conflicted between gating the whole mod or each functions ; gating the whole mod might give users a bit of a pain for their "use" statements, but it's not a huge annoyance, and it feels cleaner to gate the whole mod
Without that, serialization to string fails. Interesting to note
bincode
works without that.error log:
After more testing, I realize this crash doesn't happen every time 😮 ; around once in 10 runs 🤔.
The solution for this issue is more involved than I thought, serde json doesn't support non-string keys for
Hashmap
: serde-rs/json#887 ; I'm not sure what's the path forward.