use crate::core::{callback_state, debug_checks};
use crate::error::{Error, Result};
use crate::joints::enter_joint_call;
use crate::types::{BodyId, ContactId, JointId, ShapeId};
use crate::world::World;
use boxddd_sys::ffi;
use std::ffi::c_void;
use std::fmt;
pub struct WorldRawGuard<'a> {
world: &'a mut World,
_call: callback_state::OwnerCallFrame,
}
impl fmt::Debug for WorldRawGuard<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("WorldRawGuard")
.finish_non_exhaustive()
}
}
impl WorldRawGuard<'_> {
pub fn world_id(&self) -> ffi::b3WorldId {
self.world.raw()
}
pub fn body_id(&self, id: BodyId) -> Result<ffi::b3BodyId> {
self.world.state().ledger.authorize_body(id)
}
pub fn shape_id(&self, id: ShapeId) -> Result<ffi::b3ShapeId> {
self.world.state().ledger.authorize_shape(id)
}
pub fn joint_id(&self, id: JointId) -> Result<ffi::b3JointId> {
self.world.state().ledger.authorize_joint(id)
}
pub fn contact_id(&self, id: ContactId) -> Result<ffi::b3ContactId> {
let raw = self.world.state().ledger.authorize_contact(id)?;
debug_checks::check_contact_valid_raw(raw)?;
Ok(raw)
}
}
#[must_use = "dropping raw world parts destroys the native world and all retained sidecars"]
#[derive(Debug)]
pub struct WorldRawParts {
world: Option<World>,
}
impl WorldRawParts {
pub unsafe fn world_guard(&mut self) -> Result<WorldRawGuard<'_>> {
let world = self.world.as_mut().ok_or(Error::NativeFailure)?;
unsafe { world_raw_guard(world) }
}
pub unsafe fn into_world(mut self) -> Result<World> {
callback_state::check_not_in_callback()?;
{
let world = self.world.as_ref().ok_or(Error::NativeFailure)?;
let _call = world.enter_world_call()?;
}
Ok(self.world.take().expect("raw parts still own their world"))
}
pub unsafe fn destroy(self) {
drop(self);
}
}
impl World {
pub fn into_raw_parts(self) -> Result<WorldRawParts> {
{
let _call = self.enter_world_call()?;
}
Ok(WorldRawParts { world: Some(self) })
}
}
pub unsafe fn world_raw_guard(world: &mut World) -> Result<WorldRawGuard<'_>> {
let call = world.enter_call()?;
world.check_world_valid()?;
Ok(WorldRawGuard { world, _call: call })
}
pub unsafe fn set_world_raw_user_data(world: &mut World, user_data: *mut c_void) -> Result<()> {
let _call = world.enter_world_call()?;
unsafe { ffi::b3World_SetUserData(world.raw(), user_data) };
Ok(())
}
pub unsafe fn world_raw_user_data(world: &World) -> Result<*mut c_void> {
let _call = world.enter_world_call()?;
Ok(unsafe { ffi::b3World_GetUserData(world.raw()) })
}
pub unsafe fn set_body_raw_user_data(
world: &mut World,
body_id: BodyId,
user_data: *mut c_void,
) -> Result<()> {
let _call = world.enter_body_call(body_id)?;
unsafe { ffi::b3Body_SetUserData(body_id.into_raw(), user_data) };
Ok(())
}
pub unsafe fn body_raw_user_data(world: &World, body_id: BodyId) -> Result<*mut c_void> {
let _call = world.enter_body_call(body_id)?;
Ok(unsafe { ffi::b3Body_GetUserData(body_id.into_raw()) })
}
pub unsafe fn set_shape_raw_user_data(
world: &mut World,
shape_id: ShapeId,
user_data: *mut c_void,
) -> Result<()> {
let _call = world.enter_shape_call(shape_id)?;
unsafe { ffi::b3Shape_SetUserData(shape_id.into_raw(), user_data) };
Ok(())
}
pub unsafe fn shape_raw_user_data(world: &World, shape_id: ShapeId) -> Result<*mut c_void> {
let _call = world.enter_shape_call(shape_id)?;
Ok(unsafe { ffi::b3Shape_GetUserData(shape_id.into_raw()) })
}
pub unsafe fn set_joint_raw_user_data(
world: &mut World,
joint_id: JointId,
user_data: *mut c_void,
) -> Result<()> {
let _call = enter_joint_call(world, joint_id)?;
unsafe { ffi::b3Joint_SetUserData(joint_id.into_raw(), user_data) };
Ok(())
}
pub unsafe fn joint_raw_user_data(world: &World, joint_id: JointId) -> Result<*mut c_void> {
let _call = enter_joint_call(world, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetUserData(joint_id.into_raw()) })
}