use super::*;
#[inline]
fn assert_world_step_args_valid(time_step: f32, sub_steps: i32) {
assert!(
crate::is_valid_float(time_step),
"time_step must be finite, got {time_step}"
);
assert!(sub_steps > 0, "sub_steps must be > 0, got {sub_steps}");
}
#[inline]
fn check_world_step_args_valid(time_step: f32, sub_steps: i32) -> crate::error::ApiResult<()> {
if crate::is_valid_float(time_step) && sub_steps > 0 {
Ok(())
} else {
Err(crate::error::ApiError::InvalidArgument)
}
}
impl World {
pub fn step(&mut self, time_step: f32, sub_steps: i32) {
crate::core::callback_state::assert_not_in_callback();
assert_world_step_args_valid(time_step, sub_steps);
self.core
.callback_panicked
.store(false, std::sync::atomic::Ordering::Relaxed);
*self
.core
.callback_panic
.lock()
.expect("callback_panic mutex poisoned") = None;
unsafe { ffi::b2World_Step(self.raw(), time_step, sub_steps) };
self.core.process_deferred_destroys();
if self
.core
.callback_panicked
.load(std::sync::atomic::Ordering::Relaxed)
&& let Some(payload) = self
.core
.callback_panic
.lock()
.expect("callback_panic mutex poisoned")
.take()
{
std::panic::resume_unwind(payload);
}
}
pub fn try_step(&mut self, time_step: f32, sub_steps: i32) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
check_world_step_args_valid(time_step, sub_steps)?;
self.step(time_step, sub_steps);
Ok(())
}
pub fn flush_deferred_destroys(&mut self) {
crate::core::callback_state::assert_not_in_callback();
self.core.process_deferred_destroys();
}
pub fn try_flush_deferred_destroys(&mut self) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
self.flush_deferred_destroys();
Ok(())
}
pub fn set_gravity<V: Into<Vec2>>(&mut self, g: V) {
crate::core::callback_state::assert_not_in_callback();
let gravity = g.into();
assert_world_gravity_valid(gravity);
let gv: ffi::b2Vec2 = gravity.into_raw();
unsafe { ffi::b2World_SetGravity(self.raw(), gv) };
}
pub fn try_set_gravity<V: Into<Vec2>>(&mut self, g: V) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
let gravity = g.into();
check_world_gravity_valid(gravity)?;
let gv: ffi::b2Vec2 = gravity.into_raw();
unsafe { ffi::b2World_SetGravity(self.raw(), gv) };
Ok(())
}
pub fn gravity(&self) -> Vec2 {
world_gravity_checked_impl(self.raw())
}
pub fn try_gravity(&self) -> crate::error::ApiResult<Vec2> {
try_world_gravity_impl(self.raw())
}
pub fn counters(&self) -> Counters {
world_counters_checked_impl(self.raw())
}
pub fn try_counters(&self) -> crate::error::ApiResult<Counters> {
try_world_counters_impl(self.raw())
}
pub fn profile(&self) -> Profile {
world_profile_checked_impl(self.raw())
}
pub fn try_profile(&self) -> crate::error::ApiResult<Profile> {
try_world_profile_impl(self.raw())
}
pub fn awake_body_count(&self) -> i32 {
world_awake_body_count_checked_impl(self.raw())
}
pub fn try_awake_body_count(&self) -> crate::error::ApiResult<i32> {
try_world_awake_body_count_impl(self.raw())
}
pub fn enable_sleeping(&mut self, flag: bool) {
crate::core::callback_state::assert_not_in_callback();
unsafe { ffi::b2World_EnableSleeping(self.raw(), flag) }
}
pub fn try_enable_sleeping(&mut self, flag: bool) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
unsafe { ffi::b2World_EnableSleeping(self.raw(), flag) }
Ok(())
}
pub fn enable_continuous(&mut self, flag: bool) {
crate::core::callback_state::assert_not_in_callback();
unsafe { ffi::b2World_EnableContinuous(self.raw(), flag) }
}
pub fn try_enable_continuous(&mut self, flag: bool) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
unsafe { ffi::b2World_EnableContinuous(self.raw(), flag) }
Ok(())
}
pub fn enable_warm_starting(&mut self, flag: bool) {
crate::core::callback_state::assert_not_in_callback();
unsafe { ffi::b2World_EnableWarmStarting(self.raw(), flag) }
}
pub fn try_enable_warm_starting(&mut self, flag: bool) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
unsafe { ffi::b2World_EnableWarmStarting(self.raw(), flag) }
Ok(())
}
pub fn set_restitution_threshold(&mut self, value: f32) {
crate::core::callback_state::assert_not_in_callback();
assert_non_negative_finite_world_scalar("restitution_threshold", value);
unsafe { ffi::b2World_SetRestitutionThreshold(self.raw(), value) }
}
pub fn try_set_restitution_threshold(&mut self, value: f32) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
check_non_negative_finite_world_scalar(value)?;
unsafe { ffi::b2World_SetRestitutionThreshold(self.raw(), value) }
Ok(())
}
pub fn set_hit_event_threshold(&mut self, value: f32) {
crate::core::callback_state::assert_not_in_callback();
assert_non_negative_finite_world_scalar("hit_event_threshold", value);
unsafe { ffi::b2World_SetHitEventThreshold(self.raw(), value) }
}
pub fn try_set_hit_event_threshold(&mut self, value: f32) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
check_non_negative_finite_world_scalar(value)?;
unsafe { ffi::b2World_SetHitEventThreshold(self.raw(), value) }
Ok(())
}
pub fn set_contact_tuning(&mut self, hertz: f32, damping_ratio: f32, push_speed: f32) {
crate::core::callback_state::assert_not_in_callback();
assert_non_negative_finite_world_scalar("contact_hertz", hertz);
assert_non_negative_finite_world_scalar("contact_damping_ratio", damping_ratio);
assert_non_negative_finite_world_scalar("contact_speed", push_speed);
unsafe { ffi::b2World_SetContactTuning(self.raw(), hertz, damping_ratio, push_speed) }
}
pub fn try_set_contact_tuning(
&mut self,
hertz: f32,
damping_ratio: f32,
push_speed: f32,
) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
check_non_negative_finite_world_scalar(hertz)?;
check_non_negative_finite_world_scalar(damping_ratio)?;
check_non_negative_finite_world_scalar(push_speed)?;
unsafe { ffi::b2World_SetContactTuning(self.raw(), hertz, damping_ratio, push_speed) }
Ok(())
}
pub fn enable_speculative(&mut self, flag: bool) {
crate::core::callback_state::assert_not_in_callback();
unsafe { ffi::b2World_EnableSpeculative(self.raw(), flag) }
}
pub fn try_enable_speculative(&mut self, flag: bool) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
unsafe { ffi::b2World_EnableSpeculative(self.raw(), flag) }
Ok(())
}
pub fn set_maximum_linear_speed(&mut self, v: f32) {
crate::core::callback_state::assert_not_in_callback();
assert_positive_finite_world_scalar("maximum_linear_speed", v);
unsafe { ffi::b2World_SetMaximumLinearSpeed(self.raw(), v) }
}
pub fn try_set_maximum_linear_speed(&mut self, v: f32) -> crate::error::ApiResult<()> {
crate::core::callback_state::check_not_in_callback()?;
check_positive_finite_world_scalar(v)?;
unsafe { ffi::b2World_SetMaximumLinearSpeed(self.raw(), v) }
Ok(())
}
pub fn is_sleeping_enabled(&self) -> bool {
world_is_sleeping_enabled_checked_impl(self.raw())
}
pub fn try_is_sleeping_enabled(&self) -> crate::error::ApiResult<bool> {
try_world_is_sleeping_enabled_impl(self.raw())
}
pub fn is_continuous_enabled(&self) -> bool {
world_is_continuous_enabled_checked_impl(self.raw())
}
pub fn try_is_continuous_enabled(&self) -> crate::error::ApiResult<bool> {
try_world_is_continuous_enabled_impl(self.raw())
}
pub fn is_warm_starting_enabled(&self) -> bool {
world_is_warm_starting_enabled_checked_impl(self.raw())
}
pub fn try_is_warm_starting_enabled(&self) -> crate::error::ApiResult<bool> {
try_world_is_warm_starting_enabled_impl(self.raw())
}
pub fn restitution_threshold(&self) -> f32 {
world_restitution_threshold_checked_impl(self.raw())
}
pub fn try_restitution_threshold(&self) -> crate::error::ApiResult<f32> {
try_world_restitution_threshold_impl(self.raw())
}
pub fn hit_event_threshold(&self) -> f32 {
world_hit_event_threshold_checked_impl(self.raw())
}
pub fn try_hit_event_threshold(&self) -> crate::error::ApiResult<f32> {
try_world_hit_event_threshold_impl(self.raw())
}
pub fn maximum_linear_speed(&self) -> f32 {
world_maximum_linear_speed_checked_impl(self.raw())
}
pub fn try_maximum_linear_speed(&self) -> crate::error::ApiResult<f32> {
try_world_maximum_linear_speed_impl(self.raw())
}
}