Skip to content
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

Merged
merged 6 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions crates/rapier2d-f64/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ documentation = "https://docs.rs/rapier2d"
homepage = "https://rapier.rs"
repository = "https://github.com/dimforge/rapier"
readme = "README.md"
categories = ["science", "game-development", "mathematics", "simulation", "wasm"]
categories = [
"science",
"game-development",
"mathematics",
"simulation",
"wasm",
]
keywords = ["physics", "dynamics", "rigid", "real-time", "impulse_joints"]
license = "Apache-2.0"
edition = "2021"
Expand All @@ -26,7 +32,13 @@ simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
# enabled with the "simd-stable" or "simd-nightly" feature.
simd-is-enabled = ["vec_map"]
wasm-bindgen = ["instant/wasm-bindgen"]
serde-serialize = ["nalgebra/serde-serialize", "parry2d-f64/serde-serialize", "serde", "bit-vec/serde", "arrayvec/serde"]
serde-serialize = [
"nalgebra/serde-serialize",
"parry2d-f64/serde-serialize",
"serde",
"bit-vec/serde",
"arrayvec/serde",
]
enhanced-determinism = ["simba/libm_force", "parry2d-f64/enhanced-determinism"]
debug-render = []
profiler = ["instant"] # Enables the internal profiler.
Expand Down Expand Up @@ -70,5 +82,6 @@ thiserror = "1"

[dev-dependencies]
bincode = "1"
serde_json = "1"
serde = { version = "1", features = ["derive"] }
oorandom = { version = "11", default-features = false }
19 changes: 16 additions & 3 deletions crates/rapier2d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ documentation = "https://docs.rs/rapier2d"
homepage = "https://rapier.rs"
repository = "https://github.com/dimforge/rapier"
readme = "README.md"
categories = ["science", "game-development", "mathematics", "simulation", "wasm"]
categories = [
"science",
"game-development",
"mathematics",
"simulation",
"wasm",
]
keywords = ["physics", "dynamics", "rigid", "real-time", "impulse_joints"]
license = "Apache-2.0"
edition = "2021"
Expand All @@ -26,7 +32,13 @@ simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
# enabled with the "simd-stable" or "simd-nightly" feature.
simd-is-enabled = ["vec_map"]
wasm-bindgen = ["instant/wasm-bindgen"]
serde-serialize = ["nalgebra/serde-serialize", "parry2d/serde-serialize", "serde", "bit-vec/serde", "arrayvec/serde"]
serde-serialize = [
"nalgebra/serde-serialize",
"parry2d/serde-serialize",
"serde",
"bit-vec/serde",
"arrayvec/serde",
]
enhanced-determinism = ["simba/libm_force", "parry2d/enhanced-determinism"]
debug-render = []
profiler = ["instant"] # Enables the internal profiler.
Expand Down Expand Up @@ -70,5 +82,6 @@ thiserror = "1"

[dev-dependencies]
bincode = "1"
serde_json = "1"
serde = { version = "1", features = ["derive"] }
oorandom = { version = "11", default-features = false }
oorandom = { version = "11", default-features = false }
22 changes: 19 additions & 3 deletions crates/rapier3d-f64/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ documentation = "https://docs.rs/rapier3d"
homepage = "https://rapier.rs"
repository = "https://github.com/dimforge/rapier"
readme = "README.md"
categories = ["science", "game-development", "mathematics", "simulation", "wasm"]
categories = [
"science",
"game-development",
"mathematics",
"simulation",
"wasm",
]
keywords = ["physics", "dynamics", "rigid", "real-time", "impulse_joints"]
license = "Apache-2.0"
edition = "2021"
Expand All @@ -21,12 +27,21 @@ dim3 = []
f64 = []
parallel = ["rayon"]
simd-stable = ["parry3d-f64/simd-stable", "simba/wide", "simd-is-enabled"]
simd-nightly = ["parry3d-f64/simd-nightly", "simba/portable_simd", "simd-is-enabled"]
simd-nightly = [
"parry3d-f64/simd-nightly",
"simba/portable_simd",
"simd-is-enabled",
]
# Do not enable this feature directly. It is automatically
# enabled with the "simd-stable" or "simd-nightly" feature.
simd-is-enabled = ["vec_map"]
wasm-bindgen = ["instant/wasm-bindgen"]
serde-serialize = ["nalgebra/serde-serialize", "parry3d-f64/serde-serialize", "serde", "bit-vec/serde"]
serde-serialize = [
"nalgebra/serde-serialize",
"parry3d-f64/serde-serialize",
"serde",
"bit-vec/serde",
]
enhanced-determinism = ["simba/libm_force", "parry3d-f64/enhanced-determinism"]
debug-render = []
profiler = ["instant"] # Enables the internal profiler.
Expand Down Expand Up @@ -70,5 +85,6 @@ thiserror = "1"

[dev-dependencies]
bincode = "1"
serde_json = "1"
serde = { version = "1", features = ["derive"] }
oorandom = { version = "11", default-features = false }
22 changes: 19 additions & 3 deletions crates/rapier3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ documentation = "https://docs.rs/rapier3d"
homepage = "https://rapier.rs"
repository = "https://github.com/dimforge/rapier"
readme = "README.md"
categories = ["science", "game-development", "mathematics", "simulation", "wasm"]
categories = [
"science",
"game-development",
"mathematics",
"simulation",
"wasm",
]
keywords = ["physics", "dynamics", "rigid", "real-time", "impulse_joints"]
license = "Apache-2.0"
edition = "2021"
Expand All @@ -21,12 +27,21 @@ dim3 = []
f32 = []
parallel = ["rayon"]
simd-stable = ["parry3d/simd-stable", "simba/wide", "simd-is-enabled"]
simd-nightly = ["parry3d/simd-nightly", "simba/portable_simd", "simd-is-enabled"]
simd-nightly = [
"parry3d/simd-nightly",
"simba/portable_simd",
"simd-is-enabled",
]
# Do not enable this feature directly. It is automatically
# enabled with the "simd-stable" or "simd-nightly" feature.
simd-is-enabled = ["vec_map"]
wasm-bindgen = ["instant/wasm-bindgen"]
serde-serialize = ["nalgebra/serde-serialize", "parry3d/serde-serialize", "serde", "bit-vec/serde"]
serde-serialize = [
"nalgebra/serde-serialize",
"parry3d/serde-serialize",
"serde",
"bit-vec/serde",
]
enhanced-determinism = ["simba/libm_force", "parry3d/enhanced-determinism"]
debug-render = []
profiler = ["instant"] # Enables the internal profiler.
Expand Down Expand Up @@ -70,5 +85,6 @@ thiserror = "1"

[dev-dependencies]
bincode = "1"
serde_json = "1"
serde = { version = "1", features = ["derive"] }
oorandom = { version = "11", default-features = false }
7 changes: 7 additions & 0 deletions src/geometry/broad_phase_multi_sap/broad_phase_multi_sap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ pub struct BroadPhaseMultiSap {
// Another alternative would be to remove ColliderProxyId and
// just use a Coarena. But this seems like it could use too
// much memory.
#[cfg_attr(
feature = "serde-serialize",
serde(
serialize_with = "crate::utils::serde::serialize_to_vec_tuple",
deserialize_with = "crate::utils::serde::deserialize_from_vec_tuple"
)
)]
colliders_proxy_ids: HashMap<ColliderHandle, BroadPhaseProxyIndex>,
#[cfg_attr(feature = "serde-serialize", serde(skip))]
region_pool: SAPRegionPool, // To avoid repeated allocations.
Expand Down
71 changes: 71 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,3 +667,74 @@ pub fn smallest_abs_diff_between_angles<N: SimdRealCopy>(a: N, b: N) -> N {
let s_err_is_smallest = s_err.simd_abs().simd_lt(s_err_complement.simd_abs());
s_err.select(s_err_is_smallest, s_err_complement)
}

/// Helpers around serialization.
#[cfg(feature = "serde-serialize")]
pub mod serde {
use serde::{Deserialize, Serialize};
use std::iter::FromIterator;

/// Serializes to a `Vec<(K, V)>`.
///
/// Useful for [`std::collections::HashMap`] with a non-string key,
/// which is unsupported by [`serde_json`].
pub fn serialize_to_vec_tuple<
'a,
S: serde::Serializer,
T: IntoIterator<Item = (&'a K, &'a V)>,
K: Serialize + 'a,
V: Serialize + 'a,
>(
target: T,
s: S,
) -> Result<S::Ok, S::Error> {
let container: Vec<_> = target.into_iter().collect();
serde::Serialize::serialize(&container, s)
}

/// Deserializes from a `Vec<(K, V)>`.
///
/// Useful for [`std::collections::HashMap`] with a non-string key,
/// which is unsupported by [`serde_json`].
#[cfg(feature = "serde-serialize")]
Copy link
Member

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.

Copy link
Contributor Author

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

pub fn deserialize_from_vec_tuple<
'de,
D: serde::Deserializer<'de>,
T: FromIterator<(K, V)>,
K: Deserialize<'de>,
V: Deserialize<'de>,
>(
d: D,
) -> Result<T, D::Error> {
let hashmap_as_vec: Vec<(K, V)> = Deserialize::deserialize(d)?;
Ok(T::from_iter(hashmap_as_vec))
}

#[cfg(test)]
mod test {
use std::collections::HashMap;

#[test]
fn serde_json_hashmap() {
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct Test {
#[cfg_attr(
feature = "serde-serialize",
serde(
serialize_with = "crate::utils::serde::serialize_to_vec_tuple",
deserialize_with = "crate::utils::serde::deserialize_from_vec_tuple"
)
)]
pub map: HashMap<usize, String>,
}

let s = Test {
map: [(42, "Forty-Two".to_string())].into(),
};
let j = serde_json::to_string(&s).unwrap();
assert_eq!(&j, "{\"map\":[[42,\"Forty-Two\"]]}");
let p: Test = serde_json::from_str(&j).unwrap();
assert_eq!(&p, &s);
}
}
}