From 499fc098e60f752caba608e1cb69f8c7e49c236c Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Wed, 8 Nov 2023 00:02:28 +0100 Subject: [PATCH 1/5] Make UserData pointer-packing actually sound --- physx-sys/pxbind/src/consumer.rs | 6 + physx-sys/pxbind/src/consumer/record.rs | 11 +- physx-sys/src/generated/unix/structgen.rs | 80 +++++----- .../x86_64-pc-windows-msvc/structgen.rs | 80 +++++----- physx-sys/src/lib.rs | 140 ++++++++++++++++++ physx/src/articulation_link.rs | 9 +- physx/src/articulation_reduced_coordinate.rs | 7 +- physx/src/controller.rs | 13 +- physx/src/material.rs | 6 +- physx/src/rigid_dynamic.rs | 9 +- physx/src/rigid_static.rs | 9 +- physx/src/scene.rs | 7 +- physx/src/shape.rs | 9 +- physx/src/traits/descriptor.rs | 11 +- physx/src/traits/user_data.rs | 83 ++++++----- 15 files changed, 319 insertions(+), 161 deletions(-) diff --git a/physx-sys/pxbind/src/consumer.rs b/physx-sys/pxbind/src/consumer.rs index bf1e767c..d39291f7 100644 --- a/physx-sys/pxbind/src/consumer.rs +++ b/physx-sys/pxbind/src/consumer.rs @@ -726,6 +726,9 @@ pub enum Builtin { Mat33, Mat34, Mat44, + // on the C++ side, `void*`, but we want to be able to pack arbitrary data into the space + // available so we treat it as a separate type so we can do that properly in the Rust side + UserData, } impl Builtin { @@ -758,6 +761,7 @@ impl Builtin { Self::Mat34V => "glam::Affine3A", Self::Mat34 => "Affine", Self::Mat44V | Self::Mat44 => "PxMat44", + Self::UserData => "UserDataField", } } @@ -793,6 +797,7 @@ impl Builtin { Self::Mat34 => "physx_Mat34_Pod", Self::Mat44V => "physx_Mat44V_Pod", Self::Mat44 => "physx_PxMat44_Pod", + Self::UserData => "void*", } } @@ -828,6 +833,7 @@ impl Builtin { Self::Mat34 => "physx::PxMat34", Self::Mat44V => "physx::PxMat44V", Self::Mat44 => "physx::PxMat44", + Self::UserData => "void*", } } diff --git a/physx-sys/pxbind/src/consumer/record.rs b/physx-sys/pxbind/src/consumer/record.rs index fc8b319c..8b410423 100644 --- a/physx-sys/pxbind/src/consumer/record.rs +++ b/physx-sys/pxbind/src/consumer/record.rs @@ -713,9 +713,13 @@ impl<'ast> super::AstConsumer<'ast> { continue; } - let kind = self - .parse_type(kind, template_types) - .with_context(|| format!("failed to parse type for {rname}::{name}"))?; + let kind = if name == "userData" || name == "mUserData" { + QualType::Builtin(Builtin::UserData) + } else { + self + .parse_type(kind, template_types) + .with_context(|| format!("failed to parse type for {rname}::{name}"))? + }; // if matches!(&kind, QualType::FunctionPointer) { // continue; @@ -723,6 +727,7 @@ impl<'ast> super::AstConsumer<'ast> { let is_reference = matches!(kind, QualType::Reference { .. }); + fields.push(FieldBinding { name, kind, diff --git a/physx-sys/src/generated/unix/structgen.rs b/physx-sys/src/generated/unix/structgen.rs index 39a42e5d..3b2af626 100644 --- a/physx-sys/src/generated/unix/structgen.rs +++ b/physx-sys/src/generated/unix/structgen.rs @@ -653,14 +653,14 @@ pub struct PxSimulationTetrahedronMeshData { #[repr(C)] pub struct PxActor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxAggregate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1007,35 +1007,35 @@ pub struct PxArticulationTendonLimit { #[repr(C)] pub struct PxArticulationAttachment { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendonJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationSpatialTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationFixedTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1093,35 +1093,35 @@ pub struct PxArticulationCache { #[repr(C)] pub struct PxArticulationSensor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationJointReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxShape { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidActor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1134,14 +1134,14 @@ pub struct PxNodeIndex { #[repr(C)] pub struct PxRigidBody { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationLink { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1174,7 +1174,7 @@ pub struct PxConstraintShaderTable { #[repr(C)] pub struct PxConstraint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1293,14 +1293,14 @@ pub struct PxContactModifyPair { #[repr(C)] pub struct PxBaseMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFEMMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1323,7 +1323,7 @@ pub struct PxParticleRigidFilterPair { #[repr(C)] pub struct PxMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1372,7 +1372,7 @@ pub struct PxParticleSpring { #[repr(C)] pub struct PxParticleMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1514,14 +1514,14 @@ pub struct PxQueryFilterData { #[repr(C)] pub struct PxRigidDynamic { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidStatic { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1542,7 +1542,7 @@ pub struct PxSceneQueryDesc { #[repr(C)] pub struct PxBroadPhaseRegion { pub mBounds: PxBounds3, - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1677,7 +1677,7 @@ pub struct PxSceneDesc { pub flags: PxSceneFlags, pub cpuDispatcher: *mut PxCpuDispatcher, pub structgen_pad2: [u8; 8], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub solverBatchSize: u32, pub solverArticulationBatchSize: u32, pub nbContactDataBlocks: u32, @@ -1787,7 +1787,7 @@ pub struct PxDominanceGroupPair { #[repr(C)] pub struct PxScene { pub structgen_pad0: [u8; 8], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1936,7 +1936,7 @@ pub struct PxExtendedVec3 { #[repr(C)] pub struct PxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, pub mPos: PxExtendedVec3, pub mRot: PxQuat, } @@ -1945,7 +1945,7 @@ pub struct PxObstacle { #[repr(C)] pub struct PxBoxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfExtents: PxVec3, @@ -1956,7 +1956,7 @@ pub struct PxBoxObstacle { #[repr(C)] pub struct PxCapsuleObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfHeight: f32, @@ -2070,7 +2070,7 @@ pub struct PxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub structgen_pad4: [u8; 8], } #[derive(Clone, Copy)] @@ -2097,7 +2097,7 @@ pub struct PxBoxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub structgen_pad4: [u8; 4], pub halfHeight: f32, pub halfSideExtent: f32, @@ -2127,7 +2127,7 @@ pub struct PxCapsuleControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub structgen_pad4: [u8; 4], pub radius: f32, pub height: f32, @@ -2272,7 +2272,7 @@ pub struct PxDefaultFileInputData { #[repr(C)] pub struct PxJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2286,7 +2286,7 @@ pub struct PxSpring { #[repr(C)] pub struct PxDistanceJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2302,14 +2302,14 @@ pub struct PxJacobianRow { #[repr(C)] pub struct PxContactJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFixedJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2387,21 +2387,21 @@ pub struct PxJointLimitPyramid { #[repr(C)] pub struct PxPrismaticJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRevoluteJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxSphericalJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2417,21 +2417,21 @@ pub struct PxD6JointDrive { #[repr(C)] pub struct PxD6Joint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxGearJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRackAndPinionJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] diff --git a/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs b/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs index 750e842a..8596b3b7 100644 --- a/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs +++ b/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs @@ -653,14 +653,14 @@ pub struct PxSimulationTetrahedronMeshData { #[repr(C)] pub struct PxActor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxAggregate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1012,35 +1012,35 @@ pub struct PxArticulationTendonLimit { #[repr(C)] pub struct PxArticulationAttachment { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendonJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationSpatialTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationFixedTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1098,35 +1098,35 @@ pub struct PxArticulationCache { #[repr(C)] pub struct PxArticulationSensor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationJointReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxShape { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidActor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1139,14 +1139,14 @@ pub struct PxNodeIndex { #[repr(C)] pub struct PxRigidBody { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationLink { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1179,7 +1179,7 @@ pub struct PxConstraintShaderTable { #[repr(C)] pub struct PxConstraint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1298,14 +1298,14 @@ pub struct PxContactModifyPair { #[repr(C)] pub struct PxBaseMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFEMMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1328,7 +1328,7 @@ pub struct PxParticleRigidFilterPair { #[repr(C)] pub struct PxMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1377,7 +1377,7 @@ pub struct PxParticleSpring { #[repr(C)] pub struct PxParticleMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1519,14 +1519,14 @@ pub struct PxQueryFilterData { #[repr(C)] pub struct PxRigidDynamic { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidStatic { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1547,7 +1547,7 @@ pub struct PxSceneQueryDesc { #[repr(C)] pub struct PxBroadPhaseRegion { pub mBounds: PxBounds3, - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1682,7 +1682,7 @@ pub struct PxSceneDesc { pub flags: PxSceneFlags, pub cpuDispatcher: *mut PxCpuDispatcher, pub structgen_pad2: [u8; 8], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub solverBatchSize: u32, pub solverArticulationBatchSize: u32, pub nbContactDataBlocks: u32, @@ -1792,7 +1792,7 @@ pub struct PxDominanceGroupPair { #[repr(C)] pub struct PxScene { pub structgen_pad0: [u8; 8], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1941,7 +1941,7 @@ pub struct PxExtendedVec3 { #[repr(C)] pub struct PxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, pub mPos: PxExtendedVec3, pub mRot: PxQuat, } @@ -1950,7 +1950,7 @@ pub struct PxObstacle { #[repr(C)] pub struct PxBoxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfExtents: PxVec3, @@ -1961,7 +1961,7 @@ pub struct PxBoxObstacle { #[repr(C)] pub struct PxCapsuleObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserDataField, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfHeight: f32, @@ -2075,7 +2075,7 @@ pub struct PxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub structgen_pad4: [u8; 8], } #[derive(Clone, Copy)] @@ -2102,7 +2102,7 @@ pub struct PxBoxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub structgen_pad4: [u8; 8], pub halfHeight: f32, pub halfSideExtent: f32, @@ -2133,7 +2133,7 @@ pub struct PxCapsuleControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, pub structgen_pad4: [u8; 8], pub radius: f32, pub height: f32, @@ -2279,7 +2279,7 @@ pub struct PxDefaultFileInputData { #[repr(C)] pub struct PxJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2293,7 +2293,7 @@ pub struct PxSpring { #[repr(C)] pub struct PxDistanceJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2309,14 +2309,14 @@ pub struct PxJacobianRow { #[repr(C)] pub struct PxContactJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFixedJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2394,21 +2394,21 @@ pub struct PxJointLimitPyramid { #[repr(C)] pub struct PxPrismaticJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRevoluteJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxSphericalJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2424,21 +2424,21 @@ pub struct PxD6JointDrive { #[repr(C)] pub struct PxD6Joint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxGearJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRackAndPinionJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserDataField, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] diff --git a/physx-sys/src/lib.rs b/physx-sys/src/lib.rs index 6f3ae94a..4f9465f7 100644 --- a/physx-sys/src/lib.rs +++ b/physx-sys/src/lib.rs @@ -189,12 +189,152 @@ include!("generated/x86_64-pc-windows-msvc/structgen.rs"); include!("physx_generated.rs"); +use core::mem::MaybeUninit; use std::ffi::c_void; pub const fn version(major: u32, minor: u32, patch: u32) -> u32 { (major << 24) + (minor << 16) + (patch << 8) } +const fn can_pack_into_pointer() -> bool { + core::mem::size_of::() <= core::mem::size_of::<*mut c_void>() && core::mem::align_of::() <= core::mem::align_of::<*mut c_void>() +} + +/// The type of `userData` fields, which is a `void*` pointer in the PhysX api, but which +/// we turn into this `union` on the Rust side to be able to pack small user data types inline into +/// the space of the pointer itself when possible. +// +// NOTE: In a world where cross-language C-to-Rust link-time optimization existed and we statically +// linked PhysX, this could possibly break since on the PhsyX side it's a `void*` which is +// `noundef` under Clang whereas we explicitly allow types with arbitrary layout (including +// padding) to be packed as long as they have the necessary size an alignment. But, cross-lang +// LTO like that does not currently exist and is unlikely to happen, so it's probably Fine TM. +#[repr(C)] +#[derive(Clone, Copy)] +#[cfg_attr(feature = "debug-structs", derive(Debug))] +pub union UserDataField { + heap_pointer: *mut c_void, + packed_data: MaybeUninit<*mut c_void>, +} + +impl Default for UserDataField { + #[inline(always)] + fn default() -> Self { + Self::new_uninit() + } +} + +impl UserDataField { + /// Create a new `UserDataField` which is immediately initialized with the given `data`. See + /// [`UserDataField::initialize_with_data`] for more details. + pub fn new_with_data(data: T) -> Self { + let mut ret = Self::new_uninit(); + ret.initialize_with_data(data); + ret + } + + /// Create a new `UserDataField` which is uninitialized. Initialized it before use! + #[inline(always)] + pub fn new_uninit() -> Self { + UserDataField { packed_data: MaybeUninit::uninit() } + + } + /// Initialize the field with arbitrary user data of type `T`. + /// + /// If the data can be packed into the space of a `*mut c_void` (its size and alignement are + /// both less than or equal to the size and alignment of a pointer on your platform), then + /// it will be written inline into the space of the pointer. If it cannot, it will be placed + /// on the heap and a pointer to it will be written to this field. + /// + /// You can access data you've initialized using the other functions available on this type. + /// If `T` could not be packed and was put on the heap, you must call + /// [`UserDataField::drop_and_dealloc`] with the same `T` in order to drop and deallocate it, + /// if you care about it being dropped or dealloced (if not, the memory will leak). + /// + /// If you call this when data has already been initialized, it will be clobbered if + /// it was written inline and if it was on the heap the old data will be leaked and replaced + /// with the new data. + #[inline] + pub fn initialize_with_data(&mut self, data: T) { + if can_pack_into_pointer::() { + // SAFETY: We've checked T's size and align are both < *mut c_void, which `self` must + // be at least size/align of + unsafe { + core::ptr::write(core::ptr::addr_of_mut!(self.packed_data).cast::(), data); + } + } else { + let heap_ptr = Box::into_raw(Box::new(data)); + self.heap_pointer = heap_ptr.cast(); + } + } + + /// Get a reference to previously-initialized data of type `T`. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `initialize_with_data` with data + /// of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since + /// doing so. + #[inline(always)] + pub unsafe fn data_ref(&self) -> &T { + if can_pack_into_pointer::() { + // SAFETY: if function level safety is true, we must have initialized a valid T inside + // self as packed, since we use the same check in `initialize_with_data` + unsafe { &*(core::ptr::addr_of!(self.packed_data).cast::()) } + } else { + // SAFETY: if function level safety is true, we must have initialized a valid T on + // the heap which we point to, since we use the same check in `initialize_with_data` + unsafe { &*(self.heap_pointer.cast::().cast_const()) } + } + } + + /// Get a reference to previously-initialized data of type `T`. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `initialize_with_data` with data + /// of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since + /// doing so. + #[inline(always)] + pub unsafe fn data_ref_mut(&mut self) -> &mut T { + if can_pack_into_pointer::() { + // SAFETY: if function level safety is true, we must have initialized a valid T inside + // self as packed, since we use the same check in `initialize_with_data` + unsafe { &mut *(core::ptr::addr_of_mut!(self.packed_data).cast::()) } + } else { + // SAFETY: if function level safety is true, we must have initialized a valid T on + // the heap which we point to, since we use the same check in `initialize_with_data` + unsafe { &mut *(self.heap_pointer.cast::()) } + } + } + + /// Drop and deallocate the space that was allocated for the data on the heap, if there was + /// any. + /// + /// For types that were packed inline, it runs `drop`, if it exists for `T`, or otherwise does + /// nothing. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `initialize_with_data` with data + /// of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since + /// doing so. + #[inline] + pub unsafe fn drop_and_dealloc(&mut self) { + if !can_pack_into_pointer::() { + // SAFETY: self is a heap_pointer and must have been initialized due to function safety + let ptr = unsafe { self.heap_pointer }.cast::(); + // SAFETY: we must have constructed the value pointed to by `ptr` by putting it in a box + // if the function level safety is met. + let reconsructed_box = unsafe { Box::from_raw(ptr) }; + drop(reconsructed_box); + } else { + unsafe { + core::ptr::drop_in_place(self.data_ref_mut::()) + } + } + } +} pub type CollisionCallback = unsafe extern "C" fn(*mut c_void, *const PxContactPairHeader, *const PxContactPair, u32); diff --git a/physx/src/articulation_link.rs b/physx/src/articulation_link.rs index 01d81ba5..cfd40450 100644 --- a/physx/src/articulation_link.rs +++ b/physx/src/articulation_link.rs @@ -10,8 +10,9 @@ use crate::{ traits::{Class, UserData}, }; -use std::{marker::PhantomData, ptr::drop_in_place}; +use std::marker::PhantomData; +use physx_sys::UserDataField; #[rustfmt::skip] use physx_sys::{ PxArticulationLink_getChildren, @@ -34,12 +35,12 @@ unsafe impl UserData for PxArticulationLink { type UserData = L; #[inline] - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } #[inline] - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -47,7 +48,7 @@ unsafe impl UserData for PxArticulationLink { impl Drop for PxArticulationLink { fn drop(&mut self) { unsafe { - drop_in_place(self.get_user_data_mut() as *mut _); + self.drop_and_dealloc_user_data(); PxArticulationLink_release_mut(self.as_mut_ptr()); } } diff --git a/physx/src/articulation_reduced_coordinate.rs b/physx/src/articulation_reduced_coordinate.rs index 46426bfd..f655f753 100644 --- a/physx/src/articulation_reduced_coordinate.rs +++ b/physx/src/articulation_reduced_coordinate.rs @@ -15,6 +15,7 @@ use super::{ use std::{marker::PhantomData, ptr::drop_in_place}; +use physx_sys::UserDataField; #[rustfmt::skip] use physx_sys::{ PxArticulationReducedCoordinate_applyCache_mut, @@ -68,11 +69,11 @@ pub struct PxArticulationReducedCoordinate { unsafe impl UserData for PxArticulationReducedCoordinate { type UserData = U; - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -84,7 +85,7 @@ impl Drop for PxArticulationReducedCoordinate PxCapsuleControllerDesc { unsafe impl UserData for PxCapsuleControllerDesc { type UserData = U; - fn user_data_ptr(&self) -> &*mut c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -248,7 +249,7 @@ unsafe impl UserData for PxCapsuleControllerDesc { impl Drop for PxCapsuleControllerDesc { fn drop(&mut self) { unsafe { - drop_in_place(UserData::get_user_data_mut(self) as *mut _); + self.drop_and_dealloc_user_data(); PxCapsuleControllerDesc_delete(self.as_mut_ptr()); } } @@ -396,11 +397,11 @@ impl PxBoxControllerDesc { unsafe impl UserData for PxBoxControllerDesc { type UserData = U; - fn user_data_ptr(&self) -> &*mut c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -408,7 +409,7 @@ unsafe impl UserData for PxBoxControllerDesc { impl Drop for PxBoxControllerDesc { fn drop(&mut self) { unsafe { - drop_in_place(UserData::get_user_data_mut(self) as *mut _); + self.drop_and_dealloc_user_data(); PxBoxControllerDesc_delete(self.as_mut_ptr()) } } diff --git a/physx/src/material.rs b/physx/src/material.rs index 0019a736..cdce539d 100644 --- a/physx/src/material.rs +++ b/physx/src/material.rs @@ -5,6 +5,7 @@ use crate::{ use std::marker::PhantomData; +use physx_sys::UserDataField; #[rustfmt::skip] use physx_sys::{ PxMaterial_getDynamicFriction, @@ -39,11 +40,11 @@ pub struct PxMaterial { unsafe impl UserData for PxMaterial { type UserData = U; - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -51,6 +52,7 @@ unsafe impl UserData for PxMaterial { impl Drop for PxMaterial { fn drop(&mut self) { use crate::base::RefCounted; + unsafe { self.drop_and_dealloc_user_data() }; self.release(); } } diff --git a/physx/src/rigid_dynamic.rs b/physx/src/rigid_dynamic.rs index dbaaf9d5..87876fd3 100644 --- a/physx/src/rigid_dynamic.rs +++ b/physx/src/rigid_dynamic.rs @@ -13,8 +13,9 @@ use crate::{ traits::{Class, UserData}, }; -use std::{marker::PhantomData, ptr::drop_in_place}; +use std::marker::PhantomData; +use physx_sys::UserDataField; #[rustfmt::skip] use physx_sys::{ phys_PxCreateDynamic, @@ -57,11 +58,11 @@ pub struct PxRigidDynamic { unsafe impl UserData for PxRigidDynamic { type UserData = U; - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -69,7 +70,7 @@ unsafe impl UserData for PxRigidDynamic { impl Drop for PxRigidDynamic { fn drop(&mut self) { unsafe { - drop_in_place(self.get_user_data_mut() as *mut _); + self.drop_and_dealloc_user_data(); PxRigidActor_release_mut(self.as_mut_ptr()); } } diff --git a/physx/src/rigid_static.rs b/physx/src/rigid_static.rs index 55fd8eed..d4f9d04b 100644 --- a/physx/src/rigid_static.rs +++ b/physx/src/rigid_static.rs @@ -2,7 +2,7 @@ // Copyright © 2019, Embark Studios, all rights reserved. // Created: 15 April 2019 -use std::{marker::PhantomData, ptr::drop_in_place}; +use std::marker::PhantomData; use crate::{ geometry::PxGeometry, @@ -14,6 +14,7 @@ use crate::{ traits::{Class, UserData}, }; +use physx_sys::UserDataField; #[rustfmt::skip] use physx_sys::{ phys_PxCreateStatic, @@ -32,11 +33,11 @@ pub struct PxRigidStatic { unsafe impl UserData for PxRigidStatic { type UserData = U; - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -44,7 +45,7 @@ unsafe impl UserData for PxRigidStatic { impl Drop for PxRigidStatic { fn drop(&mut self) { unsafe { - drop_in_place(self.get_user_data_mut() as *mut _); + self.drop_and_dealloc_user_data(); PxRigidActor_release_mut(self.as_mut_ptr()) } } diff --git a/physx/src/scene.rs b/physx/src/scene.rs index 40c80015..17e6c8ac 100644 --- a/physx/src/scene.rs +++ b/physx/src/scene.rs @@ -32,6 +32,7 @@ use std::{ ptr::{drop_in_place, null, null_mut}, }; +use physx_sys::UserDataField; // A glob import is super tempting, but the wrappers shadow the names of the physx_sys types, // so those types cannot be in scope. Plus, it easier to see what's been implemented. #[rustfmt::skip] @@ -175,11 +176,11 @@ where { type UserData = U; - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -214,7 +215,7 @@ where |_| (), // ArticulationLinks are dropped when the articulation they are in is dropped ) } - drop_in_place(self.get_user_data_mut() as *mut _); + self.drop_and_dealloc_user_data(); drop_in_place(PxScene_getSimulationEventCallback(self.as_ptr()) as *mut PxSimulationEventCallback); PxScene_release_mut(self.as_mut_ptr()); diff --git a/physx/src/shape.rs b/physx/src/shape.rs index 00f70fae..536cb71f 100644 --- a/physx/src/shape.rs +++ b/physx/src/shape.rs @@ -10,8 +10,9 @@ use crate::{ traits::{Class, UserData}, }; -use std::{marker::PhantomData, ptr::drop_in_place}; +use std::marker::PhantomData; +use physx_sys::UserDataField; #[rustfmt::skip] use physx_sys::{ PxFilterData, @@ -50,11 +51,11 @@ pub struct PxShape { unsafe impl UserData for PxShape { type UserData = U; - fn user_data_ptr(&self) -> &*mut std::ffi::c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut *mut std::ffi::c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.obj.userData } } @@ -62,7 +63,7 @@ unsafe impl UserData for PxShape { impl Drop for PxShape { fn drop(&mut self) { unsafe { - drop_in_place(self.get_user_data_mut()); + self.drop_and_dealloc_user_data(); use crate::base::RefCounted; self.release(); } diff --git a/physx/src/traits/descriptor.rs b/physx/src/traits/descriptor.rs index 5eda0d2a..4a7cf6f7 100644 --- a/physx/src/traits/descriptor.rs +++ b/physx/src/traits/descriptor.rs @@ -23,8 +23,9 @@ use crate::{ }; pub use physx_sys::PxSceneFlags as SceneFlags; +use physx_sys::UserDataField; -use std::{ffi::c_void, marker::PhantomData, mem::size_of, ptr::null_mut}; +use std::{marker::PhantomData, ptr::null_mut}; pub trait Descriptor

{ type Target; @@ -182,13 +183,7 @@ impl< frictionOffsetThreshold: self.friction_offset_threshold, ccdMaxSeparation: self.ccd_max_separation, flags: self.flags, - userData: if size_of::() > size_of::<*mut c_void>() { - // Too big to pack into a *mut c_void, kick it to the heap. - Box::into_raw(Box::new(self.user_data)) as *mut c_void - } else { - // DATA_SIZE <= VOID_SIZE - *(&self.user_data as *const U as *const *mut c_void) - }, + userData: UserDataField::new_with_data(self.user_data), solverBatchSize: self.solver_batch_size, solverArticulationBatchSize: self.solver_articulation_batch_size, maxBiasCoefficient: self.max_bias_coefficient, diff --git a/physx/src/traits/user_data.rs b/physx/src/traits/user_data.rs index 5f8da32c..83964d89 100644 --- a/physx/src/traits/user_data.rs +++ b/physx/src/traits/user_data.rs @@ -1,4 +1,4 @@ -use std::{ffi::c_void, mem::size_of}; +use physx_sys::UserDataField; /// UserData allows easy access and initialization of userData *mut c_void fields on Px objects. /// Not all Px objects with user data expose them as a field, so not all objects with user data can use this. @@ -8,75 +8,66 @@ use std::{ffi::c_void, mem::size_of}; /// all constructors of implementing types must call `init_user_data` during construction. /// If this does not happen, calling get_user_data or get_user_data_mut may return garbage data, or /// dereference an invalid pointer. If UserData is larger than a *mut ptr it will be stored on the heap, -/// and it may need to be explicitly dropped by turning the field back into a Box and droppig it. +/// and it may need to be explicitly dropped by turning the field back into a Box and dropping it. /// If UserData implements Drop, this may be as simple as calling `get_user_data_mut` and then calling drop(), /// but implementation is left to the concrete type's Drop impl. pub unsafe trait UserData: Sized { type UserData; /// Returns a reference to the userData field - fn user_data_ptr(&self) -> &*mut c_void; + fn user_data_ptr(&self) -> &UserDataField; + /// Returns a mutable reference to the userData field. - fn user_data_ptr_mut(&mut self) -> &mut *mut c_void; - - unsafe fn init_user_data(&mut self, user_data: Self::UserData) -> &mut Self { - if size_of::() > size_of::<*mut c_void>() { - // Too big to pack into a *mut c_void, kick it to the heap. - let data = Box::into_raw(Box::new(user_data)); - *(self.user_data_ptr_mut() as *mut *mut c_void as *mut *mut Self::UserData) = data; - } else { - // DATA_SIZE <= VOID_SIZE - *(self.user_data_ptr_mut() as *mut *mut c_void as *mut Self::UserData) = user_data; - } + fn user_data_ptr_mut(&mut self) -> &mut UserDataField; + + #[inline(always)] + fn init_user_data(&mut self, user_data: Self::UserData) -> &mut Self { + self.user_data_ptr_mut().initialize_with_data::(user_data); self } + /// # Safety + /// + /// The user data field must have previously been initialized via `init_user_data` + #[inline(always)] + unsafe fn drop_and_dealloc_user_data(&mut self) { + // SAFETY: same as function-level safety + unsafe { self.user_data_ptr_mut().drop_and_dealloc::() } + } + /// # Safety /// /// The user data field must have previously been initialized via `init_user_data`. - unsafe fn get_user_data(this: &Self) -> &Self::UserData { - unsafe { - if size_of::() > size_of::<*mut c_void>() { - &*((*this.user_data_ptr()) as *const Self::UserData) - } else { - // DATA_SIZE <= VOID_SIZE - // Data is stored directly in the userData field. - &*(this.user_data_ptr() as *const *mut c_void as *const Self::UserData) - } - } + #[inline(always)] + unsafe fn get_user_data(&self) -> &Self::UserData { + unsafe { self.user_data_ptr().data_ref::() } } /// # Safety /// /// The user data field must have previously been initialized via `init_user_data`. - unsafe fn get_user_data_mut(this: &mut Self) -> &mut Self::UserData { - unsafe { - if size_of::() > size_of::<*mut c_void>() { - // Data is stored in a Box on the heap, and userData is just a pointer to it. - &mut *((*this.user_data_ptr_mut()) as *mut Self::UserData) - } else { - // DATA_SIZE <= VOID_SIZE - // Data is stored directly in the userData field. - &mut *(this.user_data_ptr_mut() as *mut *mut c_void as *mut Self::UserData) - } - } + #[inline(always)] + unsafe fn get_user_data_mut(&mut self) -> &mut Self::UserData { + unsafe { self.user_data_ptr_mut().data_ref_mut::() } } } #[cfg(test)] mod tests { - use std::{ffi::c_void, fmt::Debug, marker::PhantomData, ptr::null_mut}; + use std::{fmt::Debug, marker::PhantomData}; + + use physx_sys::UserDataField; use super::UserData; struct TestUserData { - user_data: *mut c_void, + user_data: UserDataField, phantom: PhantomData, } impl Default for TestUserData { fn default() -> Self { Self { - user_data: null_mut(), + user_data: Default::default(), phantom: PhantomData, } } @@ -85,11 +76,11 @@ mod tests { unsafe impl UserData for TestUserData { type UserData = U; - fn user_data_ptr(&self) -> &*mut c_void { + fn user_data_ptr(&self) -> &UserDataField { &self.user_data } - fn user_data_ptr_mut(&mut self) -> &mut *mut c_void { + fn user_data_ptr_mut(&mut self) -> &mut UserDataField { &mut self.user_data } } @@ -101,14 +92,26 @@ mod tests { assert_eq!(UserData::get_user_data(&object), &user_data); assert_eq!(UserData::get_user_data_mut(&mut object), &user_data); + + object.drop_and_dealloc_user_data(); } } + #[repr(align(16))] + #[derive(Debug, PartialEq, Eq, Clone, Copy)] + struct WeirdZst([u128; 0]); + + // should be run through miri. + // ``` + // $ cargo +nightly miri test user_data + // ``` #[test] fn test_user_data() { do_test(()); // unit type + do_test(WeirdZst([])); // weird zst with high align do_test(100u8); // smaller than pointer do_test(100usize); // same size as pointer + do_test(Box::new([1u8; 100])); // a pointer which should not leak do_test([100usize; 4]); // larger than pointer } } From 475ed900a7be8175e5e0cb2ba78992e8489e7cbd Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 9 Nov 2023 00:03:33 +0100 Subject: [PATCH 2/5] Find all the other userData and change those too --- physx-sys/pxbind/src/consumer.rs | 7 +- physx-sys/pxbind/src/consumer/record.rs | 13 +- .../structgen__all_the_things-3.snap | 74 ++-- .../snapshots/structgen__many_things-3.snap | 2 +- physx-sys/src/generated/unix/structgen.rs | 82 ++-- .../x86_64-pc-windows-msvc/structgen.rs | 82 ++-- physx-sys/src/lib.rs | 361 +++++++++++++----- physx-sys/src/physx_generated.rs | 6 +- physx/examples/profiler.rs | 9 +- physx/src/articulation_link.rs | 16 +- physx/src/articulation_reduced_coordinate.rs | 16 +- physx/src/controller.rs | 158 +++++--- physx/src/foundation.rs | 58 ++- physx/src/material.rs | 16 +- physx/src/physics.rs | 6 +- physx/src/physics/assert_handler.rs | 15 +- physx/src/physics/error_callback.rs | 15 +- physx/src/physics/profiler.rs | 8 +- physx/src/rigid_dynamic.rs | 16 +- physx/src/rigid_static.rs | 16 +- physx/src/scene.rs | 16 +- physx/src/shape.rs | 16 +- physx/src/simulation_event_callback.rs | 89 ++--- physx/src/traits.rs | 2 +- physx/src/traits/descriptor.rs | 10 +- physx/src/traits/user_data.rs | 74 ++-- 26 files changed, 713 insertions(+), 470 deletions(-) diff --git a/physx-sys/pxbind/src/consumer.rs b/physx-sys/pxbind/src/consumer.rs index d39291f7..9a9b6c72 100644 --- a/physx-sys/pxbind/src/consumer.rs +++ b/physx-sys/pxbind/src/consumer.rs @@ -729,6 +729,8 @@ pub enum Builtin { // on the C++ side, `void*`, but we want to be able to pack arbitrary data into the space // available so we treat it as a separate type so we can do that properly in the Rust side UserData, + // same as above but `const void* + ConstUserData, } impl Builtin { @@ -761,7 +763,8 @@ impl Builtin { Self::Mat34V => "glam::Affine3A", Self::Mat34 => "Affine", Self::Mat44V | Self::Mat44 => "PxMat44", - Self::UserData => "UserDataField", + Self::UserData => "UserData", + Self::ConstUserData => "ConstUserData", } } @@ -798,6 +801,7 @@ impl Builtin { Self::Mat44V => "physx_Mat44V_Pod", Self::Mat44 => "physx_PxMat44_Pod", Self::UserData => "void*", + Self::ConstUserData => "const void*", } } @@ -834,6 +838,7 @@ impl Builtin { Self::Mat44V => "physx::PxMat44V", Self::Mat44 => "physx::PxMat44", Self::UserData => "void*", + Self::ConstUserData => "const void*", } } diff --git a/physx-sys/pxbind/src/consumer/record.rs b/physx-sys/pxbind/src/consumer/record.rs index 8b410423..d0cddf92 100644 --- a/physx-sys/pxbind/src/consumer/record.rs +++ b/physx-sys/pxbind/src/consumer/record.rs @@ -714,11 +714,15 @@ impl<'ast> super::AstConsumer<'ast> { } let kind = if name == "userData" || name == "mUserData" { - QualType::Builtin(Builtin::UserData) + if kind.qual_type.contains("const") { + QualType::Builtin(Builtin::ConstUserData) + } else { + QualType::Builtin(Builtin::UserData) + } } else { - self - .parse_type(kind, template_types) - .with_context(|| format!("failed to parse type for {rname}::{name}"))? + self.parse_type(kind, template_types).with_context(|| { + format!("failed to parse type for {rname}::{name}") + })? }; // if matches!(&kind, QualType::FunctionPointer) { @@ -727,7 +731,6 @@ impl<'ast> super::AstConsumer<'ast> { let is_reference = matches!(kind, QualType::Reference { .. }); - fields.push(FieldBinding { name, kind, diff --git a/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap b/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap index 39d0336a..1d24648f 100644 --- a/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap +++ b/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap @@ -563,13 +563,13 @@ pub struct PxSimulationTetrahedronMeshData { #[repr(C)] pub struct PxActor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxAggregate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -894,31 +894,31 @@ pub struct PxArticulationTendonLimit { #[repr(C)] pub struct PxArticulationAttachment { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationTendonJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationSpatialTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationFixedTendon { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -971,31 +971,31 @@ pub struct PxArticulationCache { #[repr(C)] pub struct PxArticulationSensor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationJointReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxShape { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxRigidActor { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1006,13 +1006,13 @@ pub struct PxNodeIndex { #[repr(C)] pub struct PxRigidBody { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxArticulationLink { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1041,7 +1041,7 @@ pub struct PxConstraintShaderTable { #[repr(C)] pub struct PxConstraint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1150,13 +1150,13 @@ pub struct PxContactModifyPair { #[repr(C)] pub struct PxBaseMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxFEMMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1176,7 +1176,7 @@ pub struct PxParticleRigidFilterPair { #[repr(C)] pub struct PxMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1220,7 +1220,7 @@ pub struct PxParticleSpring { #[repr(C)] pub struct PxParticleMaterial { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1349,13 +1349,13 @@ pub struct PxQueryFilterData { #[repr(C)] pub struct PxRigidDynamic { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxRigidStatic { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1500,7 +1500,7 @@ pub struct PxSceneDesc { pub flags: PxSceneFlags, pub cpuDispatcher: *mut PxCpuDispatcher, pub structgen_pad2: [u8; 8], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, pub solverBatchSize: u32, pub solverArticulationBatchSize: u32, pub nbContactDataBlocks: u32, @@ -1604,7 +1604,7 @@ pub struct PxDominanceGroupPair { #[repr(C)] pub struct PxScene { pub structgen_pad0: [u8; 8], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1827,7 +1827,7 @@ pub struct PxControllerObstacleHit { pub dir: PxVec3, pub length: f32, pub structgen_pad0: [u8; 4], - pub userData: *const std::ffi::c_void, + pub userData: ConstUserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1861,7 +1861,7 @@ pub struct PxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, pub structgen_pad4: [u8; 8], } #[derive(Clone, Copy)] @@ -1887,7 +1887,7 @@ pub struct PxBoxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, pub structgen_pad4: [u8; 4], pub halfHeight: f32, pub halfSideExtent: f32, @@ -1916,7 +1916,7 @@ pub struct PxCapsuleControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, pub structgen_pad4: [u8; 4], pub radius: f32, pub height: f32, @@ -2046,7 +2046,7 @@ pub struct PxDefaultFileInputData { #[repr(C)] pub struct PxJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -2058,7 +2058,7 @@ pub struct PxSpring { #[repr(C)] pub struct PxDistanceJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -2072,13 +2072,13 @@ pub struct PxJacobianRow { #[repr(C)] pub struct PxContactJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxFixedJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -2149,19 +2149,19 @@ pub struct PxJointLimitPyramid { #[repr(C)] pub struct PxPrismaticJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxRevoluteJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxSphericalJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -2175,19 +2175,19 @@ pub struct PxD6JointDrive { #[repr(C)] pub struct PxD6Joint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxGearJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] pub struct PxRackAndPinionJoint { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[derive(Clone, Copy)] #[repr(C)] diff --git a/physx-sys/pxbind/tests/snapshots/structgen__many_things-3.snap b/physx-sys/pxbind/tests/snapshots/structgen__many_things-3.snap index 19407a2b..24b75971 100644 --- a/physx-sys/pxbind/tests/snapshots/structgen__many_things-3.snap +++ b/physx-sys/pxbind/tests/snapshots/structgen__many_things-3.snap @@ -274,7 +274,7 @@ pub struct PxGeometryHolder { #[repr(C)] pub struct PxShape { pub structgen_pad0: [u8; 16], - pub userData: *mut std::ffi::c_void, + pub userData: UserData, } #[cfg(test)] mod sizes { diff --git a/physx-sys/src/generated/unix/structgen.rs b/physx-sys/src/generated/unix/structgen.rs index 3b2af626..9719a7c1 100644 --- a/physx-sys/src/generated/unix/structgen.rs +++ b/physx-sys/src/generated/unix/structgen.rs @@ -653,14 +653,14 @@ pub struct PxSimulationTetrahedronMeshData { #[repr(C)] pub struct PxActor { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxAggregate { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1007,35 +1007,35 @@ pub struct PxArticulationTendonLimit { #[repr(C)] pub struct PxArticulationAttachment { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendonJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendon { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationSpatialTendon { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationFixedTendon { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1093,35 +1093,35 @@ pub struct PxArticulationCache { #[repr(C)] pub struct PxArticulationSensor { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationJointReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxShape { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidActor { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1134,14 +1134,14 @@ pub struct PxNodeIndex { #[repr(C)] pub struct PxRigidBody { pub structgen_pad0: [u8; 16], - pub userData: UserDataField + pub userData: UserData } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationLink { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1174,7 +1174,7 @@ pub struct PxConstraintShaderTable { #[repr(C)] pub struct PxConstraint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1293,14 +1293,14 @@ pub struct PxContactModifyPair { #[repr(C)] pub struct PxBaseMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFEMMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1323,7 +1323,7 @@ pub struct PxParticleRigidFilterPair { #[repr(C)] pub struct PxMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1372,7 +1372,7 @@ pub struct PxParticleSpring { #[repr(C)] pub struct PxParticleMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1514,14 +1514,14 @@ pub struct PxQueryFilterData { #[repr(C)] pub struct PxRigidDynamic { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidStatic { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1542,7 +1542,7 @@ pub struct PxSceneQueryDesc { #[repr(C)] pub struct PxBroadPhaseRegion { pub mBounds: PxBounds3, - pub mUserData: UserDataField, + pub mUserData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1677,7 +1677,7 @@ pub struct PxSceneDesc { pub flags: PxSceneFlags, pub cpuDispatcher: *mut PxCpuDispatcher, pub structgen_pad2: [u8; 8], - pub userData: UserDataField, + pub userData: UserData, pub solverBatchSize: u32, pub solverArticulationBatchSize: u32, pub nbContactDataBlocks: u32, @@ -1787,7 +1787,7 @@ pub struct PxDominanceGroupPair { #[repr(C)] pub struct PxScene { pub structgen_pad0: [u8; 8], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1936,7 +1936,7 @@ pub struct PxExtendedVec3 { #[repr(C)] pub struct PxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: UserDataField, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, } @@ -1945,7 +1945,7 @@ pub struct PxObstacle { #[repr(C)] pub struct PxBoxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: UserDataField, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfExtents: PxVec3, @@ -1956,7 +1956,7 @@ pub struct PxBoxObstacle { #[repr(C)] pub struct PxCapsuleObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: UserDataField, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfHeight: f32, @@ -2034,7 +2034,7 @@ pub struct PxControllerObstacleHit { pub dir: PxVec3, pub length: f32, pub structgen_pad0: [u8; 4], - pub userData: *const std::ffi::c_void, + pub userData: ConstUserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2070,7 +2070,7 @@ pub struct PxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: UserDataField, + pub userData: UserData, pub structgen_pad4: [u8; 8], } #[derive(Clone, Copy)] @@ -2097,7 +2097,7 @@ pub struct PxBoxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: UserDataField, + pub userData: UserData, pub structgen_pad4: [u8; 4], pub halfHeight: f32, pub halfSideExtent: f32, @@ -2127,7 +2127,7 @@ pub struct PxCapsuleControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: UserDataField, + pub userData: UserData, pub structgen_pad4: [u8; 4], pub radius: f32, pub height: f32, @@ -2272,7 +2272,7 @@ pub struct PxDefaultFileInputData { #[repr(C)] pub struct PxJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2286,7 +2286,7 @@ pub struct PxSpring { #[repr(C)] pub struct PxDistanceJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2302,14 +2302,14 @@ pub struct PxJacobianRow { #[repr(C)] pub struct PxContactJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFixedJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2387,21 +2387,21 @@ pub struct PxJointLimitPyramid { #[repr(C)] pub struct PxPrismaticJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRevoluteJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxSphericalJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2417,21 +2417,21 @@ pub struct PxD6JointDrive { #[repr(C)] pub struct PxD6Joint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxGearJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRackAndPinionJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] diff --git a/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs b/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs index 8596b3b7..7405f613 100644 --- a/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs +++ b/physx-sys/src/generated/x86_64-pc-windows-msvc/structgen.rs @@ -653,14 +653,14 @@ pub struct PxSimulationTetrahedronMeshData { #[repr(C)] pub struct PxActor { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxAggregate { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1012,35 +1012,35 @@ pub struct PxArticulationTendonLimit { #[repr(C)] pub struct PxArticulationAttachment { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendonJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationTendon { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationSpatialTendon { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationFixedTendon { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1098,35 +1098,35 @@ pub struct PxArticulationCache { #[repr(C)] pub struct PxArticulationSensor { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationJointReducedCoordinate { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxShape { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidActor { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1139,14 +1139,14 @@ pub struct PxNodeIndex { #[repr(C)] pub struct PxRigidBody { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxArticulationLink { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1179,7 +1179,7 @@ pub struct PxConstraintShaderTable { #[repr(C)] pub struct PxConstraint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1298,14 +1298,14 @@ pub struct PxContactModifyPair { #[repr(C)] pub struct PxBaseMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFEMMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1328,7 +1328,7 @@ pub struct PxParticleRigidFilterPair { #[repr(C)] pub struct PxMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1377,7 +1377,7 @@ pub struct PxParticleSpring { #[repr(C)] pub struct PxParticleMaterial { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1519,14 +1519,14 @@ pub struct PxQueryFilterData { #[repr(C)] pub struct PxRigidDynamic { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRigidStatic { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1547,7 +1547,7 @@ pub struct PxSceneQueryDesc { #[repr(C)] pub struct PxBroadPhaseRegion { pub mBounds: PxBounds3, - pub mUserData: UserDataField, + pub mUserData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1682,7 +1682,7 @@ pub struct PxSceneDesc { pub flags: PxSceneFlags, pub cpuDispatcher: *mut PxCpuDispatcher, pub structgen_pad2: [u8; 8], - pub userData: UserDataField, + pub userData: UserData, pub solverBatchSize: u32, pub solverArticulationBatchSize: u32, pub nbContactDataBlocks: u32, @@ -1792,7 +1792,7 @@ pub struct PxDominanceGroupPair { #[repr(C)] pub struct PxScene { pub structgen_pad0: [u8; 8], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -1941,7 +1941,7 @@ pub struct PxExtendedVec3 { #[repr(C)] pub struct PxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: UserDataField, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, } @@ -1950,7 +1950,7 @@ pub struct PxObstacle { #[repr(C)] pub struct PxBoxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: UserDataField, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfExtents: PxVec3, @@ -1961,7 +1961,7 @@ pub struct PxBoxObstacle { #[repr(C)] pub struct PxCapsuleObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: UserDataField, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfHeight: f32, @@ -2039,7 +2039,7 @@ pub struct PxControllerObstacleHit { pub dir: PxVec3, pub length: f32, pub structgen_pad0: [u8; 4], - pub userData: *const std::ffi::c_void, + pub userData: ConstUserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2075,7 +2075,7 @@ pub struct PxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: UserDataField, + pub userData: UserData, pub structgen_pad4: [u8; 8], } #[derive(Clone, Copy)] @@ -2102,7 +2102,7 @@ pub struct PxBoxControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: UserDataField, + pub userData: UserData, pub structgen_pad4: [u8; 8], pub halfHeight: f32, pub halfSideExtent: f32, @@ -2133,7 +2133,7 @@ pub struct PxCapsuleControllerDesc { pub registerDeletionListener: bool, pub clientID: u8, pub structgen_pad3: [u8; 6], - pub userData: UserDataField, + pub userData: UserData, pub structgen_pad4: [u8; 8], pub radius: f32, pub height: f32, @@ -2279,7 +2279,7 @@ pub struct PxDefaultFileInputData { #[repr(C)] pub struct PxJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2293,7 +2293,7 @@ pub struct PxSpring { #[repr(C)] pub struct PxDistanceJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2309,14 +2309,14 @@ pub struct PxJacobianRow { #[repr(C)] pub struct PxContactJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxFixedJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2394,21 +2394,21 @@ pub struct PxJointLimitPyramid { #[repr(C)] pub struct PxPrismaticJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRevoluteJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxSphericalJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] @@ -2424,21 +2424,21 @@ pub struct PxD6JointDrive { #[repr(C)] pub struct PxD6Joint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxGearJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] #[repr(C)] pub struct PxRackAndPinionJoint { pub structgen_pad0: [u8; 16], - pub userData: UserDataField, + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] diff --git a/physx-sys/src/lib.rs b/physx-sys/src/lib.rs index 4f9465f7..e04f123c 100644 --- a/physx-sys/src/lib.rs +++ b/physx-sys/src/lib.rs @@ -197,48 +197,133 @@ pub const fn version(major: u32, minor: u32, patch: u32) -> u32 { } const fn can_pack_into_pointer() -> bool { - core::mem::size_of::() <= core::mem::size_of::<*mut c_void>() && core::mem::align_of::() <= core::mem::align_of::<*mut c_void>() + core::mem::size_of::() <= core::mem::size_of::<*mut c_void>() + && core::mem::align_of::() <= core::mem::align_of::<*mut c_void>() } -/// The type of `userData` fields, which is a `void*` pointer in the PhysX api, but which -/// we turn into this `union` on the Rust side to be able to pack small user data types inline into -/// the space of the pointer itself when possible. -// -// NOTE: In a world where cross-language C-to-Rust link-time optimization existed and we statically -// linked PhysX, this could possibly break since on the PhsyX side it's a `void*` which is -// `noundef` under Clang whereas we explicitly allow types with arbitrary layout (including -// padding) to be packed as long as they have the necessary size an alignment. But, cross-lang -// LTO like that does not currently exist and is unlikely to happen, so it's probably Fine TM. +/// The type of `const void* userData` parameters in functions. Only allows shared access to the +/// underlying data. Modification is still possible for data on the heap by using internal +/// mutability. +#[repr(transparent)] +#[derive(Clone, Copy)] +pub struct ConstUserData(UserData); + +impl ConstUserData { + /// Get a reference to previously-initialized data of type `T`. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `new_maybe_packed` or `intialize_maybe_packed` with + /// data of the same exact `T` on the `UserData` that this came from, and not have already + /// called `drop_and_dealloc` on `self` since doing so. + #[inline(always)] + pub unsafe fn maybe_packed_data_ref(&self) -> &T { + self.0.maybe_packed_data_ref::() + } + + /// Get a reference to previously-initialized data of type `T` which you know was initialized + /// on the heap (i.e. through `new_on_heap` or `initialize_on_heap`). + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `new_on_heap` or `initialize_on_heap` + /// with data of the same exact `T` on the `UserData` that this came from, and not have already + /// called `heap_drop_and_dealloc` on `self` since doing so. + #[inline(always)] + pub unsafe fn heap_data_ref(&self) -> &T { + self.0.heap_data_ref::() + } +} + +/// The type of `void* userData` fields and function parameters, which is a `void*` pointer in the +/// PhysX api, but which we turn into this `union` on the Rust side to be able to pack small user +/// data types inline into the space of the pointer itself when possible. +/// +/// In a given situation, you should choose whether you want to exploit the idea of trying to pack +/// data into the size of the pointer or not. If so, use the `maybe_packed` family of methods. +/// If not, use the `heap` family of methods. +/// +/// NOTE: In a world where cross-language C-to-Rust link-time optimization existed and we statically +/// linked PhysX, this could possibly break since on the PhsyX side it's a `void*` which is +/// `noundef` under Clang whereas we explicitly allow types with arbitrary layout (including +/// padding) to be packed as long as they have the necessary size an alignment. But, cross-lang +/// LTO like that does not currently exist and is unlikely to happen, so it's Fine TM. #[repr(C)] #[derive(Clone, Copy)] -#[cfg_attr(feature = "debug-structs", derive(Debug))] -pub union UserDataField { +pub union UserData { heap_pointer: *mut c_void, packed_data: MaybeUninit<*mut c_void>, } -impl Default for UserDataField { +impl Default for UserData { #[inline(always)] fn default() -> Self { - Self::new_uninit() + Self::null() } } -impl UserDataField { - /// Create a new `UserDataField` which is immediately initialized with the given `data`. See - /// [`UserDataField::initialize_with_data`] for more details. - pub fn new_with_data(data: T) -> Self { - let mut ret = Self::new_uninit(); - ret.initialize_with_data(data); +impl UserData { + /// Create a new `UserData` which is immediately initialized with the given `data`. + /// + /// See [`UserData::initialize_maybe_packed`] for more details. + #[inline] + pub fn new_maybe_packed(data: T) -> Self { + let mut ret = UserData { + packed_data: MaybeUninit::uninit(), + }; + ret.initialize_maybe_packed(data); + ret + } + + /// Create a new `UserData` by placing `data` of type `T` on the heap and then making `self` + /// a pointer to that data. + /// + /// See [`UserData::initialize_on_heap`] for more information. + #[inline] + pub fn new_on_heap(data: T) -> Self { + let mut ret = UserData { + packed_data: MaybeUninit::uninit(), + }; + ret.initialize_on_heap(data); ret } - /// Create a new `UserDataField` which is uninitialized. Initialized it before use! + /// Create a new `UserData` which is zeroed, i.e. a null pointer. You still must + /// initialize it before using any of the data accessor methods! #[inline(always)] - pub fn new_uninit() -> Self { - UserDataField { packed_data: MaybeUninit::uninit() } + pub fn null() -> Self { + UserData { + heap_pointer: core::ptr::null_mut(), + } + } + + /// Returns true if `T` would be packed when using the maybe-packed initialization methods + /// on `UserData` + #[inline(always)] + pub const fn can_pack() -> bool { + can_pack_into_pointer::() + } + /// Initialize the field by placing `data` of type `T` on the heap and then making `self` + /// a pointer to that data. + /// + /// This is useful in cases where a `user_data` will be passed back through a callback function + /// and you want to be able to guarantee you can modify the actual stored user data. In such + /// cases, if we packed the data into the `void*` pointer, that data is passed by-value into + /// our callback function and so any modifications that happen to it inline wouldn't actually + /// be written back to where the data is stored in memory. + /// + /// In order to access it, you should use `heap_data_ref`, `heap_data_mut`, and dealloc/drop + /// it with `heap_drop_and_dealloc`. This is because if `T`'s layout can fit within the + /// size of a pointer, the regular `data_ref`, `data_mut`, and `drop_and_dealloc` functions + /// will assume `self` has been initialized as packed data, which would result in + /// undefined behavior when `self` (which is a pointer) is interpreted as a `T`. + #[inline(always)] + pub fn initialize_on_heap(&mut self, data: T) { + let heap_ptr = Box::into_raw(Box::new(data)); + self.heap_pointer = heap_ptr.cast(); } + /// Initialize the field with arbitrary user data of type `T`. /// /// If the data can be packed into the space of a `*mut c_void` (its size and alignement are @@ -248,14 +333,14 @@ impl UserDataField { /// /// You can access data you've initialized using the other functions available on this type. /// If `T` could not be packed and was put on the heap, you must call - /// [`UserDataField::drop_and_dealloc`] with the same `T` in order to drop and deallocate it, + /// [`UserData::drop_and_dealloc`] with the same `T` in order to drop and deallocate it, /// if you care about it being dropped or dealloced (if not, the memory will leak). /// /// If you call this when data has already been initialized, it will be clobbered if /// it was written inline and if it was on the heap the old data will be leaked and replaced /// with the new data. #[inline] - pub fn initialize_with_data(&mut self, data: T) { + pub fn initialize_maybe_packed(&mut self, data: T) { if can_pack_into_pointer::() { // SAFETY: We've checked T's size and align are both < *mut c_void, which `self` must // be at least size/align of @@ -263,8 +348,7 @@ impl UserDataField { core::ptr::write(core::ptr::addr_of_mut!(self.packed_data).cast::(), data); } } else { - let heap_ptr = Box::into_raw(Box::new(data)); - self.heap_pointer = heap_ptr.cast(); + self.initialize_on_heap::(data); } } @@ -272,42 +356,97 @@ impl UserDataField { /// /// # Safety /// - /// You must have previously initialized `self` by calling `initialize_with_data` with data - /// of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since + /// You must have previously initialized `self` by calling `new_maybe_packed` or `initialize_maybe_packed` with + /// data of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since /// doing so. #[inline(always)] - pub unsafe fn data_ref(&self) -> &T { + pub unsafe fn maybe_packed_data_ref(&self) -> &T { if can_pack_into_pointer::() { // SAFETY: if function level safety is true, we must have initialized a valid T inside - // self as packed, since we use the same check in `initialize_with_data` + // self as packed, since we use the same check in `auto_initialize_with_data` unsafe { &*(core::ptr::addr_of!(self.packed_data).cast::()) } } else { // SAFETY: if function level safety is true, we must have initialized a valid T on - // the heap which we point to, since we use the same check in `initialize_with_data` - unsafe { &*(self.heap_pointer.cast::().cast_const()) } + // the heap which we point to, since we use the same check in `auto_initialize_with_data` + self.heap_data_ref::() } } + /// Get a reference to previously-initialized data of type `T` which you know was initialized + /// on the heap (i.e. through `new_on_heap` or `initialize_on_heap`). + /// + /// Note that the lifetime of the returned reference is scoped to the borrow of `self`, which is + /// the most conservative estimate of its lifetime. However, in some cases this is overly + /// restrictive. In that case you can either use `&mut *slf.as_mut_ptr()` and deref or + /// `transmute` the returned reference from this function to extend the lifetime if you know + /// doing so is valid. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `new_on_heap` or `initialize_on_heap` + /// with data of the same exact `T` on the `UserData` that this came from, and not have already + /// called `heap_drop_and_dealloc` on `self` since doing so. + #[inline(always)] + pub unsafe fn heap_data_ref(&self) -> &T { + unsafe { &*(self.heap_pointer.cast::().cast_const()) } + } + /// Get a reference to previously-initialized data of type `T`. /// /// # Safety /// - /// You must have previously initialized `self` by calling `initialize_with_data` with data - /// of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since + /// You must have previously initialized `self` by calling `new_maybe_packed` or `initialize_maybe_packed` with + /// data of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since /// doing so. #[inline(always)] - pub unsafe fn data_ref_mut(&mut self) -> &mut T { + pub unsafe fn maybe_packed_data_mut(&mut self) -> &mut T { if can_pack_into_pointer::() { // SAFETY: if function level safety is true, we must have initialized a valid T inside - // self as packed, since we use the same check in `initialize_with_data` + // self as packed, since we use the same check in `initialize_maybe_packed` unsafe { &mut *(core::ptr::addr_of_mut!(self.packed_data).cast::()) } } else { // SAFETY: if function level safety is true, we must have initialized a valid T on - // the heap which we point to, since we use the same check in `initialize_with_data` - unsafe { &mut *(self.heap_pointer.cast::()) } + // the heap which we point to, since we use the same check in `initialize_maybe_packed` + self.heap_data_mut::() } } + /// Get a reference to previously-initialized data of type `T` which you know was initialized + /// on the heap (i.e. through `new_on_heap` or `initialize_on_heap`). + /// + /// Note that the lifetime of the returned reference is scoped to the borrow of `self`, which is + /// the most conservative estimate of its lifetime. However, in some cases this is overly + /// restrictive. In that case you can either use `&mut *slf.as_mut_ptr()` and deref or + /// `transmute` the returned reference from this function to extend the lifetime if you know + /// doing so is valid. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `new_on_heap` or `initialize_on_heap` + /// with data of the same exact `T` on the `UserData` that this came from, and not have already + /// called `heap_drop_and_dealloc` on `self` since doing so. + #[inline(always)] + pub unsafe fn heap_data_mut(&mut self) -> &mut T { + unsafe { &mut *(self.heap_pointer.cast::()) } + } + + /// Drop and deallocate the space that was allocated for the data on the heap. + /// + /// # Safety + /// + /// You must have previously initialized `self` by calling `new_on_heap` or `initialize_on_heap` + /// with data of the same exact `T`, and not have already called `drop_and_dealloc` on `self` + /// since doing so. + #[inline] + pub unsafe fn heap_drop_and_dealloc(&mut self) { + // SAFETY: self is a heap_pointer and must have been initialized due to function safety + let ptr = unsafe { self.heap_pointer }.cast::(); + // SAFETY: we must have constructed the value pointed to by `ptr` by putting it in a box + // if the function level safety is met. + let reconsructed_box = unsafe { Box::from_raw(ptr) }; + drop(reconsructed_box); + } + /// Drop and deallocate the space that was allocated for the data on the heap, if there was /// any. /// @@ -316,74 +455,95 @@ impl UserDataField { /// /// # Safety /// - /// You must have previously initialized `self` by calling `initialize_with_data` with data - /// of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since + /// You must have previously initialized `self` by calling `new_maybe_packed` or `initialize_maybe_packed` with + /// data of the same exact `T`, and not have already called `drop_and_dealloc` on `self` since /// doing so. - #[inline] - pub unsafe fn drop_and_dealloc(&mut self) { - if !can_pack_into_pointer::() { - // SAFETY: self is a heap_pointer and must have been initialized due to function safety - let ptr = unsafe { self.heap_pointer }.cast::(); + #[inline(always)] + pub unsafe fn maybe_packed_drop_and_dealloc(&mut self) { + if can_pack_into_pointer::() { + // SAFETY: self is a packed T and has not been dropped according to function safety + // and the fact we use the same check in `initialize_maybe_packed` + unsafe { core::ptr::drop_in_place(self.maybe_packed_data_mut::()) } + } else { // SAFETY: we must have constructed the value pointed to by `ptr` by putting it in a box // if the function level safety is met. - let reconsructed_box = unsafe { Box::from_raw(ptr) }; - drop(reconsructed_box); - } else { - unsafe { - core::ptr::drop_in_place(self.data_ref_mut::()) - } + unsafe { self.heap_drop_and_dealloc::() } } } + + /// Interpret `self` as a `*mut T` + /// + /// # Safety + /// + /// `self` must have been previously initialized as a pointer, i.e. through one of the + /// heap initialization functions or [`UserData::null`]. It **must not** contain any + /// uninit bytes, i.e. [`UserData::uninit`] or writing a `T` that is not a pointer packed + /// into `self` + #[inline(always)] + pub unsafe fn as_mut_ptr(&mut self) -> *mut T { + self.heap_pointer.cast::() + } + + /// Interpret `self` as a `*const T` + /// + /// # Safety + /// + /// `self` must have been previously initialized as a pointer, i.e. through one of the + /// heap initialization functions or [`UserData::null`]. It **must not** contain any + /// uninit bytes, i.e. [`UserData::uninit`] or writing a `T` that is not a pointer packed + /// into `self` + #[inline(always)] + pub unsafe fn as_ptr(&self) -> *const T { + self.heap_pointer.cast::().cast_const() + } + + /// Interpret `self` as a `*const c_void` and check if it is null. + /// + /// # Safety + /// + /// `self` must have been previously initialized as a pointer, i.e. through one of the + /// heap initialization functions or [`UserData::null`]. It **must not** contain any + /// uninit bytes, i.e. [`UserData::uninit`] or writing a `T` that is not a pointer packed + /// into `self` + #[inline(always)] + pub unsafe fn is_null(&self) -> bool { + self.as_ptr::().is_null() + } } + pub type CollisionCallback = - unsafe extern "C" fn(*mut c_void, *const PxContactPairHeader, *const PxContactPair, u32); + unsafe extern "C" fn(UserData, *const PxContactPairHeader, *const PxContactPair, u32); -pub type TriggerCallback = unsafe extern "C" fn(*mut c_void, *const PxTriggerPair, u32); +pub type TriggerCallback = unsafe extern "C" fn(UserData, *const PxTriggerPair, u32); -pub type ConstraintBreakCallback = unsafe extern "C" fn(*mut c_void, *const PxConstraintInfo, u32); +pub type ConstraintBreakCallback = unsafe extern "C" fn(UserData, *const PxConstraintInfo, u32); -pub type WakeSleepCallback = unsafe extern "C" fn(*mut c_void, *const *const PxActor, u32, bool); +pub type WakeSleepCallback = unsafe extern "C" fn(UserData, *const *const PxActor, u32, bool); pub type AdvanceCallback = - unsafe extern "C" fn(*mut c_void, *const *const PxRigidBody, *const PxTransform, u32); + unsafe extern "C" fn(UserData, *const *const PxRigidBody, *const PxTransform, u32); // Function pointers in Rust are normally not nullable (which is why they don't require unsafe to call) // but we need them to be, so we simply wrap them in Option<>. An Option is luckily represented // by the compiler as a simple pointer with null representing None, so this is compatible with the C struct. #[repr(C)] +#[derive(Default)] pub struct SimulationEventCallbackInfo { // Callback for collision events. pub collision_callback: Option, - pub collision_user_data: *mut c_void, + pub collision_user_data: UserData, // Callback for trigger shape events (an object entered or left a trigger shape). pub trigger_callback: Option, - pub trigger_user_data: *mut c_void, + pub trigger_user_data: UserData, // Callback for when a constraint breaks (such as a joint with a force limit) pub constraint_break_callback: Option, - pub constraint_break_user_data: *mut c_void, + pub constraint_break_user_data: UserData, // Callback for when an object falls asleep or is awoken. pub wake_sleep_callback: Option, - pub wake_sleep_user_data: *mut c_void, + pub wake_sleep_user_data: UserData, // Callback to get the next pose early for objects (if flagged with eENABLE_POSE_INTEGRATION_PREVIEW). pub advance_callback: Option, - pub advance_user_data: *mut c_void, -} - -impl Default for SimulationEventCallbackInfo { - fn default() -> Self { - Self { - collision_callback: None, - collision_user_data: std::ptr::null_mut(), - trigger_callback: None, - trigger_user_data: std::ptr::null_mut(), - constraint_break_callback: None, - constraint_break_user_data: std::ptr::null_mut(), - wake_sleep_callback: None, - wake_sleep_user_data: std::ptr::null_mut(), - advance_callback: None, - advance_user_data: std::ptr::null_mut(), - } - } + pub advance_user_data: UserData, } pub type RaycastHitCallback = unsafe extern "C" fn( @@ -391,11 +551,11 @@ pub type RaycastHitCallback = unsafe extern "C" fn( *const PxFilterData, *const PxShape, hit_flags: u32, - *const c_void, + ConstUserData, ) -> PxQueryHitType; pub type PostFilterCallback = - unsafe extern "C" fn(*const PxFilterData, *const PxQueryHit, *const c_void) -> PxQueryHitType; + unsafe extern "C" fn(*const PxFilterData, *const PxQueryHit, ConstUserData) -> PxQueryHitType; #[repr(C)] pub struct FilterShaderCallbackInfo { @@ -412,28 +572,28 @@ pub type SimulationFilterShader = unsafe extern "C" fn(*mut FilterShaderCallbackInfo) -> PxFilterFlags; pub type RaycastProcessTouchesCallback = - unsafe extern "C" fn(*const PxRaycastHit, u32, *mut c_void) -> bool; + unsafe extern "C" fn(*const PxRaycastHit, u32, UserData) -> bool; pub type SweepProcessTouchesCallback = - unsafe extern "C" fn(*const PxSweepHit, u32, *mut c_void) -> bool; + unsafe extern "C" fn(*const PxSweepHit, u32, UserData) -> bool; pub type OverlapProcessTouchesCallback = - unsafe extern "C" fn(*const PxOverlapHit, u32, *mut c_void) -> bool; + unsafe extern "C" fn(*const PxOverlapHit, u32, UserData) -> bool; -pub type FinalizeQueryCallback = unsafe extern "C" fn(*mut c_void); +pub type FinalizeQueryCallback = unsafe extern "C" fn(UserData); pub type AllocCallback = - unsafe extern "C" fn(u64, *const c_void, *const c_void, u32, *const c_void) -> *mut c_void; + unsafe extern "C" fn(u64, *const c_void, *const c_void, u32, ConstUserData) -> *mut c_void; -pub type DeallocCallback = unsafe extern "C" fn(*const c_void, *const c_void); +pub type DeallocCallback = unsafe extern "C" fn(*const c_void, ConstUserData); pub type ZoneStartCallback = - unsafe extern "C" fn(*const i8, bool, u64, *const c_void) -> *mut c_void; + unsafe extern "C" fn(*const i8, bool, u64, ConstUserData) -> *mut c_void; -pub type ZoneEndCallback = unsafe extern "C" fn(*const c_void, *const i8, bool, u64, *const c_void); +pub type ZoneEndCallback = unsafe extern "C" fn(*const c_void, *const i8, bool, u64, ConstUserData); pub type ErrorCallback = - unsafe extern "C" fn(PxErrorCode, *const i8, *const i8, u32, *const c_void); + unsafe extern "C" fn(PxErrorCode, *const i8, *const i8, u32, ConstUserData); -pub type AssertHandler = unsafe extern "C" fn(*const i8, *const i8, u32, *mut bool, *const c_void); +pub type AssertHandler = unsafe extern "C" fn(*const i8, *const i8, u32, *mut bool, ConstUserData); extern "C" { pub fn physx_create_foundation() -> *mut PxFoundation; @@ -472,21 +632,21 @@ extern "C" { finalize_query_callback: FinalizeQueryCallback, touches_buffer: *mut PxRaycastHit, num_touches: u32, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxRaycastCallback; pub fn create_sweep_callback( process_touches_callback: SweepProcessTouchesCallback, finalize_query_callback: FinalizeQueryCallback, touches_buffer: *mut PxSweepHit, num_touches: u32, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxSweepCallback; pub fn create_overlap_callback( process_touches_callback: OverlapProcessTouchesCallback, finalize_query_callback: FinalizeQueryCallback, touches_buffer: *mut PxOverlapHit, num_touches: u32, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxOverlapCallback; pub fn delete_raycast_callback(callback: *mut PxRaycastCallback); @@ -496,25 +656,25 @@ extern "C" { pub fn create_alloc_callback( alloc_callback: AllocCallback, dealloc_callback: DeallocCallback, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxAllocatorCallback; pub fn create_profiler_callback( zone_start_callback: ZoneStartCallback, zone_end_callback: ZoneEndCallback, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxProfilerCallback; - pub fn get_alloc_callback_user_data(alloc_callback: *mut PxAllocatorCallback) -> *mut c_void; + pub fn get_alloc_callback_user_data(alloc_callback: *mut PxAllocatorCallback) -> UserData; pub fn create_error_callback( error_callback: ErrorCallback, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxErrorCallback; pub fn create_assert_handler( error_callback: AssertHandler, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxAssertHandler; pub fn get_default_simulation_filter_shader() -> *mut c_void; @@ -524,8 +684,9 @@ extern "C" { #[deprecated] pub fn create_contact_callback( callback: CollisionCallback, - userdata: *mut c_void, + userdata: UserData, ) -> *mut PxSimulationEventCallback; + /// Deallocates the PxSimulationEventCallback that has previously been created #[deprecated()] pub fn destroy_contact_callback(callback: *mut PxSimulationEventCallback); diff --git a/physx-sys/src/physx_generated.rs b/physx-sys/src/physx_generated.rs index cfc45d47..fc977a54 100644 --- a/physx-sys/src/physx_generated.rs +++ b/physx-sys/src/physx_generated.rs @@ -9099,7 +9099,7 @@ extern "C" { /// be referenced by other objects or the simulation might still be running and accessing the object state. In such cases the destructor will be called /// as soon as it is safe to do so. After the destruction of the object and its memory, an eMEMORY_RELEASE event will get fired. In this case it is not /// allowed to dereference the object pointer in the callback. - pub fn PxDeletionListener_onRelease_mut(self_: *mut PxDeletionListener, observed: *const PxBase, userData: *mut std::ffi::c_void, deletionEvent: PxDeletionEventFlag); + pub fn PxDeletionListener_onRelease_mut(self_: *mut PxDeletionListener, observed: *const PxBase, userData: UserData, deletionEvent: PxDeletionEventFlag); pub fn PxBaseMaterial_isKindOf(self_: *const PxBaseMaterial, name: *const std::ffi::c_char) -> bool; @@ -11818,10 +11818,10 @@ extern "C" { /// Returns the user data associated with this controller. /// /// The user pointer associated with the controller. - pub fn PxController_getUserData(self_: *const PxController) -> *mut std::ffi::c_void; + pub fn PxController_getUserData(self_: *const PxController) -> UserData; /// Sets the user data associated with this controller. - pub fn PxController_setUserData_mut(self_: *mut PxController, userData: *mut std::ffi::c_void); + pub fn PxController_setUserData_mut(self_: *mut PxController, userData: UserData); /// Returns information about the controller's internal state. pub fn PxController_getState(self_: *const PxController, state: *mut PxControllerState); diff --git a/physx/examples/profiler.rs b/physx/examples/profiler.rs index d19e4626..860dfb37 100644 --- a/physx/examples/profiler.rs +++ b/physx/examples/profiler.rs @@ -1,4 +1,5 @@ use physx::{physics::ProfilerCallback, prelude::*}; +use physx_sys::ConstUserData; use std::ffi::CStr; type PxMaterial = physx::material::PxMaterial<()>; @@ -72,9 +73,9 @@ unsafe impl ProfilerCallback for PrintProfilerCallback { _name: *const i8, _detached: bool, _context_id: u64, - user_data: *const std::ffi::c_void, + user_data: ConstUserData, ) -> *mut std::ffi::c_void { - let this = &*user_data.cast::(); + let this = user_data.heap_data_ref::(); let start = this.start.elapsed().as_micros() as u64; start as *mut std::ffi::c_void @@ -85,10 +86,10 @@ unsafe impl ProfilerCallback for PrintProfilerCallback { name: *const i8, _detached: bool, _context_id: u64, - user_data: *const std::ffi::c_void, + user_data: ConstUserData, ) { let name: &'static str = std::mem::transmute(CStr::from_ptr(name).to_str().unwrap()); - let this = &*user_data.cast::(); + let this = user_data.heap_data_ref::(); let end = this.start.elapsed().as_micros() as u64; let start = context as u64; diff --git a/physx/src/articulation_link.rs b/physx/src/articulation_link.rs index cfd40450..6a0757c7 100644 --- a/physx/src/articulation_link.rs +++ b/physx/src/articulation_link.rs @@ -7,12 +7,12 @@ use crate::{ rigid_actor::RigidActor, rigid_body::RigidBody, shape::{Shape, ShapeFlag}, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; use std::marker::PhantomData; -use physx_sys::UserDataField; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ PxArticulationLink_getChildren, @@ -31,16 +31,16 @@ pub struct PxArticulationLink { phantom_user_data: PhantomData<(L, Geom)>, } -unsafe impl UserData for PxArticulationLink { +impl HasUserData for PxArticulationLink { type UserData = L; #[inline] - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } #[inline] - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -78,7 +78,7 @@ impl RigidActor for PxArticulationLink { impl ArticulationLink for PxArticulationLink {} -pub trait ArticulationLink: Class + RigidBody + UserData { +pub trait ArticulationLink: Class + RigidBody + HasUserData { /// # Safety /// /// Owner's own the pointer they wrap, using the pointer after dropping the Owner, @@ -96,14 +96,14 @@ pub trait ArticulationLink: Class + RigidBody + U #[inline] fn get_user_data(&self) -> &Self::UserData { // Safety: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get the user data. #[inline] fn get_user_data_mut(&mut self) -> &mut Self::UserData { // Safety: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } /// Enable collisions for this link. Equivalent to setting SimulationShape to false for all attached shapes. diff --git a/physx/src/articulation_reduced_coordinate.rs b/physx/src/articulation_reduced_coordinate.rs index f655f753..d13c556d 100644 --- a/physx/src/articulation_reduced_coordinate.rs +++ b/physx/src/articulation_reduced_coordinate.rs @@ -10,12 +10,12 @@ use super::{ owner::Owner, rigid_actor::RigidActor, shape::CollisionLayers, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; use std::{marker::PhantomData, ptr::drop_in_place}; -use physx_sys::UserDataField; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ PxArticulationReducedCoordinate_applyCache_mut, @@ -66,14 +66,14 @@ pub struct PxArticulationReducedCoordinate { phantom_user_data: PhantomData<(U, Link)>, } -unsafe impl UserData for PxArticulationReducedCoordinate { +impl HasUserData for PxArticulationReducedCoordinate { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -120,7 +120,7 @@ impl ArticulationReducedCoordinate } pub trait ArticulationReducedCoordinate: - Class + UserData + Class + HasUserData { type ArticulationLink: ArticulationLink; @@ -143,13 +143,13 @@ pub trait ArticulationReducedCoordinate: /// Get a reference to the user data. fn get_user_data(&self) -> &Self::UserData { // Safety: construction must go through `from_raw` which calls `init_user_data` - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get a mutable reference to the user data. fn get_user_data_mut(&mut self) -> &mut Self::UserData { // Safety: construction must go through `from_raw` which calls `init_user_data` - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } #[inline] diff --git a/physx/src/controller.rs b/physx/src/controller.rs index dc613f73..43a100cb 100644 --- a/physx/src/controller.rs +++ b/physx/src/controller.rs @@ -4,12 +4,12 @@ use crate::{ material::Material, math::{PxExtendedVec3, PxVec3}, owner::Owner, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; -use std::{ffi::c_void, marker::PhantomData, mem::size_of, ptr::drop_in_place}; +use std::marker::PhantomData; -use physx_sys::UserDataField; +use physx_sys::UserData; use thiserror::Error; #[rustfmt::skip] @@ -46,41 +46,49 @@ pub trait Controller: Class + Sized { type UserData; type Descriptor: Class; - /// Retrieve the user data from the controller. - // Due to the size trick employed and the API decision to expose this userData via method calls, - // get_user_data_mut will not work for small sizes of U, since getUserData returns a copy of the field, - // rather than being able to write a method that returns a pointer to the field or the field itself. - fn get_user_data(&self) -> &Self::UserData { - unsafe { - if size_of::() > size_of::<*mut c_void>() { - // Cast *mut c_void to appropriate type and reborrow - &*(PxController_getUserData(self.as_ptr()) as *const Self::UserData) - } else { - // DATA_SIZE < VOID_SIZE - // The data is packed into the "*mut c_void" - &*(&PxController_getUserData(self.as_ptr()) as *const *mut c_void - as *const Self::UserData) - } - } + /// Sets the controller's user data. + fn set_user_data(&mut self, user_data: Self::UserData) -> &mut Self { + let user_data = UserData::new_maybe_packed(user_data); + // SAFETY: self is not null and is Class user_data is valid + unsafe { PxController_setUserData_mut(self.as_mut_ptr(), user_data) } + self } - /// Sets the controllers user data. If U is larger than a *mut _, it is heap allocated in a box. - /// Otherwise, it is packed directly into the *mut c_void userData field. - fn set_user_data(&mut self, user_data: Self::UserData) -> &mut Self { - unsafe { - let user_data: *mut c_void = if size_of::() > size_of::<*mut c_void>() { - // Allocate on heap since it is too large to pack into *mut c_void field - let user_data = Box::new(user_data); - // Cast to *mut c_void - Box::into_raw(user_data) as *mut c_void - } else { - // DATA_SIZE < VOID_SIZE - // The data is small enough to be packed directly into the "*mut c_void" - *(&user_data as *const Self::UserData as *const *mut c_void) - }; - PxController_setUserData_mut(self.as_mut_ptr(), user_data); + /// Retrieve the user data from the controller. Must have been already created with + /// `set_user_data` or will return `None` + fn get_user_data(&self) -> Option<&Self::UserData> { + // SAFETY: self is a valid reference and is Class + let user_data = unsafe { PxController_getUserData(self.as_ptr()) }; + // SAFETY: we only ever init the user data as a pointer, so if it's nonnull we know we have + // valid data, and it will live on the heap at least as long as we have a borrow of self + // since it only will go out of scope by being able to have a mut ref to self + unsafe { user_data.as_ptr::().as_ref() } + } + + /// Retrieve a mutable reference to the user data from the controller. Must have been already + /// created with `set_user_data` or will return `None`. + fn get_user_data_mut(&mut self) -> Option<&mut Self::UserData> { + // SAFETY: self is a valid reference and is Class + let mut user_data = unsafe { PxController_getUserData(self.as_ptr()) }; + // SAFETY: we only ever init the user data as a pointer, so if it's nonnull we know we have + // valid data, and it will live on the heap at least as long as we have a borrow of self + // since it only will go out of scope by being able to have a mut ref to self + unsafe { user_data.as_mut_ptr::().as_mut() } + } + + /// If it exists, drop and dealloc associated user data. + fn drop_and_dealloc_user_data(&mut self) { + // SAFETY: self is a valid reference and is Class + let mut user_data = unsafe { PxController_getUserData(self.as_ptr()) }; + // SAFETY: we only initialize user_data as a pointer ever + let is_null = unsafe { user_data.is_null() }; + if !is_null { + // SAFETY: if the user_data is not null, we must have allocated it as on the heap + // and it may be drop and dealloced + unsafe { + user_data.heap_drop_and_dealloc::(); + } } - self } /// Set the position of teh controller @@ -119,13 +127,7 @@ where impl Drop for PxCapsuleController { fn drop(&mut self) { unsafe { - if size_of::() > size_of::<*mut c_void>() { - drop_in_place(PxController_getUserData(self.as_ptr()) as *mut U); - } else { - drop_in_place( - (&mut PxController_getUserData(self.as_ptr())) as *mut *mut c_void as *mut U, - ); - }; + self.drop_and_dealloc_user_data(); PxController_release_mut(self.as_mut_ptr()) } } @@ -234,21 +236,47 @@ impl PxCapsuleControllerDesc { } } -unsafe impl UserData for PxCapsuleControllerDesc { +// override default behavior because we need the `userData` that gets passed along to the +// `Controller` this creates to be on the heap, which expects it to be so (see implementation +// of `Controller` trait) +impl HasUserData for PxCapsuleControllerDesc { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } + + fn init_user_data(&mut self, user_data: Self::UserData) -> &mut Self { + self.user_data_ptr_mut() + .initialize_on_heap::(user_data); + self + } + + unsafe fn drop_and_dealloc_user_data(&mut self) { + // SAFETY: same as function-level safety + unsafe { + self.user_data_ptr_mut() + .heap_drop_and_dealloc::() + } + } + + unsafe fn get_user_data(&self) -> &Self::UserData { + unsafe { self.user_data_ptr().heap_data_ref::() } + } + + unsafe fn get_user_data_mut(&mut self) -> &mut Self::UserData { + unsafe { self.user_data_ptr_mut().heap_data_mut::() } + } } impl Drop for PxCapsuleControllerDesc { fn drop(&mut self) { unsafe { + // SAFETY: we always initialize this in the only public constructors self.drop_and_dealloc_user_data(); PxCapsuleControllerDesc_delete(self.as_mut_ptr()); } @@ -277,13 +305,7 @@ where impl Drop for PxBoxController { fn drop(&mut self) { unsafe { - if size_of::() > size_of::<*mut c_void>() { - drop_in_place(PxController_getUserData(self.as_ptr()) as *mut U); - } else { - drop_in_place( - (&mut PxController_getUserData(self.as_ptr())) as *mut *mut c_void as *mut U, - ); - }; + self.drop_and_dealloc_user_data(); PxController_release_mut(self.as_mut_ptr()) } } @@ -394,21 +416,47 @@ impl PxBoxControllerDesc { } } -unsafe impl UserData for PxBoxControllerDesc { +// override default behavior because we need the `userData` that gets passed along to the +// `Controller` this creates to be on the heap, which expects it to be so (see implementation +// of `Controller` trait) +impl HasUserData for PxBoxControllerDesc { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } + + fn init_user_data(&mut self, user_data: Self::UserData) -> &mut Self { + self.user_data_ptr_mut() + .initialize_on_heap::(user_data); + self + } + + unsafe fn drop_and_dealloc_user_data(&mut self) { + // SAFETY: same as function-level safety + unsafe { + self.user_data_ptr_mut() + .heap_drop_and_dealloc::() + } + } + + unsafe fn get_user_data(&self) -> &Self::UserData { + unsafe { self.user_data_ptr().heap_data_ref::() } + } + + unsafe fn get_user_data_mut(&mut self) -> &mut Self::UserData { + unsafe { self.user_data_ptr_mut().heap_data_mut::() } + } } impl Drop for PxBoxControllerDesc { fn drop(&mut self) { unsafe { + // SAFETY: we always initialize this in the only public constructors self.drop_and_dealloc_user_data(); PxBoxControllerDesc_delete(self.as_mut_ptr()) } diff --git a/physx/src/foundation.rs b/physx/src/foundation.rs index 30fe3e2a..32267b58 100644 --- a/physx/src/foundation.rs +++ b/physx/src/foundation.rs @@ -6,6 +6,7 @@ use crate::{owner::Owner, traits::Class}; +use physx_sys::{ConstUserData, UserData}; #[rustfmt::skip] use physx_sys::{ create_alloc_callback, @@ -152,10 +153,21 @@ pub trait Foundation: Class + Sized { /// Get the allocator callback. fn get_allocator_callback(&mut self) -> Option<&mut Self::Allocator> { - unsafe { - (get_alloc_callback_user_data(PxFoundation_getAllocatorCallback_mut(self.as_mut_ptr())) - as *mut Self::Allocator) - .as_mut() + let px_allocatorcallback = + unsafe { PxFoundation_getAllocatorCallback_mut(self.as_mut_ptr()) }; + if px_allocatorcallback.is_null() { + None + } else { + // SAFETY: we know px_allocatorcallback is not null, and the only way for that to happen when using + // the safe wrapper is if we initialized it properly + let mut userdata = unsafe { get_alloc_callback_user_data(px_allocatorcallback) }; + // SAFETY: if we got a non-null allocatorcallback object back, then we must also have a non-null pointer + // to a `Self::Allocator` in the userdata because we initialize it ourselves in the implementation of `AllocatorCallback`, + // which `Self::Allocator` implements and uses to initialize itself. + // + // we assert the lifetime of `allocator_mut` to be at least as long as the borrow of `self`, which is true since it's on the heap + // and we don't clean it up + Some(unsafe { &mut *userdata.as_mut_ptr::() }) } } @@ -199,8 +211,17 @@ impl ScratchBuffer { /// /// Reporting the name, file and line is not enabled by default. /// Use [`Foundation::set_report_allocation_names`] to toggle this on or off. +/// +/// When you use `AllocatorCallback::into_px(self)`, the `self` you pass in will be +/// placed on the heap and a pointer to it will be passed into the `user_data` in the +/// `allocate` and `deallocate` functions. Keep in mind the threading context you're using and +/// ensure that the type you're implementing this on is sufficiently thread-safe for the kinds +/// of access you are doing. #[allow(clippy::missing_safety_doc)] pub unsafe trait AllocatorCallback: Sized { + /// `user_data` will be a forced-heap-pointer to a `Self`. So you can access the `self` that + /// `into_px` was called on by calling `user_data.heap_data_ref::()`. + /// /// # Safety /// /// Allocations must be aligned 16. This should not panic, since it is @@ -210,13 +231,16 @@ pub unsafe trait AllocatorCallback: Sized { name: *const c_void, file: *const c_void, line: u32, - user_data: *const c_void, + user_data: ConstUserData, ) -> *mut c_void; + /// `user_data` will be a forced-heap-pointer to a `Self`. So you can access the `self` that + /// `into_px` was called on by calling `user_data.heap_data_ref::()`. + /// /// # Safety /// /// Must not panic. - unsafe extern "C" fn deallocate(ptr: *const c_void, user_data: *const c_void); + unsafe extern "C" fn deallocate(ptr: *const c_void, user_data: ConstUserData); /// # Safety /// @@ -226,7 +250,7 @@ pub unsafe trait AllocatorCallback: Sized { create_alloc_callback( Self::allocate, Self::deallocate, - Box::into_raw(Box::new(self)) as *mut c_void, + UserData::new_on_heap(self), ) } } @@ -241,7 +265,7 @@ unsafe impl AllocatorCallback for GlobalAllocCallback { _name: *const c_void, _file: *const c_void, _line: u32, - _user_data: *const c_void, + _user_data: ConstUserData, ) -> *mut c_void { let alloc_size = size as usize + 16; let layout = std::alloc::Layout::from_size_align(alloc_size, 16).unwrap(); @@ -252,7 +276,7 @@ unsafe impl AllocatorCallback for GlobalAllocCallback { } } - unsafe extern "C" fn deallocate(ptr: *const c_void, _user_data: *const c_void) { + unsafe extern "C" fn deallocate(ptr: *const c_void, _user_data: ConstUserData) { let ptr = (ptr as usize - 16) as *mut u64; unsafe { let size = *ptr; @@ -285,12 +309,12 @@ unsafe impl AllocatorCallback for TrackingAllocator { _name: *const c_void, _file: *const c_void, _line: u32, - user_data: *const c_void, + user_data: ConstUserData, ) -> *mut c_void { - let user_data = unsafe { &*(user_data as *const Self) }; let alloc_size = size as usize + 16; let layout = std::alloc::Layout::from_size_align(alloc_size, 16).unwrap(); - user_data.allocated.fetch_add(layout.size(), SeqCst); + let this = unsafe { user_data.heap_data_ref::() }; + this.allocated.fetch_add(layout.size(), SeqCst); unsafe { let allocation = alloc(layout) as *mut u64; *allocation = alloc_size as u64; @@ -298,12 +322,12 @@ unsafe impl AllocatorCallback for TrackingAllocator { } } - unsafe extern "C" fn deallocate(ptr: *const c_void, user_data: *const c_void) { - let user_data = unsafe { &*(user_data as *const Self) }; + unsafe extern "C" fn deallocate(ptr: *const c_void, user_data: ConstUserData) { let ptr = (ptr as usize - 16) as *mut u64; let size = unsafe { *ptr }; let layout = Layout::from_size_align(size as usize, 16).unwrap(); - user_data.deallocated.fetch_add(layout.size(), SeqCst); + let this = unsafe { user_data.heap_data_ref::() }; + this.deallocated.fetch_add(layout.size(), SeqCst); unsafe { dealloc(ptr as *mut u8, layout) } } } @@ -321,12 +345,12 @@ unsafe impl AllocatorCallback for DefaultAllocator { _name: *const c_void, _file: *const c_void, _line: u32, - _user_data: *const c_void, + _user_data: ConstUserData, ) -> *mut c_void { unreachable!() } - unsafe extern "C" fn deallocate(_ptr: *const c_void, _user_data: *const c_void) { + unsafe extern "C" fn deallocate(_ptr: *const c_void, _user_data: ConstUserData) { unreachable!() } } diff --git a/physx/src/material.rs b/physx/src/material.rs index cdce539d..ffeae8b0 100644 --- a/physx/src/material.rs +++ b/physx/src/material.rs @@ -1,11 +1,11 @@ use crate::{ owner::Owner, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; use std::marker::PhantomData; -use physx_sys::UserDataField; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ PxMaterial_getDynamicFriction, @@ -37,14 +37,14 @@ pub struct PxMaterial { phantom_user_data: PhantomData, } -unsafe impl UserData for PxMaterial { +impl HasUserData for PxMaterial { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -75,7 +75,7 @@ unsafe impl Sync for PxMaterial {} impl Material for PxMaterial {} -pub trait Material: Class + UserData { +pub trait Material: Class + HasUserData { /// # Safety /// /// Owner's own the pointer they wrap, using the pointer after dropping the Owner, @@ -92,14 +92,14 @@ pub trait Material: Class + UserData { #[inline] fn get_user_data(&self) -> &Self::UserData { // Safety: all constructors go through from_raw which calls init_user_data - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get a mutable reference to the user data. #[inline] fn get_user_data_mut(&mut self) -> &mut Self::UserData { // Safety: all constructors go through from_raw which calls init_user_data - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } /// Set the dynamic friction. diff --git a/physx/src/physics.rs b/physx/src/physics.rs index 9619936b..895087a5 100644 --- a/physx/src/physics.rs +++ b/physx/src/physics.rs @@ -30,7 +30,7 @@ use crate::{ scene::PxScene, shape::{Shape, ShapeFlags}, simulation_event_callback::*, - traits::{Class, Descriptor, SceneDescriptor, UserData}, + traits::{Class, Descriptor, HasUserData, SceneDescriptor}, triangle_mesh::TriangleMesh, visual_debugger::VisualDebugger, }; @@ -394,7 +394,7 @@ pub trait Physics: Class + Sized { static_friction: f32, dynamic_friction: f32, restitution: f32, - user_data: <::Material as UserData>::UserData, + user_data: <::Material as HasUserData>::UserData, ) -> Option::Material>> { unsafe { Material::from_raw( @@ -460,7 +460,7 @@ pub trait Physics: Class + Sized { materials: &mut [&mut ::Material], is_exclusive: bool, shape_flags: ShapeFlags, - user_data: ::UserData, + user_data: ::UserData, ) -> Option> { unsafe { Shape::from_raw( diff --git a/physx/src/physics/assert_handler.rs b/physx/src/physics/assert_handler.rs index 93abf1ef..2fc47d1c 100644 --- a/physx/src/physics/assert_handler.rs +++ b/physx/src/physics/assert_handler.rs @@ -1,6 +1,6 @@ -use std::ffi::{c_void, CStr}; +use std::ffi::CStr; -use physx_sys::{create_assert_handler, PxAssertHandler}; +use physx_sys::{create_assert_handler, ConstUserData, PxAssertHandler, UserData}; /// This represents the (deprecated) PxAssertHandler interface. pub trait AssertHandler: Sized { @@ -18,25 +18,20 @@ pub trait AssertHandler: Sized { file: *const i8, line: u32, should_ignore: *mut bool, - this: *const c_void, + user_data: ConstUserData, ) { unsafe { - let this = &*this.cast::(); let expr = CStr::from_ptr(expr.cast()); let expr = expr.to_string_lossy(); let file = CStr::from_ptr(file.cast()); let file = file.to_string_lossy(); + let this = user_data.heap_data_ref::(); this.on_assert(&expr, &file, line, &mut *should_ignore); } } - unsafe { - create_assert_handler( - on_message_shim::, - Box::into_raw(Box::new(self)) as *mut c_void, - ) - } + unsafe { create_assert_handler(on_message_shim::, UserData::new_on_heap(self)) } } } diff --git a/physx/src/physics/error_callback.rs b/physx/src/physics/error_callback.rs index 2f5229fe..5b58d5d1 100644 --- a/physx/src/physics/error_callback.rs +++ b/physx/src/physics/error_callback.rs @@ -1,5 +1,5 @@ -use physx_sys::{create_error_callback, PxErrorCallback, PxErrorCode}; -use std::ffi::{c_void, CStr}; +use physx_sys::{create_error_callback, ConstUserData, PxErrorCallback, PxErrorCode, UserData}; +use std::ffi::CStr; pub trait ErrorCallback: Sized { fn report_error(&self, code: PxErrorCode, message: &str, file: &str, line: u32); @@ -12,25 +12,20 @@ pub trait ErrorCallback: Sized { message: *const i8, file: *const i8, line: u32, - this: *const c_void, + user_data: ConstUserData, ) { unsafe { - let this = &*this.cast::(); let msg = CStr::from_ptr(message.cast()); let msg = msg.to_string_lossy(); let file = CStr::from_ptr(file.cast()); let file = file.to_string_lossy(); + let this = user_data.heap_data_ref::(); this.report_error(code, &msg, &file, line); } } - unsafe { - create_error_callback( - on_message_shim::, - Box::into_raw(Box::new(self)) as *mut c_void, - ) - } + unsafe { create_error_callback(on_message_shim::, UserData::new_on_heap(self)) } } } diff --git a/physx/src/physics/profiler.rs b/physx/src/physics/profiler.rs index 0d8fce1a..35fce371 100644 --- a/physx/src/physics/profiler.rs +++ b/physx/src/physics/profiler.rs @@ -1,4 +1,4 @@ -use physx_sys::{create_profiler_callback, PxProfilerCallback}; +use physx_sys::{create_profiler_callback, ConstUserData, PxProfilerCallback, UserData}; use std::ffi::c_void; /// A trait for creating profiler callbacks for PhysX. @@ -13,7 +13,7 @@ pub unsafe trait ProfilerCallback: Sized { name: *const i8, detached: bool, context_id: u64, - user_data: *const c_void, + user_data: ConstUserData, ) -> *mut c_void; /// # Safety @@ -25,7 +25,7 @@ pub unsafe trait ProfilerCallback: Sized { name: *const i8, detached: bool, context_id: u64, - user_data: *const c_void, + user_data: ConstUserData, ); /// # Safety @@ -36,7 +36,7 @@ pub unsafe trait ProfilerCallback: Sized { create_profiler_callback( Self::zone_start, Self::zone_end, - Box::into_raw(Box::new(self)) as *mut c_void, + UserData::new_on_heap(self), ) } } diff --git a/physx/src/rigid_dynamic.rs b/physx/src/rigid_dynamic.rs index 87876fd3..75587a29 100644 --- a/physx/src/rigid_dynamic.rs +++ b/physx/src/rigid_dynamic.rs @@ -10,12 +10,12 @@ use crate::{ rigid_actor::RigidActor, rigid_body::RigidBody, shape::Shape, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; use std::marker::PhantomData; -use physx_sys::UserDataField; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ phys_PxCreateDynamic, @@ -55,14 +55,14 @@ pub struct PxRigidDynamic { phantom_user_data: PhantomData<(D, Geom)>, } -unsafe impl UserData for PxRigidDynamic { +impl HasUserData for PxRigidDynamic { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -98,7 +98,7 @@ impl RigidActor for PxRigidDynamic { impl RigidDynamic for PxRigidDynamic {} -pub trait RigidDynamic: Class + RigidBody + UserData { +pub trait RigidDynamic: Class + RigidBody + HasUserData { /// Create a new RigidDynamic. #[inline] fn new( @@ -148,14 +148,14 @@ pub trait RigidDynamic: Class + RigidBody + UserData #[inline] fn get_user_data(&self) -> &Self::UserData { // SAFETY: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get the user data. #[inline] fn get_user_data_mut(&mut self) -> &mut Self::UserData { // SAFETY: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } /// Set the linear velocity. diff --git a/physx/src/rigid_static.rs b/physx/src/rigid_static.rs index d4f9d04b..7f2caa44 100644 --- a/physx/src/rigid_static.rs +++ b/physx/src/rigid_static.rs @@ -11,10 +11,10 @@ use crate::{ physics::Physics, rigid_actor::RigidActor, shape::Shape, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; -use physx_sys::UserDataField; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ phys_PxCreateStatic, @@ -30,14 +30,14 @@ pub struct PxRigidStatic { phantom_user_data: PhantomData<(S, Geom)>, } -unsafe impl UserData for PxRigidStatic { +impl HasUserData for PxRigidStatic { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -73,7 +73,7 @@ impl RigidActor for PxRigidStatic { impl RigidStatic for PxRigidStatic {} -pub trait RigidStatic: Class + RigidActor + UserData { +pub trait RigidStatic: Class + RigidActor + HasUserData { /// Create a new RigidStatic. fn new( physics: &mut impl Physics, @@ -115,13 +115,13 @@ pub trait RigidStatic: Class + RigidActor + UserData { /// Get the user data. fn get_user_data(&self) -> &Self::UserData { // Safety: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get the user data. fn get_user_data_mut(&mut self) -> &mut Self::UserData { // Safety: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } /// Get the name of the real type referenced by this pointer, or None if the returned string is not valid diff --git a/physx/src/scene.rs b/physx/src/scene.rs index 17e6c8ac..c50f76b0 100644 --- a/physx/src/scene.rs +++ b/physx/src/scene.rs @@ -23,7 +23,7 @@ use crate::{ AdvanceCallback, CollisionCallback, ConstraintBreakCallback, PxSimulationEventCallback, TriggerCallback, WakeSleepCallback, }, - traits::{Class, UserData}, + traits::{Class, HasUserData}, visual_debugger::PvdSceneClient, }; @@ -32,7 +32,7 @@ use std::{ ptr::{drop_in_place, null, null_mut}, }; -use physx_sys::UserDataField; +use physx_sys::UserData; // A glob import is super tempting, but the wrappers shadow the names of the physx_sys types, // so those types cannot be in scope. Plus, it easier to see what's been implemented. #[rustfmt::skip] @@ -161,7 +161,7 @@ where phantom_user_data: PhantomData<(U, L, S, D, C, OC, OT, OCB, OWS, OA)>, } -unsafe impl UserData +impl HasUserData for PxScene where L: ArticulationLink, @@ -176,11 +176,11 @@ where { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -296,7 +296,7 @@ where type Aggregate = PxAggregate; } -pub trait Scene: Class + UserData { +pub trait Scene: Class + HasUserData { type ArticulationLink: ArticulationLink; type RigidStatic: RigidStatic; type RigidDynamic: RigidDynamic; @@ -316,13 +316,13 @@ pub trait Scene: Class + UserData { /// Get the user data. fn get_user_data(&self) -> &Self::UserData { // Safety: Scenes are constructed from SceneDescriptor which sets up user data appropriately - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get the user data. fn get_user_data_mut(&mut self) -> *mut Self::UserData { // Safety: Scenes are constructed from SceneDescriptor which sets up user data appropriately - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } /// Get the visual debugger client diff --git a/physx/src/shape.rs b/physx/src/shape.rs index 536cb71f..0cf384ed 100644 --- a/physx/src/shape.rs +++ b/physx/src/shape.rs @@ -7,12 +7,12 @@ use crate::{ material::Material, owner::Owner, - traits::{Class, UserData}, + traits::{Class, HasUserData}, }; use std::marker::PhantomData; -use physx_sys::UserDataField; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ PxFilterData, @@ -48,14 +48,14 @@ pub struct PxShape { phantom_user_data: PhantomData<(U, M)>, } -unsafe impl UserData for PxShape { +impl HasUserData for PxShape { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.obj.userData } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.obj.userData } } @@ -90,7 +90,7 @@ impl Shape for PxShape { type Material = M; } -pub trait Shape: Class + UserData { +pub trait Shape: Class + HasUserData { type Material: Material; /// # Safety @@ -110,13 +110,13 @@ pub trait Shape: Class + UserData { /// Get a reference to the user data. fn get_user_data(&self) -> &Self::UserData { // Safety: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data(self) } + unsafe { HasUserData::get_user_data(self) } } /// Get a mutable reference to the user data. fn get_user_data_mut(&mut self) -> &mut Self::UserData { // Safety: all construction goes through from_raw, which calls init_user_data - unsafe { UserData::get_user_data_mut(self) } + unsafe { HasUserData::get_user_data_mut(self) } } /// Set the simulation (collision) filter of this shape diff --git a/physx/src/simulation_event_callback.rs b/physx/src/simulation_event_callback.rs index dfec8255..09b6440f 100644 --- a/physx/src/simulation_event_callback.rs +++ b/physx/src/simulation_event_callback.rs @@ -1,4 +1,4 @@ -use std::{ffi::c_void, marker::PhantomData, ptr::null_mut, slice}; +use std::{marker::PhantomData, slice}; #[rustfmt::skip] use crate::{ @@ -12,6 +12,7 @@ use crate::{ traits::Class, }; +use physx_sys::UserData; #[rustfmt::skip] use physx_sys::{ create_simulation_event_callbacks, @@ -97,15 +98,15 @@ where { unsafe { let (collision_callback, collision_user_data) = - on_collide.map_or((None, null_mut()), OC::into_cb_user_data); + on_collide.map_or((None, UserData::null()), OC::into_cb_user_data); let (trigger_callback, trigger_user_data) = - on_trigger.map_or((None, null_mut()), OT::into_cb_user_data); + on_trigger.map_or((None, UserData::null()), OT::into_cb_user_data); let (constraint_break_callback, constraint_break_user_data) = - on_constraint_break.map_or((None, null_mut()), OCB::into_cb_user_data); + on_constraint_break.map_or((None, UserData::null()), OCB::into_cb_user_data); let (wake_sleep_callback, wake_sleep_user_data) = - on_wake_sleep.map_or((None, null_mut()), OWS::into_cb_user_data); + on_wake_sleep.map_or((None, UserData::null()), OWS::into_cb_user_data); let (advance_callback, advance_user_data) = - on_advance.map_or((None, null_mut()), OA::into_cb_user_data); + on_advance.map_or((None, UserData::null()), OA::into_cb_user_data); Owner::from_raw( create_simulation_event_callbacks(&SimulationEventCallbackInfo { @@ -142,20 +143,21 @@ where unsafe { let info = &mut *get_simulation_event_info(self.as_mut_ptr()); { - if !info.collision_user_data.is_null() { - drop(Box::from_raw(info.collision_user_data as *mut OC)); + if info.collision_callback.is_some() { + info.collision_user_data.heap_drop_and_dealloc::(); }; - if !info.trigger_user_data.is_null() { - drop(Box::from_raw(info.trigger_user_data as *mut OT)); + if info.trigger_callback.is_some() { + info.trigger_user_data.heap_drop_and_dealloc::(); }; - if !info.constraint_break_user_data.is_null() { - drop(Box::from_raw(info.constraint_break_user_data as *mut OCB)); + if info.constraint_break_callback.is_some() { + info.constraint_break_user_data + .heap_drop_and_dealloc::(); }; - if !info.wake_sleep_user_data.is_null() { - drop(Box::from_raw(info.wake_sleep_user_data as *mut OWS)); + if info.wake_sleep_callback.is_some() { + info.wake_sleep_user_data.heap_drop_and_dealloc::(); }; - if !info.advance_user_data.is_null() { - drop(Box::from_raw(info.advance_user_data as *mut OA)); + if info.advance_callback.is_some() { + info.advance_user_data.heap_drop_and_dealloc::(); }; } destroy_simulation_event_callbacks(self.as_mut_ptr()); @@ -172,25 +174,22 @@ impl CollisionCallbackRaw for T where T: CollisionCallback {} trait CollisionCallbackRaw: CollisionCallback { unsafe extern "C" fn callback( - user_data: *mut c_void, + mut user_data: UserData, header: *const physx_sys::PxContactPairHeader, pairs: *const physx_sys::PxContactPair, nb_pairs: u32, ) { unsafe { Self::on_collision( - &mut *(user_data as *mut Self), + user_data.heap_data_mut::(), &*header, slice::from_raw_parts(pairs, nb_pairs as usize), ) } } - fn into_cb_user_data(self) -> (Option, *mut c_void) { - ( - Some(Self::callback), - Box::into_raw(Box::new(self)) as *mut c_void, - ) + fn into_cb_user_data(self) -> (Option, UserData) { + (Some(Self::callback), UserData::new_on_heap(self)) } } @@ -203,23 +202,20 @@ impl TriggerCallbackRaw for T where T: TriggerCallback {} trait TriggerCallbackRaw: TriggerCallback { unsafe extern "C" fn callback( - user_data: *mut c_void, + mut user_data: UserData, pairs: *const physx_sys::PxTriggerPair, nb_pairs: u32, ) { unsafe { Self::on_trigger( - &mut *(user_data as *mut Self), + user_data.heap_data_mut::(), slice::from_raw_parts(pairs, nb_pairs as usize), ) } } - fn into_cb_user_data(self) -> (Option, *mut c_void) { - ( - Some(Self::callback), - Box::into_raw(Box::new(self)) as *mut c_void, - ) + fn into_cb_user_data(self) -> (Option, UserData) { + (Some(Self::callback), UserData::new_on_heap(self)) } } @@ -232,23 +228,20 @@ impl ConstraintBreakCallbackRaw for T where T: ConstraintBreakCallback {} trait ConstraintBreakCallbackRaw: ConstraintBreakCallback { unsafe extern "C" fn callback( - this: *mut c_void, + mut user_data: UserData, constraints: *const physx_sys::PxConstraintInfo, nb_constraints: u32, ) { unsafe { Self::on_constraint_break( - &mut *(this as *mut Self), + user_data.heap_data_mut::(), slice::from_raw_parts(constraints, nb_constraints as usize), ) } } - fn into_cb_user_data(self) -> (Option, *mut c_void) { - ( - Some(Self::callback), - Box::into_raw(Box::new(self)) as *mut c_void, - ) + fn into_cb_user_data(self) -> (Option, UserData) { + (Some(Self::callback), UserData::new_on_heap(self)) } } @@ -274,25 +267,22 @@ where D: RigidDynamic, { unsafe extern "C" fn callback( - this: *mut c_void, + mut user_data: UserData, actors: *const *const physx_sys::PxActor, nb_actors: u32, is_waking: bool, ) { unsafe { Self::on_wake_sleep( - &mut *(this as *mut Self), + user_data.heap_data_mut::(), slice::from_raw_parts(actors as *const &ActorMap, nb_actors as usize), is_waking, ); } } - fn into_cb_user_data(self) -> (Option, *mut c_void) { - ( - Some(Self::callback), - Box::into_raw(Box::new(self)) as *mut c_void, - ) + fn into_cb_user_data(self) -> (Option, UserData) { + (Some(Self::callback), UserData::new_on_heap(self)) } } @@ -319,24 +309,21 @@ where D: RigidDynamic, { unsafe extern "C" fn callback( - this: *mut c_void, + user_data: UserData, bodies: *const *const physx_sys::PxRigidBody, transforms: *const physx_sys::PxTransform, nb_actors: u32, ) { unsafe { Self::on_advance( - &*(this as *const _ as *const Self), + user_data.heap_data_ref::(), slice::from_raw_parts(bodies as *const &RigidBodyMap, nb_actors as usize), slice::from_raw_parts(transforms as *const PxTransform, nb_actors as usize), ) } } - fn into_cb_user_data(self) -> (Option, *mut c_void) { - ( - Some(Self::callback), - Box::into_raw(Box::new(self)) as *mut c_void, - ) + fn into_cb_user_data(self) -> (Option, UserData) { + (Some(Self::callback), UserData::new_on_heap(self)) } } diff --git a/physx/src/traits.rs b/physx/src/traits.rs index 0e69715a..1991731f 100644 --- a/physx/src/traits.rs +++ b/physx/src/traits.rs @@ -7,7 +7,7 @@ pub use class::Class; pub(crate) use class::DeriveClassForNewType; mod user_data; -pub(crate) use user_data::UserData; +pub(crate) use user_data::HasUserData; pub mod descriptor; pub(crate) use descriptor::*; diff --git a/physx/src/traits/descriptor.rs b/physx/src/traits/descriptor.rs index 4a7cf6f7..86d5cf15 100644 --- a/physx/src/traits/descriptor.rs +++ b/physx/src/traits/descriptor.rs @@ -19,11 +19,11 @@ use crate::{ AdvanceCallback, CollisionCallback, ConstraintBreakCallback, PxSimulationEventCallback, TriggerCallback, WakeSleepCallback, }, - traits::UserData, + traits::HasUserData, }; pub use physx_sys::PxSceneFlags as SceneFlags; -use physx_sys::UserDataField; +use physx_sys::UserData; use std::{marker::PhantomData, ptr::null_mut}; @@ -183,7 +183,7 @@ impl< frictionOffsetThreshold: self.friction_offset_threshold, ccdMaxSeparation: self.ccd_max_separation, flags: self.flags, - userData: UserDataField::new_with_data(self.user_data), + userData: UserData::new_maybe_packed(self.user_data), solverBatchSize: self.solver_batch_size, solverArticulationBatchSize: self.solver_articulation_batch_size, maxBiasCoefficient: self.max_bias_coefficient, @@ -278,7 +278,7 @@ pub struct MaterialDescriptor { } impl Descriptor

- for MaterialDescriptor<<<

::Shape as Shape>::Material as UserData>::UserData> + for MaterialDescriptor<<<

::Shape as Shape>::Material as HasUserData>::UserData> { type Target = Option::Shape as Shape>::Material>>; fn create(self, physics: &mut P) -> Self::Target { @@ -300,7 +300,7 @@ pub struct ShapeDescriptor<'a, U, G: Geometry, M: Material> { } impl Descriptor

- for ShapeDescriptor<'_, ::UserData, G, ::Material> + for ShapeDescriptor<'_, ::UserData, G, ::Material> { type Target = Option>; diff --git a/physx/src/traits/user_data.rs b/physx/src/traits/user_data.rs index 83964d89..306ce3d6 100644 --- a/physx/src/traits/user_data.rs +++ b/physx/src/traits/user_data.rs @@ -1,53 +1,77 @@ -use physx_sys::UserDataField; +use physx_sys::UserData; -/// UserData allows easy access and initialization of userData *mut c_void fields on Px objects. -/// Not all Px objects with user data expose them as a field, so not all objects with user data can use this. +/// `HasUserData` allows easy access and initialization of `void* userData` (in Rust, `UserData`) +/// fields on Px objects. /// -/// # Safety +/// Not all Px objects with user data expose them as a field, so not all +/// objects with user data can use this. Objects which only allow getting the user data through +/// an accessor function cannot use this trait because returning a (mutable) reference to the +/// user data field itself isn't possible. /// -/// all constructors of implementing types must call `init_user_data` during construction. -/// If this does not happen, calling get_user_data or get_user_data_mut may return garbage data, or -/// dereference an invalid pointer. If UserData is larger than a *mut ptr it will be stored on the heap, -/// and it may need to be explicitly dropped by turning the field back into a Box and dropping it. -/// If UserData implements Drop, this may be as simple as calling `get_user_data_mut` and then calling drop(), -/// but implementation is left to the concrete type's Drop impl. -pub unsafe trait UserData: Sized { +/// The default implementations try to exploit packing `UserData` into the space of the pointer +/// field itself. If `UserData` has larger size or alignment than a pointer, it will be stored +/// on the heap. Other implementations may modify this behavior to, for example, always store the +/// data on the heap, if it suits them. An example of this are the `Px__ControllerDesc` objects, +/// which will be used to create `Px__Controller`s that implement the `Controller` trait. That +/// `Controller` trait expects the user data to always be on the heap because it is one of the +/// objects for which user data is only accessible through an acessor method. As such, the +/// `Desc` objects must follow suit and always place the data on the heap. +pub trait HasUserData: Sized { type UserData; /// Returns a reference to the userData field - fn user_data_ptr(&self) -> &UserDataField; + fn user_data_ptr(&self) -> &UserData; /// Returns a mutable reference to the userData field. - fn user_data_ptr_mut(&mut self) -> &mut UserDataField; + fn user_data_ptr_mut(&mut self) -> &mut UserData; + /// Initialize the user data #[inline(always)] fn init_user_data(&mut self, user_data: Self::UserData) -> &mut Self { - self.user_data_ptr_mut().initialize_with_data::(user_data); + self.user_data_ptr_mut() + .initialize_maybe_packed::(user_data); self } + /// Drop and dealloc the user data + /// /// # Safety /// /// The user data field must have previously been initialized via `init_user_data` #[inline(always)] unsafe fn drop_and_dealloc_user_data(&mut self) { // SAFETY: same as function-level safety - unsafe { self.user_data_ptr_mut().drop_and_dealloc::() } + unsafe { + self.user_data_ptr_mut() + .maybe_packed_drop_and_dealloc::() + } } + /// Get a shared ref to the user data, whether packed in the pointer or on the heap. + /// /// # Safety /// /// The user data field must have previously been initialized via `init_user_data`. #[inline(always)] unsafe fn get_user_data(&self) -> &Self::UserData { - unsafe { self.user_data_ptr().data_ref::() } + // SAFETY: same as function-level safety + unsafe { + self.user_data_ptr() + .maybe_packed_data_ref::() + } } + /// Get a mutable ref to the user data, whether packed in the pointer or on the heap. + /// /// # Safety /// /// The user data field must have previously been initialized via `init_user_data`. #[inline(always)] unsafe fn get_user_data_mut(&mut self) -> &mut Self::UserData { - unsafe { self.user_data_ptr_mut().data_ref_mut::() } + // SAFETY: same as function-level safety + unsafe { + self.user_data_ptr_mut() + .maybe_packed_data_mut::() + } } } @@ -55,12 +79,12 @@ pub unsafe trait UserData: Sized { mod tests { use std::{fmt::Debug, marker::PhantomData}; - use physx_sys::UserDataField; + use physx_sys::UserData; - use super::UserData; + use super::HasUserData; struct TestUserData { - user_data: UserDataField, + user_data: UserData, phantom: PhantomData, } @@ -73,14 +97,14 @@ mod tests { } } - unsafe impl UserData for TestUserData { + impl HasUserData for TestUserData { type UserData = U; - fn user_data_ptr(&self) -> &UserDataField { + fn user_data_ptr(&self) -> &UserData { &self.user_data } - fn user_data_ptr_mut(&mut self) -> &mut UserDataField { + fn user_data_ptr_mut(&mut self) -> &mut UserData { &mut self.user_data } } @@ -90,8 +114,8 @@ mod tests { let mut object: TestUserData = TestUserData::default(); object.init_user_data(user_data.clone()); - assert_eq!(UserData::get_user_data(&object), &user_data); - assert_eq!(UserData::get_user_data_mut(&mut object), &user_data); + assert_eq!(HasUserData::get_user_data(&object), &user_data); + assert_eq!(HasUserData::get_user_data_mut(&mut object), &user_data); object.drop_and_dealloc_user_data(); } From c3d493a15be27dd88b410ec91a59a633c824fa66 Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 9 Nov 2023 00:07:19 +0100 Subject: [PATCH 3/5] fix wrong Controller user data impl --- physx/src/controller.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/physx/src/controller.rs b/physx/src/controller.rs index 43a100cb..3c4d7ee9 100644 --- a/physx/src/controller.rs +++ b/physx/src/controller.rs @@ -48,14 +48,14 @@ pub trait Controller: Class + Sized { /// Sets the controller's user data. fn set_user_data(&mut self, user_data: Self::UserData) -> &mut Self { - let user_data = UserData::new_maybe_packed(user_data); + let user_data = UserData::new_on_heap(user_data); // SAFETY: self is not null and is Class user_data is valid unsafe { PxController_setUserData_mut(self.as_mut_ptr(), user_data) } self } /// Retrieve the user data from the controller. Must have been already created with - /// `set_user_data` or will return `None` + /// `set_user_data` or in the `Desc` this came from or will return `None` fn get_user_data(&self) -> Option<&Self::UserData> { // SAFETY: self is a valid reference and is Class let user_data = unsafe { PxController_getUserData(self.as_ptr()) }; @@ -66,7 +66,7 @@ pub trait Controller: Class + Sized { } /// Retrieve a mutable reference to the user data from the controller. Must have been already - /// created with `set_user_data` or will return `None`. + /// created with `set_user_data` or in the `Desc` this came from or will return `None`. fn get_user_data_mut(&mut self) -> Option<&mut Self::UserData> { // SAFETY: self is a valid reference and is Class let mut user_data = unsafe { PxController_getUserData(self.as_ptr()) }; From e7656ef26ef345f51bd9233c197b26d51705fb95 Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 9 Nov 2023 01:55:44 +0100 Subject: [PATCH 4/5] actually run pxbind on my linux machine, fix up its output to match --- physx-sys/pxbind/src/consumer.rs | 6 +- physx-sys/pxbind/src/consumer/functions.rs | 42 +++++++--- .../structgen__all_the_things-3.snap | 8 +- .../snapshots/structgen__all_the_things.snap | 82 +++++++++---------- .../snapshots/structgen__many_things.snap | 2 +- physx-sys/src/generated/unix/structgen.rs | 2 +- physx-sys/src/lib.rs | 8 +- physx-sys/src/structgen/structgen.cpp | 82 +++++++++---------- 8 files changed, 131 insertions(+), 101 deletions(-) diff --git a/physx-sys/pxbind/src/consumer.rs b/physx-sys/pxbind/src/consumer.rs index 9a9b6c72..8eff3756 100644 --- a/physx-sys/pxbind/src/consumer.rs +++ b/physx-sys/pxbind/src/consumer.rs @@ -801,7 +801,7 @@ impl Builtin { Self::Mat44V => "physx_Mat44V_Pod", Self::Mat44 => "physx_PxMat44_Pod", Self::UserData => "void*", - Self::ConstUserData => "const void*", + Self::ConstUserData => "void const*", } } @@ -838,7 +838,7 @@ impl Builtin { Self::Mat44V => "physx::PxMat44V", Self::Mat44 => "physx::PxMat44", Self::UserData => "void*", - Self::ConstUserData => "const void*", + Self::ConstUserData => "void const*", } } @@ -858,6 +858,8 @@ impl Builtin { | Self::UInt | Self::Long | Self::ULong + | Self::UserData + | Self::ConstUserData ) } } diff --git a/physx-sys/pxbind/src/consumer/functions.rs b/physx-sys/pxbind/src/consumer/functions.rs index 3b5f9ef1..9f1c1bcc 100644 --- a/physx-sys/pxbind/src/consumer/functions.rs +++ b/physx-sys/pxbind/src/consumer/functions.rs @@ -1,4 +1,4 @@ -use super::{Comment, Item, Method, QualType, TemplateArg}; +use super::{Builtin, Comment, Item, Method, QualType, TemplateArg}; use crate::Node; use anyhow::Context as _; use std::borrow::Cow; @@ -197,14 +197,22 @@ impl<'ast> super::AstConsumer<'ast> { .name .as_deref() .map_or_else(|| format!("anon_param{i}").into(), Cow::Borrowed); - let kind = self - .parse_type(¶m.kind, template_types) - .with_context(|| { - format!( - "failed to parse parameter '{pname} ({})' for function '{name}'", - param.kind.qual_type, - ) - })?; + + let kind = if param.name.as_ref().map_or(false, |name| name == "userData") { + if param.kind.qual_type.contains("const") { + QualType::Builtin(Builtin::ConstUserData) + } else { + QualType::Builtin(Builtin::UserData) + } + } else { + self.parse_type(¶m.kind, template_types) + .with_context(|| { + format!( + "failed to parse parameter '{pname} ({})' for function '{name}'", + param.kind.qual_type, + ) + })? + }; func.params.push(Param { name: pname, kind }); } @@ -229,7 +237,21 @@ impl<'ast> super::AstConsumer<'ast> { .with_context(|| format!("function signature for '{name}' doesn't have a '('"))?; let ret = sig[..open_ind].trim(); - if ret != "void" { + if name.contains("getUserData") { + if ret == "void*" || ret == "void *" { + func.ret = Some(QualType::Builtin(Builtin::UserData)); + } else { + log::warn!( + "found function with name containing getUserData that had unexpected return type: {ret}" + ); + if ret != "void" { + func.ret = + Some(self.parse_type(ret, template_types).with_context(|| { + format!("failed to parse return type for '{name}'") + })?); + } + } + } else if ret != "void" { func.ret = Some( self.parse_type(ret, template_types) .with_context(|| format!("failed to parse return type for '{name}'"))?, diff --git a/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap b/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap index 1d24648f..ec7b775a 100644 --- a/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap +++ b/physx-sys/pxbind/tests/snapshots/structgen__all_the_things-3.snap @@ -1374,7 +1374,7 @@ pub struct PxSceneQueryDesc { #[repr(C)] pub struct PxBroadPhaseRegion { pub mBounds: PxBounds3, - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserData, } #[derive(Clone, Copy)] #[repr(C)] @@ -1737,7 +1737,7 @@ pub struct PxExtendedVec3 { #[repr(C)] pub struct PxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, } @@ -1745,7 +1745,7 @@ pub struct PxObstacle { #[repr(C)] pub struct PxBoxObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfExtents: PxVec3, @@ -1755,7 +1755,7 @@ pub struct PxBoxObstacle { #[repr(C)] pub struct PxCapsuleObstacle { pub structgen_pad0: [u8; 8], - pub mUserData: *mut std::ffi::c_void, + pub mUserData: UserData, pub mPos: PxExtendedVec3, pub mRot: PxQuat, pub mHalfHeight: f32, diff --git a/physx-sys/pxbind/tests/snapshots/structgen__all_the_things.snap b/physx-sys/pxbind/tests/snapshots/structgen__all_the_things.snap index 2427c724..f7d57384 100644 --- a/physx-sys/pxbind/tests/snapshots/structgen__all_the_things.snap +++ b/physx-sys/pxbind/tests/snapshots/structgen__all_the_things.snap @@ -955,7 +955,7 @@ int main() { struct physx_PxActor_Pod: public physx::PxActor { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxActor_Pod", "PxActor"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxActor_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxActor_Pod, userData)); sg.end_struct(sizeof(physx::PxActor)); } }; @@ -964,7 +964,7 @@ int main() { struct physx_PxAggregate_Pod: public physx::PxAggregate { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxAggregate_Pod", "PxAggregate"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxAggregate_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxAggregate_Pod, userData)); sg.end_struct(sizeof(physx::PxAggregate)); } }; @@ -1365,7 +1365,7 @@ int main() { struct physx_PxArticulationAttachment_Pod: public physx::PxArticulationAttachment { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationAttachment_Pod", "PxArticulationAttachment"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationAttachment_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationAttachment_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationAttachment)); } }; @@ -1374,7 +1374,7 @@ int main() { struct physx_PxArticulationTendonJoint_Pod: public physx::PxArticulationTendonJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationTendonJoint_Pod", "PxArticulationTendonJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendonJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendonJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationTendonJoint)); } }; @@ -1383,7 +1383,7 @@ int main() { struct physx_PxArticulationTendon_Pod: public physx::PxArticulationTendon { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationTendon_Pod", "PxArticulationTendon"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendon_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendon_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationTendon)); } }; @@ -1392,7 +1392,7 @@ int main() { struct physx_PxArticulationSpatialTendon_Pod: public physx::PxArticulationSpatialTendon { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationSpatialTendon_Pod", "PxArticulationSpatialTendon"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationSpatialTendon_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationSpatialTendon_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationSpatialTendon)); } }; @@ -1401,7 +1401,7 @@ int main() { struct physx_PxArticulationFixedTendon_Pod: public physx::PxArticulationFixedTendon { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationFixedTendon_Pod", "PxArticulationFixedTendon"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationFixedTendon_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationFixedTendon_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationFixedTendon)); } }; @@ -1472,7 +1472,7 @@ int main() { struct physx_PxArticulationSensor_Pod: public physx::PxArticulationSensor { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationSensor_Pod", "PxArticulationSensor"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationSensor_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationSensor_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationSensor)); } }; @@ -1481,7 +1481,7 @@ int main() { struct physx_PxArticulationReducedCoordinate_Pod: public physx::PxArticulationReducedCoordinate { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationReducedCoordinate_Pod", "PxArticulationReducedCoordinate"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationReducedCoordinate_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationReducedCoordinate_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationReducedCoordinate)); } }; @@ -1490,7 +1490,7 @@ int main() { struct physx_PxArticulationJointReducedCoordinate_Pod: public physx::PxArticulationJointReducedCoordinate { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationJointReducedCoordinate_Pod", "PxArticulationJointReducedCoordinate"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationJointReducedCoordinate_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationJointReducedCoordinate_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationJointReducedCoordinate)); } }; @@ -1501,7 +1501,7 @@ int main() { struct physx_PxShape_Pod: public physx::PxShape { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxShape_Pod", "PxShape"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxShape_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxShape_Pod, userData)); sg.end_struct(sizeof(physx::PxShape)); } }; @@ -1510,7 +1510,7 @@ int main() { struct physx_PxRigidActor_Pod: public physx::PxRigidActor { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidActor_Pod", "PxRigidActor"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidActor_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidActor_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidActor)); } }; @@ -1527,7 +1527,7 @@ int main() { struct physx_PxRigidBody_Pod: public physx::PxRigidBody { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidBody_Pod", "PxRigidBody"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidBody_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidBody_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidBody)); } }; @@ -1536,7 +1536,7 @@ int main() { struct physx_PxArticulationLink_Pod: public physx::PxArticulationLink { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationLink_Pod", "PxArticulationLink"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationLink_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationLink_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationLink)); } }; @@ -1578,7 +1578,7 @@ int main() { struct physx_PxConstraint_Pod: public physx::PxConstraint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxConstraint_Pod", "PxConstraint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxConstraint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxConstraint_Pod, userData)); sg.end_struct(sizeof(physx::PxConstraint)); } }; @@ -1725,7 +1725,7 @@ int main() { struct physx_PxBaseMaterial_Pod: public physx::PxBaseMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxBaseMaterial_Pod", "PxBaseMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBaseMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBaseMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxBaseMaterial)); } }; @@ -1734,7 +1734,7 @@ int main() { struct physx_PxFEMMaterial_Pod: public physx::PxFEMMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxFEMMaterial_Pod", "PxFEMMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxFEMMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxFEMMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxFEMMaterial)); } }; @@ -1767,7 +1767,7 @@ int main() { struct physx_PxMaterial_Pod: public physx::PxMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxMaterial_Pod", "PxMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxMaterial)); } }; @@ -1831,7 +1831,7 @@ int main() { struct physx_PxParticleMaterial_Pod: public physx::PxParticleMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxParticleMaterial_Pod", "PxParticleMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxParticleMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxParticleMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxParticleMaterial)); } }; @@ -1997,7 +1997,7 @@ int main() { struct physx_PxRigidDynamic_Pod: public physx::PxRigidDynamic { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidDynamic_Pod", "PxRigidDynamic"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidDynamic_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidDynamic_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidDynamic)); } }; @@ -2006,7 +2006,7 @@ int main() { struct physx_PxRigidStatic_Pod: public physx::PxRigidStatic { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidStatic_Pod", "PxRigidStatic"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidStatic_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidStatic_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidStatic)); } }; @@ -2037,7 +2037,7 @@ int main() { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxBroadPhaseRegion_Pod", "PxBroadPhaseRegion"); sg.add_field("physx_PxBounds3_Pod mBounds", "mBounds", "PxBounds3", sizeof(physx::PxBounds3), unsafe_offsetof(physx_PxBroadPhaseRegion_Pod, mBounds)); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBroadPhaseRegion_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBroadPhaseRegion_Pod, mUserData)); sg.end_struct(sizeof(physx::PxBroadPhaseRegion)); } }; @@ -2191,7 +2191,7 @@ int main() { sg.add_field("float frictionCorrelationDistance", "frictionCorrelationDistance", "f32", sizeof(float), unsafe_offsetof(physx_PxSceneDesc_Pod, frictionCorrelationDistance)); sg.add_field("uint32_t flags", "flags", "PxSceneFlags", sizeof(physx::PxSceneFlags), unsafe_offsetof(physx_PxSceneDesc_Pod, flags)); sg.add_field("physx_PxCpuDispatcher_Pod* cpuDispatcher", "cpuDispatcher", "*mut PxCpuDispatcher", sizeof(physx::PxCpuDispatcher*), unsafe_offsetof(physx_PxSceneDesc_Pod, cpuDispatcher)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxSceneDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxSceneDesc_Pod, userData)); sg.add_field("uint32_t solverBatchSize", "solverBatchSize", "u32", sizeof(uint32_t), unsafe_offsetof(physx_PxSceneDesc_Pod, solverBatchSize)); sg.add_field("uint32_t solverArticulationBatchSize", "solverArticulationBatchSize", "u32", sizeof(uint32_t), unsafe_offsetof(physx_PxSceneDesc_Pod, solverArticulationBatchSize)); sg.add_field("uint32_t nbContactDataBlocks", "nbContactDataBlocks", "u32", sizeof(uint32_t), unsafe_offsetof(physx_PxSceneDesc_Pod, nbContactDataBlocks)); @@ -2317,7 +2317,7 @@ int main() { struct physx_PxScene_Pod: public physx::PxScene { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxScene_Pod", "PxScene"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxScene_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxScene_Pod, userData)); sg.end_struct(sizeof(physx::PxScene)); } }; @@ -2504,7 +2504,7 @@ int main() { struct physx_PxObstacle_Pod: public physx::PxObstacle { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxObstacle_Pod", "PxObstacle"); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxObstacle_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxObstacle_Pod, mUserData)); sg.add_field("physx_PxExtendedVec3_Pod mPos", "mPos", "PxExtendedVec3", sizeof(physx::PxExtendedVec3), unsafe_offsetof(physx_PxObstacle_Pod, mPos)); sg.add_field("physx_PxQuat_Pod mRot", "mRot", "PxQuat", sizeof(physx::PxQuat), unsafe_offsetof(physx_PxObstacle_Pod, mRot)); sg.end_struct(sizeof(physx::PxObstacle)); @@ -2515,7 +2515,7 @@ int main() { struct physx_PxBoxObstacle_Pod: public physx::PxBoxObstacle { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxBoxObstacle_Pod", "PxBoxObstacle"); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBoxObstacle_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBoxObstacle_Pod, mUserData)); sg.add_field("physx_PxExtendedVec3_Pod mPos", "mPos", "PxExtendedVec3", sizeof(physx::PxExtendedVec3), unsafe_offsetof(physx_PxBoxObstacle_Pod, mPos)); sg.add_field("physx_PxQuat_Pod mRot", "mRot", "PxQuat", sizeof(physx::PxQuat), unsafe_offsetof(physx_PxBoxObstacle_Pod, mRot)); sg.add_field("physx_PxVec3_Pod mHalfExtents", "mHalfExtents", "PxVec3", sizeof(physx::PxVec3), unsafe_offsetof(physx_PxBoxObstacle_Pod, mHalfExtents)); @@ -2527,7 +2527,7 @@ int main() { struct physx_PxCapsuleObstacle_Pod: public physx::PxCapsuleObstacle { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxCapsuleObstacle_Pod", "PxCapsuleObstacle"); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mUserData)); sg.add_field("physx_PxExtendedVec3_Pod mPos", "mPos", "PxExtendedVec3", sizeof(physx::PxExtendedVec3), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mPos)); sg.add_field("physx_PxQuat_Pod mRot", "mRot", "PxQuat", sizeof(physx::PxQuat), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mRot)); sg.add_field("float mHalfHeight", "mHalfHeight", "f32", sizeof(float), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mHalfHeight)); @@ -2619,7 +2619,7 @@ int main() { sg.add_field("physx_PxVec3_Pod worldNormal", "worldNormal", "PxVec3", sizeof(physx::PxVec3), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, worldNormal)); sg.add_field("physx_PxVec3_Pod dir", "dir", "PxVec3", sizeof(physx::PxVec3), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, dir)); sg.add_field("float length", "length", "f32", sizeof(float), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, length)); - sg.add_field("void const* userData", "userData", "*const std::ffi::c_void", sizeof(void const*), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, userData)); + sg.add_field("void const* userData", "userData", "ConstUserData", sizeof(void const*), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, userData)); sg.end_struct(sizeof(physx::PxControllerObstacleHit)); } }; @@ -2658,7 +2658,7 @@ int main() { sg.add_field("physx_PxMaterial_Pod* material", "material", "*mut PxMaterial", sizeof(physx::PxMaterial*), unsafe_offsetof(physx_PxControllerDesc_Pod, material)); sg.add_field("bool registerDeletionListener", "registerDeletionListener", "bool", sizeof(bool), unsafe_offsetof(physx_PxControllerDesc_Pod, registerDeletionListener)); sg.add_field("uint8_t clientID", "clientID", "u8", sizeof(uint8_t), unsafe_offsetof(physx_PxControllerDesc_Pod, clientID)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxControllerDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxControllerDesc_Pod, userData)); sg.end_struct(sizeof(physx::PxControllerDesc)); } }; @@ -2684,7 +2684,7 @@ int main() { sg.add_field("physx_PxMaterial_Pod* material", "material", "*mut PxMaterial", sizeof(physx::PxMaterial*), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, material)); sg.add_field("bool registerDeletionListener", "registerDeletionListener", "bool", sizeof(bool), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, registerDeletionListener)); sg.add_field("uint8_t clientID", "clientID", "u8", sizeof(uint8_t), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, clientID)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, userData)); sg.add_field("float halfHeight", "halfHeight", "f32", sizeof(float), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, halfHeight)); sg.add_field("float halfSideExtent", "halfSideExtent", "f32", sizeof(float), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, halfSideExtent)); sg.add_field("float halfForwardExtent", "halfForwardExtent", "f32", sizeof(float), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, halfForwardExtent)); @@ -2713,7 +2713,7 @@ int main() { sg.add_field("physx_PxMaterial_Pod* material", "material", "*mut PxMaterial", sizeof(physx::PxMaterial*), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, material)); sg.add_field("bool registerDeletionListener", "registerDeletionListener", "bool", sizeof(bool), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, registerDeletionListener)); sg.add_field("uint8_t clientID", "clientID", "u8", sizeof(uint8_t), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, clientID)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, userData)); sg.add_field("float radius", "radius", "f32", sizeof(float), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, radius)); sg.add_field("float height", "height", "f32", sizeof(float), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, height)); sg.add_field("int32_t climbingMode", "climbingMode", "PxCapsuleClimbingMode", sizeof(physx::PxCapsuleClimbingMode::Enum), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, climbingMode)); @@ -2904,7 +2904,7 @@ int main() { struct physx_PxJoint_Pod: public physx::PxJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxJoint_Pod", "PxJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxJoint)); } }; @@ -2923,7 +2923,7 @@ int main() { struct physx_PxDistanceJoint_Pod: public physx::PxDistanceJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxDistanceJoint_Pod", "PxDistanceJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxDistanceJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxDistanceJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxDistanceJoint)); } }; @@ -2944,7 +2944,7 @@ int main() { struct physx_PxContactJoint_Pod: public physx::PxContactJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxContactJoint_Pod", "PxContactJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxContactJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxContactJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxContactJoint)); } }; @@ -2953,7 +2953,7 @@ int main() { struct physx_PxFixedJoint_Pod: public physx::PxFixedJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxFixedJoint_Pod", "PxFixedJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxFixedJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxFixedJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxFixedJoint)); } }; @@ -3051,7 +3051,7 @@ int main() { struct physx_PxPrismaticJoint_Pod: public physx::PxPrismaticJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxPrismaticJoint_Pod", "PxPrismaticJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxPrismaticJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxPrismaticJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxPrismaticJoint)); } }; @@ -3060,7 +3060,7 @@ int main() { struct physx_PxRevoluteJoint_Pod: public physx::PxRevoluteJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRevoluteJoint_Pod", "PxRevoluteJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRevoluteJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRevoluteJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxRevoluteJoint)); } }; @@ -3069,7 +3069,7 @@ int main() { struct physx_PxSphericalJoint_Pod: public physx::PxSphericalJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxSphericalJoint_Pod", "PxSphericalJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxSphericalJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxSphericalJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxSphericalJoint)); } }; @@ -3090,7 +3090,7 @@ int main() { struct physx_PxD6Joint_Pod: public physx::PxD6Joint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxD6Joint_Pod", "PxD6Joint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxD6Joint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxD6Joint_Pod, userData)); sg.end_struct(sizeof(physx::PxD6Joint)); } }; @@ -3099,7 +3099,7 @@ int main() { struct physx_PxGearJoint_Pod: public physx::PxGearJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxGearJoint_Pod", "PxGearJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxGearJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxGearJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxGearJoint)); } }; @@ -3108,7 +3108,7 @@ int main() { struct physx_PxRackAndPinionJoint_Pod: public physx::PxRackAndPinionJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRackAndPinionJoint_Pod", "PxRackAndPinionJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRackAndPinionJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRackAndPinionJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxRackAndPinionJoint)); } }; diff --git a/physx-sys/pxbind/tests/snapshots/structgen__many_things.snap b/physx-sys/pxbind/tests/snapshots/structgen__many_things.snap index 728aeff3..100c3a13 100644 --- a/physx-sys/pxbind/tests/snapshots/structgen__many_things.snap +++ b/physx-sys/pxbind/tests/snapshots/structgen__many_things.snap @@ -477,7 +477,7 @@ int main() { struct physx_PxShape_Pod: public physx::PxShape { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxShape_Pod", "PxShape"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxShape_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxShape_Pod, userData)); sg.end_struct(sizeof(physx::PxShape)); } }; diff --git a/physx-sys/src/generated/unix/structgen.rs b/physx-sys/src/generated/unix/structgen.rs index 9719a7c1..4fef483a 100644 --- a/physx-sys/src/generated/unix/structgen.rs +++ b/physx-sys/src/generated/unix/structgen.rs @@ -1134,7 +1134,7 @@ pub struct PxNodeIndex { #[repr(C)] pub struct PxRigidBody { pub structgen_pad0: [u8; 16], - pub userData: UserData + pub userData: UserData, } #[derive(Clone, Copy)] #[cfg_attr(feature = "debug-structs", derive(Debug))] diff --git a/physx-sys/src/lib.rs b/physx-sys/src/lib.rs index e04f123c..520e373b 100644 --- a/physx-sys/src/lib.rs +++ b/physx-sys/src/lib.rs @@ -205,7 +205,7 @@ const fn can_pack_into_pointer() -> bool { /// underlying data. Modification is still possible for data on the heap by using internal /// mutability. #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct ConstUserData(UserData); impl ConstUserData { @@ -262,6 +262,12 @@ impl Default for UserData { } } +impl std::fmt::Debug for UserData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("") + } +} + impl UserData { /// Create a new `UserData` which is immediately initialized with the given `data`. /// diff --git a/physx-sys/src/structgen/structgen.cpp b/physx-sys/src/structgen/structgen.cpp index 51d9811c..97dbd064 100644 --- a/physx-sys/src/structgen/structgen.cpp +++ b/physx-sys/src/structgen/structgen.cpp @@ -959,7 +959,7 @@ int main() { struct physx_PxActor_Pod: public physx::PxActor { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxActor_Pod", "PxActor"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxActor_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxActor_Pod, userData)); sg.end_struct(sizeof(physx::PxActor)); } }; @@ -968,7 +968,7 @@ int main() { struct physx_PxAggregate_Pod: public physx::PxAggregate { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxAggregate_Pod", "PxAggregate"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxAggregate_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxAggregate_Pod, userData)); sg.end_struct(sizeof(physx::PxAggregate)); } }; @@ -1369,7 +1369,7 @@ int main() { struct physx_PxArticulationAttachment_Pod: public physx::PxArticulationAttachment { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationAttachment_Pod", "PxArticulationAttachment"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationAttachment_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationAttachment_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationAttachment)); } }; @@ -1378,7 +1378,7 @@ int main() { struct physx_PxArticulationTendonJoint_Pod: public physx::PxArticulationTendonJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationTendonJoint_Pod", "PxArticulationTendonJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendonJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendonJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationTendonJoint)); } }; @@ -1387,7 +1387,7 @@ int main() { struct physx_PxArticulationTendon_Pod: public physx::PxArticulationTendon { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationTendon_Pod", "PxArticulationTendon"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendon_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationTendon_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationTendon)); } }; @@ -1396,7 +1396,7 @@ int main() { struct physx_PxArticulationSpatialTendon_Pod: public physx::PxArticulationSpatialTendon { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationSpatialTendon_Pod", "PxArticulationSpatialTendon"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationSpatialTendon_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationSpatialTendon_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationSpatialTendon)); } }; @@ -1405,7 +1405,7 @@ int main() { struct physx_PxArticulationFixedTendon_Pod: public physx::PxArticulationFixedTendon { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationFixedTendon_Pod", "PxArticulationFixedTendon"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationFixedTendon_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationFixedTendon_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationFixedTendon)); } }; @@ -1476,7 +1476,7 @@ int main() { struct physx_PxArticulationSensor_Pod: public physx::PxArticulationSensor { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationSensor_Pod", "PxArticulationSensor"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationSensor_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationSensor_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationSensor)); } }; @@ -1485,7 +1485,7 @@ int main() { struct physx_PxArticulationReducedCoordinate_Pod: public physx::PxArticulationReducedCoordinate { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationReducedCoordinate_Pod", "PxArticulationReducedCoordinate"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationReducedCoordinate_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationReducedCoordinate_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationReducedCoordinate)); } }; @@ -1494,7 +1494,7 @@ int main() { struct physx_PxArticulationJointReducedCoordinate_Pod: public physx::PxArticulationJointReducedCoordinate { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationJointReducedCoordinate_Pod", "PxArticulationJointReducedCoordinate"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationJointReducedCoordinate_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationJointReducedCoordinate_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationJointReducedCoordinate)); } }; @@ -1505,7 +1505,7 @@ int main() { struct physx_PxShape_Pod: public physx::PxShape { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxShape_Pod", "PxShape"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxShape_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxShape_Pod, userData)); sg.end_struct(sizeof(physx::PxShape)); } }; @@ -1514,7 +1514,7 @@ int main() { struct physx_PxRigidActor_Pod: public physx::PxRigidActor { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidActor_Pod", "PxRigidActor"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidActor_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidActor_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidActor)); } }; @@ -1531,7 +1531,7 @@ int main() { struct physx_PxRigidBody_Pod: public physx::PxRigidBody { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidBody_Pod", "PxRigidBody"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidBody_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidBody_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidBody)); } }; @@ -1540,7 +1540,7 @@ int main() { struct physx_PxArticulationLink_Pod: public physx::PxArticulationLink { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxArticulationLink_Pod", "PxArticulationLink"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxArticulationLink_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxArticulationLink_Pod, userData)); sg.end_struct(sizeof(physx::PxArticulationLink)); } }; @@ -1582,7 +1582,7 @@ int main() { struct physx_PxConstraint_Pod: public physx::PxConstraint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxConstraint_Pod", "PxConstraint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxConstraint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxConstraint_Pod, userData)); sg.end_struct(sizeof(physx::PxConstraint)); } }; @@ -1729,7 +1729,7 @@ int main() { struct physx_PxBaseMaterial_Pod: public physx::PxBaseMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxBaseMaterial_Pod", "PxBaseMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBaseMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBaseMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxBaseMaterial)); } }; @@ -1738,7 +1738,7 @@ int main() { struct physx_PxFEMMaterial_Pod: public physx::PxFEMMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxFEMMaterial_Pod", "PxFEMMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxFEMMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxFEMMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxFEMMaterial)); } }; @@ -1771,7 +1771,7 @@ int main() { struct physx_PxMaterial_Pod: public physx::PxMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxMaterial_Pod", "PxMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxMaterial)); } }; @@ -1835,7 +1835,7 @@ int main() { struct physx_PxParticleMaterial_Pod: public physx::PxParticleMaterial { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxParticleMaterial_Pod", "PxParticleMaterial"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxParticleMaterial_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxParticleMaterial_Pod, userData)); sg.end_struct(sizeof(physx::PxParticleMaterial)); } }; @@ -2001,7 +2001,7 @@ int main() { struct physx_PxRigidDynamic_Pod: public physx::PxRigidDynamic { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidDynamic_Pod", "PxRigidDynamic"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidDynamic_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidDynamic_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidDynamic)); } }; @@ -2010,7 +2010,7 @@ int main() { struct physx_PxRigidStatic_Pod: public physx::PxRigidStatic { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRigidStatic_Pod", "PxRigidStatic"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRigidStatic_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRigidStatic_Pod, userData)); sg.end_struct(sizeof(physx::PxRigidStatic)); } }; @@ -2041,7 +2041,7 @@ int main() { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxBroadPhaseRegion_Pod", "PxBroadPhaseRegion"); sg.add_field("physx_PxBounds3_Pod mBounds", "mBounds", "PxBounds3", sizeof(physx::PxBounds3), unsafe_offsetof(physx_PxBroadPhaseRegion_Pod, mBounds)); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBroadPhaseRegion_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBroadPhaseRegion_Pod, mUserData)); sg.end_struct(sizeof(physx::PxBroadPhaseRegion)); } }; @@ -2195,7 +2195,7 @@ int main() { sg.add_field("float frictionCorrelationDistance", "frictionCorrelationDistance", "f32", sizeof(float), unsafe_offsetof(physx_PxSceneDesc_Pod, frictionCorrelationDistance)); sg.add_field("uint32_t flags", "flags", "PxSceneFlags", sizeof(physx::PxSceneFlags), unsafe_offsetof(physx_PxSceneDesc_Pod, flags)); sg.add_field("physx_PxCpuDispatcher_Pod* cpuDispatcher", "cpuDispatcher", "*mut PxCpuDispatcher", sizeof(physx::PxCpuDispatcher*), unsafe_offsetof(physx_PxSceneDesc_Pod, cpuDispatcher)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxSceneDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxSceneDesc_Pod, userData)); sg.add_field("uint32_t solverBatchSize", "solverBatchSize", "u32", sizeof(uint32_t), unsafe_offsetof(physx_PxSceneDesc_Pod, solverBatchSize)); sg.add_field("uint32_t solverArticulationBatchSize", "solverArticulationBatchSize", "u32", sizeof(uint32_t), unsafe_offsetof(physx_PxSceneDesc_Pod, solverArticulationBatchSize)); sg.add_field("uint32_t nbContactDataBlocks", "nbContactDataBlocks", "u32", sizeof(uint32_t), unsafe_offsetof(physx_PxSceneDesc_Pod, nbContactDataBlocks)); @@ -2321,7 +2321,7 @@ int main() { struct physx_PxScene_Pod: public physx::PxScene { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxScene_Pod", "PxScene"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxScene_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxScene_Pod, userData)); sg.end_struct(sizeof(physx::PxScene)); } }; @@ -2508,7 +2508,7 @@ int main() { struct physx_PxObstacle_Pod: public physx::PxObstacle { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxObstacle_Pod", "PxObstacle"); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxObstacle_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxObstacle_Pod, mUserData)); sg.add_field("physx_PxExtendedVec3_Pod mPos", "mPos", "PxExtendedVec3", sizeof(physx::PxExtendedVec3), unsafe_offsetof(physx_PxObstacle_Pod, mPos)); sg.add_field("physx_PxQuat_Pod mRot", "mRot", "PxQuat", sizeof(physx::PxQuat), unsafe_offsetof(physx_PxObstacle_Pod, mRot)); sg.end_struct(sizeof(physx::PxObstacle)); @@ -2519,7 +2519,7 @@ int main() { struct physx_PxBoxObstacle_Pod: public physx::PxBoxObstacle { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxBoxObstacle_Pod", "PxBoxObstacle"); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBoxObstacle_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBoxObstacle_Pod, mUserData)); sg.add_field("physx_PxExtendedVec3_Pod mPos", "mPos", "PxExtendedVec3", sizeof(physx::PxExtendedVec3), unsafe_offsetof(physx_PxBoxObstacle_Pod, mPos)); sg.add_field("physx_PxQuat_Pod mRot", "mRot", "PxQuat", sizeof(physx::PxQuat), unsafe_offsetof(physx_PxBoxObstacle_Pod, mRot)); sg.add_field("physx_PxVec3_Pod mHalfExtents", "mHalfExtents", "PxVec3", sizeof(physx::PxVec3), unsafe_offsetof(physx_PxBoxObstacle_Pod, mHalfExtents)); @@ -2531,7 +2531,7 @@ int main() { struct physx_PxCapsuleObstacle_Pod: public physx::PxCapsuleObstacle { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxCapsuleObstacle_Pod", "PxCapsuleObstacle"); - sg.add_field("void* mUserData", "mUserData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mUserData)); + sg.add_field("void* mUserData", "mUserData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mUserData)); sg.add_field("physx_PxExtendedVec3_Pod mPos", "mPos", "PxExtendedVec3", sizeof(physx::PxExtendedVec3), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mPos)); sg.add_field("physx_PxQuat_Pod mRot", "mRot", "PxQuat", sizeof(physx::PxQuat), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mRot)); sg.add_field("float mHalfHeight", "mHalfHeight", "f32", sizeof(float), unsafe_offsetof(physx_PxCapsuleObstacle_Pod, mHalfHeight)); @@ -2623,7 +2623,7 @@ int main() { sg.add_field("physx_PxVec3_Pod worldNormal", "worldNormal", "PxVec3", sizeof(physx::PxVec3), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, worldNormal)); sg.add_field("physx_PxVec3_Pod dir", "dir", "PxVec3", sizeof(physx::PxVec3), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, dir)); sg.add_field("float length", "length", "f32", sizeof(float), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, length)); - sg.add_field("void const* userData", "userData", "*const std::ffi::c_void", sizeof(void const*), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, userData)); + sg.add_field("void const* userData", "userData", "ConstUserData", sizeof(void const*), unsafe_offsetof(physx_PxControllerObstacleHit_Pod, userData)); sg.end_struct(sizeof(physx::PxControllerObstacleHit)); } }; @@ -2662,7 +2662,7 @@ int main() { sg.add_field("physx_PxMaterial_Pod* material", "material", "*mut PxMaterial", sizeof(physx::PxMaterial*), unsafe_offsetof(physx_PxControllerDesc_Pod, material)); sg.add_field("bool registerDeletionListener", "registerDeletionListener", "bool", sizeof(bool), unsafe_offsetof(physx_PxControllerDesc_Pod, registerDeletionListener)); sg.add_field("uint8_t clientID", "clientID", "u8", sizeof(uint8_t), unsafe_offsetof(physx_PxControllerDesc_Pod, clientID)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxControllerDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxControllerDesc_Pod, userData)); sg.end_struct(sizeof(physx::PxControllerDesc)); } }; @@ -2688,7 +2688,7 @@ int main() { sg.add_field("physx_PxMaterial_Pod* material", "material", "*mut PxMaterial", sizeof(physx::PxMaterial*), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, material)); sg.add_field("bool registerDeletionListener", "registerDeletionListener", "bool", sizeof(bool), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, registerDeletionListener)); sg.add_field("uint8_t clientID", "clientID", "u8", sizeof(uint8_t), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, clientID)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, userData)); sg.add_field("float halfHeight", "halfHeight", "f32", sizeof(float), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, halfHeight)); sg.add_field("float halfSideExtent", "halfSideExtent", "f32", sizeof(float), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, halfSideExtent)); sg.add_field("float halfForwardExtent", "halfForwardExtent", "f32", sizeof(float), unsafe_offsetof(physx_PxBoxControllerDesc_Pod, halfForwardExtent)); @@ -2717,7 +2717,7 @@ int main() { sg.add_field("physx_PxMaterial_Pod* material", "material", "*mut PxMaterial", sizeof(physx::PxMaterial*), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, material)); sg.add_field("bool registerDeletionListener", "registerDeletionListener", "bool", sizeof(bool), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, registerDeletionListener)); sg.add_field("uint8_t clientID", "clientID", "u8", sizeof(uint8_t), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, clientID)); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, userData)); sg.add_field("float radius", "radius", "f32", sizeof(float), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, radius)); sg.add_field("float height", "height", "f32", sizeof(float), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, height)); sg.add_field("int32_t climbingMode", "climbingMode", "PxCapsuleClimbingMode", sizeof(physx::PxCapsuleClimbingMode::Enum), unsafe_offsetof(physx_PxCapsuleControllerDesc_Pod, climbingMode)); @@ -2908,7 +2908,7 @@ int main() { struct physx_PxJoint_Pod: public physx::PxJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxJoint_Pod", "PxJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxJoint)); } }; @@ -2927,7 +2927,7 @@ int main() { struct physx_PxDistanceJoint_Pod: public physx::PxDistanceJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxDistanceJoint_Pod", "PxDistanceJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxDistanceJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxDistanceJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxDistanceJoint)); } }; @@ -2948,7 +2948,7 @@ int main() { struct physx_PxContactJoint_Pod: public physx::PxContactJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxContactJoint_Pod", "PxContactJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxContactJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxContactJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxContactJoint)); } }; @@ -2957,7 +2957,7 @@ int main() { struct physx_PxFixedJoint_Pod: public physx::PxFixedJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxFixedJoint_Pod", "PxFixedJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxFixedJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxFixedJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxFixedJoint)); } }; @@ -3055,7 +3055,7 @@ int main() { struct physx_PxPrismaticJoint_Pod: public physx::PxPrismaticJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxPrismaticJoint_Pod", "PxPrismaticJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxPrismaticJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxPrismaticJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxPrismaticJoint)); } }; @@ -3064,7 +3064,7 @@ int main() { struct physx_PxRevoluteJoint_Pod: public physx::PxRevoluteJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRevoluteJoint_Pod", "PxRevoluteJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRevoluteJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRevoluteJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxRevoluteJoint)); } }; @@ -3073,7 +3073,7 @@ int main() { struct physx_PxSphericalJoint_Pod: public physx::PxSphericalJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxSphericalJoint_Pod", "PxSphericalJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxSphericalJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxSphericalJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxSphericalJoint)); } }; @@ -3094,7 +3094,7 @@ int main() { struct physx_PxD6Joint_Pod: public physx::PxD6Joint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxD6Joint_Pod", "PxD6Joint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxD6Joint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxD6Joint_Pod, userData)); sg.end_struct(sizeof(physx::PxD6Joint)); } }; @@ -3103,7 +3103,7 @@ int main() { struct physx_PxGearJoint_Pod: public physx::PxGearJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxGearJoint_Pod", "PxGearJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxGearJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxGearJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxGearJoint)); } }; @@ -3112,7 +3112,7 @@ int main() { struct physx_PxRackAndPinionJoint_Pod: public physx::PxRackAndPinionJoint { static void dump_layout(PodStructGen& sg) { sg.begin_struct("physx_PxRackAndPinionJoint_Pod", "PxRackAndPinionJoint"); - sg.add_field("void* userData", "userData", "*mut std::ffi::c_void", sizeof(void*), unsafe_offsetof(physx_PxRackAndPinionJoint_Pod, userData)); + sg.add_field("void* userData", "userData", "UserData", sizeof(void*), unsafe_offsetof(physx_PxRackAndPinionJoint_Pod, userData)); sg.end_struct(sizeof(physx::PxRackAndPinionJoint)); } }; From 530d6fd123e769a5b603a18a943d9a2e2736b2d6 Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 9 Nov 2023 11:59:15 +0100 Subject: [PATCH 5/5] fix typo --- physx-sys/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/physx-sys/src/lib.rs b/physx-sys/src/lib.rs index 520e373b..b3dd6d12 100644 --- a/physx-sys/src/lib.rs +++ b/physx-sys/src/lib.rs @@ -244,7 +244,7 @@ impl ConstUserData { /// If not, use the `heap` family of methods. /// /// NOTE: In a world where cross-language C-to-Rust link-time optimization existed and we statically -/// linked PhysX, this could possibly break since on the PhsyX side it's a `void*` which is +/// linked PhysX, this could possibly break since on the PhysX side it's a `void*` which is /// `noundef` under Clang whereas we explicitly allow types with arbitrary layout (including /// padding) to be packed as long as they have the necessary size an alignment. But, cross-lang /// LTO like that does not currently exist and is unlikely to happen, so it's Fine TM.