use crate::core::{box3d_lock, callback_state};
use crate::error::{Error, Result};
use crate::joints::lock_joint_checked;
use crate::types::{BodyId, JointId, ShapeId};
use crate::world::World;
use boxddd_sys::ffi;
use std::ffi::c_void;
pub unsafe fn try_set_world_raw_user_data(world: &mut World, user_data: *mut c_void) -> Result<()> {
callback_state::check_not_in_callback()?;
let _guard = box3d_lock::lock();
world.check_world_valid_locked()?;
unsafe { ffi::b3World_SetUserData(world.raw(), user_data) };
Ok(())
}
pub unsafe fn try_world_raw_user_data(world: &World) -> Result<*mut c_void> {
callback_state::check_not_in_callback()?;
let _guard = box3d_lock::lock();
world.check_world_valid_locked()?;
Ok(unsafe { ffi::b3World_GetUserData(world.raw()) })
}
pub unsafe fn try_set_body_raw_user_data(
world: &mut World,
body_id: BodyId,
user_data: *mut c_void,
) -> Result<()> {
let _guard = world.lock_body_checked(body_id)?;
unsafe { ffi::b3Body_SetUserData(body_id.into_raw(), user_data) };
Ok(())
}
pub unsafe fn try_body_raw_user_data(world: &World, body_id: BodyId) -> Result<*mut c_void> {
let _guard = world.lock_body_checked(body_id)?;
Ok(unsafe { ffi::b3Body_GetUserData(body_id.into_raw()) })
}
pub unsafe fn try_set_shape_raw_user_data(
world: &mut World,
shape_id: ShapeId,
user_data: *mut c_void,
) -> Result<()> {
let _guard = world.lock_shape_checked(shape_id)?;
unsafe { ffi::b3Shape_SetUserData(shape_id.into_raw(), user_data) };
Ok(())
}
pub unsafe fn try_shape_raw_user_data(world: &World, shape_id: ShapeId) -> Result<*mut c_void> {
let _guard = world.lock_shape_checked(shape_id)?;
Ok(unsafe { ffi::b3Shape_GetUserData(shape_id.into_raw()) })
}
pub unsafe fn try_set_joint_raw_user_data(
world: &mut World,
joint_id: JointId,
user_data: *mut c_void,
) -> Result<()> {
let _guard = lock_joint_checked(world, joint_id)?;
unsafe { ffi::b3Joint_SetUserData(joint_id.into_raw(), user_data) };
Ok(())
}
pub unsafe fn try_joint_raw_user_data(world: &World, joint_id: JointId) -> Result<*mut c_void> {
let _guard = lock_joint_checked(world, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetUserData(joint_id.into_raw()) })
}
pub fn length_units_per_meter() -> f32 {
try_length_units_per_meter().expect("boxddd raw API called from a Box3D callback")
}
pub fn try_length_units_per_meter() -> Result<f32> {
callback_state::check_not_in_callback()?;
let _guard = box3d_lock::lock();
Ok(unsafe { ffi::b3GetLengthUnitsPerMeter() })
}
pub fn try_set_length_units_per_meter(length_units: f32) -> Result<()> {
validate_positive(length_units)?;
callback_state::check_not_in_callback()?;
let _guard = box3d_lock::lock();
unsafe { ffi::b3SetLengthUnitsPerMeter(length_units) };
Ok(())
}
pub fn stall_threshold() -> f32 {
try_stall_threshold().expect("boxddd raw API called from a Box3D callback")
}
pub fn try_stall_threshold() -> Result<f32> {
callback_state::check_not_in_callback()?;
let _guard = box3d_lock::lock();
Ok(unsafe { ffi::b3GetStallThreshold() })
}
pub fn try_set_stall_threshold(seconds: f32) -> Result<()> {
validate_nonnegative(seconds)?;
callback_state::check_not_in_callback()?;
let _guard = box3d_lock::lock();
unsafe { ffi::b3SetStallThreshold(seconds) };
Ok(())
}
#[inline]
fn validate_positive(value: f32) -> Result<()> {
if value.is_finite() && value > 0.0 {
Ok(())
} else {
Err(Error::InvalidArgument)
}
}
#[inline]
fn validate_nonnegative(value: f32) -> Result<()> {
if value.is_finite() && value >= 0.0 {
Ok(())
} else {
Err(Error::InvalidArgument)
}
}