use crate::Transform;
use crate::world::World;
use boxdd_sys::ffi;
#[derive(Clone, Debug)]
pub struct BodyMoveEvent {
pub body_id: ffi::b2BodyId,
pub transform: Transform,
pub fell_asleep: bool,
}
#[derive(Copy, Clone)]
pub struct BodyMove<'a>(&'a ffi::b2BodyMoveEvent);
impl<'a> BodyMove<'a> {
pub fn body_id(&self) -> ffi::b2BodyId {
self.0.bodyId
}
pub fn transform(&self) -> Transform {
Transform::from(self.0.transform)
}
pub fn fell_asleep(&self) -> bool {
self.0.fellAsleep
}
}
pub struct BodyMoveIter<'a>(core::slice::Iter<'a, ffi::b2BodyMoveEvent>);
impl<'a> Iterator for BodyMoveIter<'a> {
type Item = BodyMove<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(BodyMove)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl World {
pub fn body_events(&self) -> Vec<BodyMoveEvent> {
crate::core::callback_state::assert_not_in_callback();
let raw = unsafe { ffi::b2World_GetBodyEvents(self.raw()) };
if raw.moveCount <= 0 || raw.moveEvents.is_null() {
return Vec::new();
}
let slice = unsafe { core::slice::from_raw_parts(raw.moveEvents, raw.moveCount as usize) };
slice
.iter()
.map(|e| BodyMoveEvent {
body_id: e.bodyId,
transform: Transform::from(e.transform),
fell_asleep: e.fellAsleep,
})
.collect()
}
pub unsafe fn with_body_events<T>(&self, f: impl FnOnce(&[ffi::b2BodyMoveEvent]) -> T) -> T {
crate::core::callback_state::assert_not_in_callback();
let out = {
let _borrow = self.core_arc().borrow_event_buffers();
let raw = unsafe { ffi::b2World_GetBodyEvents(self.raw()) };
let slice = if raw.moveCount > 0 && !raw.moveEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.moveEvents, raw.moveCount as usize) }
} else {
&[][..]
};
f(slice)
};
self.core_arc().process_deferred_destroys();
out
}
pub fn with_body_events_view<T>(&self, f: impl FnOnce(BodyMoveIter<'_>) -> T) -> T {
crate::core::callback_state::assert_not_in_callback();
let out = {
let _borrow = self.core_arc().borrow_event_buffers();
let raw = unsafe { ffi::b2World_GetBodyEvents(self.raw()) };
let slice = if raw.moveCount > 0 && !raw.moveEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.moveEvents, raw.moveCount as usize) }
} else {
&[][..]
};
f(BodyMoveIter(slice.iter()))
};
self.core_arc().process_deferred_destroys();
out
}
}