use crate::types::ShapeId;
use crate::world::{World, WorldHandle};
use boxdd_sys::ffi;
#[derive(Copy, Clone)]
pub struct SensorBeginTouch<'a>(&'a ffi::b2SensorBeginTouchEvent);
impl<'a> SensorBeginTouch<'a> {
pub fn sensor_shape(&self) -> ShapeId {
ShapeId::from_raw(self.0.sensorShapeId)
}
pub fn visitor_shape(&self) -> ShapeId {
ShapeId::from_raw(self.0.visitorShapeId)
}
}
#[derive(Copy, Clone)]
pub struct SensorEndTouch<'a>(&'a ffi::b2SensorEndTouchEvent);
impl<'a> SensorEndTouch<'a> {
pub fn sensor_shape(&self) -> ShapeId {
ShapeId::from_raw(self.0.sensorShapeId)
}
pub fn visitor_shape(&self) -> ShapeId {
ShapeId::from_raw(self.0.visitorShapeId)
}
}
pub struct SensorBeginIter<'a>(core::slice::Iter<'a, ffi::b2SensorBeginTouchEvent>);
impl<'a> Iterator for SensorBeginIter<'a> {
type Item = SensorBeginTouch<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(SensorBeginTouch)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
pub struct SensorEndIter<'a>(core::slice::Iter<'a, ffi::b2SensorEndTouchEvent>);
impl<'a> Iterator for SensorEndIter<'a> {
type Item = SensorEndTouch<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(SensorEndTouch)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[derive(Clone, Debug)]
pub struct SensorBeginTouchEvent {
pub sensor_shape: ShapeId,
pub visitor_shape: ShapeId,
}
#[derive(Clone, Debug)]
pub struct SensorEndTouchEvent {
pub sensor_shape: ShapeId,
pub visitor_shape: ShapeId,
}
#[derive(Clone, Debug, Default)]
pub struct SensorEvents {
pub begin: Vec<SensorBeginTouchEvent>,
pub end: Vec<SensorEndTouchEvent>,
}
fn sensor_events_into_impl(world: ffi::b2WorldId, out: &mut SensorEvents) {
let raw = unsafe { ffi::b2World_GetSensorEvents(world) };
let begin = if raw.beginCount > 0 && !raw.beginEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.beginEvents, raw.beginCount as usize) }
} else {
&[][..]
};
let end = if raw.endCount > 0 && !raw.endEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.endEvents, raw.endCount as usize) }
} else {
&[][..]
};
super::map_snapshot_into(&mut out.begin, begin, |e| SensorBeginTouchEvent {
sensor_shape: ShapeId::from_raw(e.sensorShapeId),
visitor_shape: ShapeId::from_raw(e.visitorShapeId),
});
super::map_snapshot_into(&mut out.end, end, |e| SensorEndTouchEvent {
sensor_shape: ShapeId::from_raw(e.sensorShapeId),
visitor_shape: ShapeId::from_raw(e.visitorShapeId),
});
}
fn sensor_events_snapshot_impl(world: ffi::b2WorldId) -> SensorEvents {
let mut out = SensorEvents::default();
sensor_events_into_impl(world, &mut out);
out
}
fn sensor_events_checked_impl(world: ffi::b2WorldId) -> SensorEvents {
crate::core::callback_state::assert_not_in_callback();
sensor_events_snapshot_impl(world)
}
fn sensor_events_into_checked_impl(world: ffi::b2WorldId, out: &mut SensorEvents) {
crate::core::callback_state::assert_not_in_callback();
sensor_events_into_impl(world, out);
}
fn try_sensor_events_impl(world: ffi::b2WorldId) -> crate::error::ApiResult<SensorEvents> {
crate::core::callback_state::check_not_in_callback()?;
Ok(sensor_events_snapshot_impl(world))
}
fn try_sensor_events_into_impl(
world: ffi::b2WorldId,
out: &mut SensorEvents,
) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
sensor_events_into_impl(world, out);
Ok(())
}
impl World {
pub fn sensor_events(&self) -> SensorEvents {
sensor_events_checked_impl(self.raw())
}
pub fn sensor_events_into(&self, out: &mut SensorEvents) {
sensor_events_into_checked_impl(self.raw(), out);
}
pub fn try_sensor_events(&self) -> crate::error::ApiResult<SensorEvents> {
try_sensor_events_impl(self.raw())
}
pub fn try_sensor_events_into(&self, out: &mut SensorEvents) -> crate::error::ApiResult<()> {
try_sensor_events_into_impl(self.raw(), out)
}
}
impl WorldHandle {
pub fn sensor_events(&self) -> SensorEvents {
sensor_events_checked_impl(self.raw())
}
pub fn sensor_events_into(&self, out: &mut SensorEvents) {
sensor_events_into_checked_impl(self.raw(), out);
}
pub fn try_sensor_events(&self) -> crate::error::ApiResult<SensorEvents> {
try_sensor_events_impl(self.raw())
}
pub fn try_sensor_events_into(&self, out: &mut SensorEvents) -> crate::error::ApiResult<()> {
try_sensor_events_into_impl(self.raw(), out)
}
}
impl World {
pub unsafe fn with_sensor_events_raw<T>(
&self,
f: impl FnOnce(&[ffi::b2SensorBeginTouchEvent], &[ffi::b2SensorEndTouchEvent]) -> T,
) -> T {
self.with_borrowed_event_buffers(|| {
let raw = unsafe { ffi::b2World_GetSensorEvents(self.raw()) };
let begin = if raw.beginCount > 0 && !raw.beginEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.beginEvents, raw.beginCount as usize) }
} else {
&[][..]
};
let end = if raw.endCount > 0 && !raw.endEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.endEvents, raw.endCount as usize) }
} else {
&[][..]
};
f(begin, end)
})
}
pub unsafe fn try_with_sensor_events_raw<T>(
&self,
f: impl FnOnce(&[ffi::b2SensorBeginTouchEvent], &[ffi::b2SensorEndTouchEvent]) -> T,
) -> crate::error::ApiResult<T> {
self.try_with_borrowed_event_buffers(|| {
let raw = unsafe { ffi::b2World_GetSensorEvents(self.raw()) };
let begin = if raw.beginCount > 0 && !raw.beginEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.beginEvents, raw.beginCount as usize) }
} else {
&[][..]
};
let end = if raw.endCount > 0 && !raw.endEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.endEvents, raw.endCount as usize) }
} else {
&[][..]
};
f(begin, end)
})
}
pub fn with_sensor_events_view<T>(
&self,
f: impl FnOnce(SensorBeginIter<'_>, SensorEndIter<'_>) -> T,
) -> T {
self.with_borrowed_event_buffers(|| {
let raw = unsafe { ffi::b2World_GetSensorEvents(self.raw()) };
let begin = if raw.beginCount > 0 && !raw.beginEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.beginEvents, raw.beginCount as usize) }
} else {
&[][..]
};
let end = if raw.endCount > 0 && !raw.endEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.endEvents, raw.endCount as usize) }
} else {
&[][..]
};
f(SensorBeginIter(begin.iter()), SensorEndIter(end.iter()))
})
}
pub fn try_with_sensor_events_view<T>(
&self,
f: impl FnOnce(SensorBeginIter<'_>, SensorEndIter<'_>) -> T,
) -> crate::error::ApiResult<T> {
self.try_with_borrowed_event_buffers(|| {
let raw = unsafe { ffi::b2World_GetSensorEvents(self.raw()) };
let begin = if raw.beginCount > 0 && !raw.beginEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.beginEvents, raw.beginCount as usize) }
} else {
&[][..]
};
let end = if raw.endCount > 0 && !raw.endEvents.is_null() {
unsafe { core::slice::from_raw_parts(raw.endEvents, raw.endCount as usize) }
} else {
&[][..]
};
f(SensorBeginIter(begin.iter()), SensorEndIter(end.iter()))
})
}
}