pub struct QueryDispatcherChain<T, U>(/* private fields */);Expand description
A chain of two query dispatchers that provides fallback behavior.
This struct is created by calling QueryDispatcher::chain() and allows combining multiple
dispatchers into a fallback sequence. When a query is performed:
- The first dispatcher (
T) is tried - If it returns
Err(Unsupported), the second dispatcher (U) is tried - If the second also returns
Unsupported, the error is propagated
§Use Cases
Dispatcher chains are useful for:
-
Custom shapes with default fallback: Handle your custom shapes specifically, but fall back to Parry’s default dispatcher for standard shapes
-
Performance optimization: Try a fast specialized algorithm first, fall back to a general but slower algorithm if needed
-
Progressive feature support: Layer dispatchers that support different feature sets
-
Debugging: Wrap the default dispatcher with a logging dispatcher that passes through
§Example
use parry3d::query::{QueryDispatcher, DefaultQueryDispatcher};
// A dispatcher that handles only custom shapes
struct CustomShapeDispatcher;
impl QueryDispatcher for CustomShapeDispatcher {
fn distance(
&self,
pos12: &Isometry<Real>,
g1: &dyn Shape,
g2: &dyn Shape,
) -> Result<Real, Unsupported> {
// Try to handle custom shapes
match (g1.as_any().downcast_ref::<MyShape>(),
g2.as_any().downcast_ref::<MyShape>()) {
(Some(s1), Some(s2)) => Ok(custom_distance(s1, s2, pos12)),
_ => Err(Unsupported), // Let the next dispatcher handle it
}
}
// ... other methods return Err(Unsupported)
}
// Chain: try custom first, fall back to default
let dispatcher = CustomShapeDispatcher.chain(DefaultQueryDispatcher);
// This will use CustomShapeDispatcher if both are MyShape,
// otherwise DefaultQueryDispatcher handles it
let dist = dispatcher.distance(&pos12, shape1, shape2)?;§Performance Note
Chaining has minimal overhead - it’s just two function calls in the worst case. The first dispatcher is always tried first, so place your most likely-to-succeed dispatcher at the front of the chain for best performance.
§Multiple Chains
You can chain more than two dispatchers by chaining chains:
let dispatcher = custom1
.chain(custom2)
.chain(DefaultQueryDispatcher);This creates a chain of three dispatchers: custom1 -> custom2 -> DefaultQueryDispatcher.
Trait Implementations§
Source§impl<ManifoldData, ContactData, T, U> PersistentQueryDispatcher<ManifoldData, ContactData> for QueryDispatcherChain<T, U>where
T: PersistentQueryDispatcher<ManifoldData, ContactData>,
U: PersistentQueryDispatcher<ManifoldData, ContactData>,
impl<ManifoldData, ContactData, T, U> PersistentQueryDispatcher<ManifoldData, ContactData> for QueryDispatcherChain<T, U>where
T: PersistentQueryDispatcher<ManifoldData, ContactData>,
U: PersistentQueryDispatcher<ManifoldData, ContactData>,
Source§fn contact_manifolds(
&self,
pos12: &Isometry<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
prediction: f32,
manifolds: &mut Vec<ContactManifold<ManifoldData, ContactData>>,
workspace: &mut Option<ContactManifoldsWorkspace>,
) -> Result<(), Unsupported>
fn contact_manifolds( &self, pos12: &Isometry<f32>, g1: &dyn Shape, g2: &dyn Shape, prediction: f32, manifolds: &mut Vec<ContactManifold<ManifoldData, ContactData>>, workspace: &mut Option<ContactManifoldsWorkspace>, ) -> Result<(), Unsupported>
Source§fn contact_manifold_convex_convex(
&self,
pos12: &Isometry<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
normal_constraints1: Option<&dyn NormalConstraints>,
normal_constraints2: Option<&dyn NormalConstraints>,
prediction: f32,
manifold: &mut ContactManifold<ManifoldData, ContactData>,
) -> Result<(), Unsupported>
fn contact_manifold_convex_convex( &self, pos12: &Isometry<f32>, g1: &dyn Shape, g2: &dyn Shape, normal_constraints1: Option<&dyn NormalConstraints>, normal_constraints2: Option<&dyn NormalConstraints>, prediction: f32, manifold: &mut ContactManifold<ManifoldData, ContactData>, ) -> Result<(), Unsupported>
Source§impl<T, U> QueryDispatcher for QueryDispatcherChain<T, U>where
T: QueryDispatcher,
U: QueryDispatcher,
impl<T, U> QueryDispatcher for QueryDispatcherChain<T, U>where
T: QueryDispatcher,
U: QueryDispatcher,
Source§fn intersection_test(
&self,
pos12: &Isometry<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
) -> Result<bool, Unsupported>
fn intersection_test( &self, pos12: &Isometry<f32>, g1: &dyn Shape, g2: &dyn Shape, ) -> Result<bool, Unsupported>
Source§fn distance(
&self,
pos12: &Isometry<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
) -> Result<f32, Unsupported>
fn distance( &self, pos12: &Isometry<f32>, g1: &dyn Shape, g2: &dyn Shape, ) -> Result<f32, Unsupported>
Source§fn contact(
&self,
pos12: &Isometry<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
prediction: f32,
) -> Result<Option<Contact>, Unsupported>
fn contact( &self, pos12: &Isometry<f32>, g1: &dyn Shape, g2: &dyn Shape, prediction: f32, ) -> Result<Option<Contact>, Unsupported>
Source§fn closest_points(
&self,
pos12: &Isometry<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
max_dist: f32,
) -> Result<ClosestPoints, Unsupported>
fn closest_points( &self, pos12: &Isometry<f32>, g1: &dyn Shape, g2: &dyn Shape, max_dist: f32, ) -> Result<ClosestPoints, Unsupported>
Source§fn cast_shapes(
&self,
pos12: &Isometry<f32>,
vel12: &Vector<f32>,
g1: &dyn Shape,
g2: &dyn Shape,
options: ShapeCastOptions,
) -> Result<Option<ShapeCastHit>, Unsupported>
fn cast_shapes( &self, pos12: &Isometry<f32>, vel12: &Vector<f32>, g1: &dyn Shape, g2: &dyn Shape, options: ShapeCastOptions, ) -> Result<Option<ShapeCastHit>, Unsupported>
distance. Read moreSource§fn cast_shapes_nonlinear(
&self,
motion1: &NonlinearRigidMotion,
g1: &dyn Shape,
motion2: &NonlinearRigidMotion,
g2: &dyn Shape,
start_time: f32,
end_time: f32,
stop_at_penetration: bool,
) -> Result<Option<ShapeCastHit>, Unsupported>
fn cast_shapes_nonlinear( &self, motion1: &NonlinearRigidMotion, g1: &dyn Shape, motion2: &NonlinearRigidMotion, g2: &dyn Shape, start_time: f32, end_time: f32, stop_at_penetration: bool, ) -> Result<Option<ShapeCastHit>, Unsupported>
Source§fn chain<U: QueryDispatcher>(self, other: U) -> QueryDispatcherChain<Self, U>where
Self: Sized,
fn chain<U: QueryDispatcher>(self, other: U) -> QueryDispatcherChain<Self, U>where
Self: Sized,
QueryDispatcher that falls back on other for cases not handled by selfAuto Trait Implementations§
impl<T, U> Freeze for QueryDispatcherChain<T, U>
impl<T, U> RefUnwindSafe for QueryDispatcherChain<T, U>where
T: RefUnwindSafe,
U: RefUnwindSafe,
impl<T, U> Send for QueryDispatcherChain<T, U>
impl<T, U> Sync for QueryDispatcherChain<T, U>
impl<T, U> Unpin for QueryDispatcherChain<T, U>
impl<T, U> UnwindSafe for QueryDispatcherChain<T, U>where
T: UnwindSafe,
U: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.