Skip to content

Commit

Permalink
Small iteration on safe wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
LPGhatguy committed Apr 20, 2024
1 parent 7c77a64 commit aaff39c
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 53 deletions.
4 changes: 4 additions & 0 deletions crates/jolt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ edition = "2021"

[dependencies]
jolt-sys = { path = "../jolt-sys" }

[lints.clippy]
new_without_default = { level = "allow" }
too_many_arguments = { level = "allow" }
13 changes: 13 additions & 0 deletions crates/jolt/src/body_interface.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use jolt_sys::*;

pub struct BodyInterface(*mut JPC_BodyInterface);

impl BodyInterface {
pub(crate) fn new(inner: *mut JPC_BodyInterface) -> Self {
Self(inner)
}

pub fn as_raw(&self) -> *mut JPC_BodyInterface {
self.0
}
}
65 changes: 65 additions & 0 deletions crates/jolt/src/interfaces.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::ffi::{c_uint, c_void};
use std::marker::PhantomData;
use std::ptr;

use jolt_sys::*;

use crate::{BroadPhaseLayer, ObjectLayer};

pub trait IntoBroadPhaseLayerInterface {
fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface;
}

pub trait BroadPhaseLayerInterface: Sized {
fn get_num_broad_phase_layers(&self) -> u32;
fn get_broad_phase_layer(&self, layer: ObjectLayer) -> BroadPhaseLayer;

fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface {
type Bridge<T> = BroadPhaseLayerInterfaceBridge<T>;

let fns = JPC_BroadPhaseLayerInterfaceFns {
GetNumBroadPhaseLayers: Some(Bridge::<Self>::GetNumBroadPhaseLayers as _),
GetBroadPhaseLayer: Some(Bridge::<Self>::GetBroadPhaseLayer as _),
};

unsafe { JPC_BroadPhaseLayerInterface_new(ptr::from_ref(self).cast::<c_void>(), fns) }
}
}

impl IntoBroadPhaseLayerInterface for *mut JPC_BroadPhaseLayerInterface {
fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface {
*self
}
}

impl<T> IntoBroadPhaseLayerInterface for T
where
T: BroadPhaseLayerInterface,
{
fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface {
<Self as BroadPhaseLayerInterface>::as_raw(self)
}
}

struct BroadPhaseLayerInterfaceBridge<T> {
_phantom: PhantomData<T>,
}

#[allow(non_snake_case)]
impl<T: BroadPhaseLayerInterface> BroadPhaseLayerInterfaceBridge<T> {
unsafe extern "C" fn GetNumBroadPhaseLayers(this: *const c_void) -> c_uint {
let this = this.cast::<T>().as_ref().unwrap();

this.get_num_broad_phase_layers()
}

unsafe extern "C" fn GetBroadPhaseLayer(
this: *const c_void,
layer: JPC_ObjectLayer,
) -> JPC_BroadPhaseLayer {
let this = this.cast::<T>().as_ref().unwrap();
let layer = ObjectLayer(layer);

this.get_broad_phase_layer(layer).raw()
}
}
61 changes: 8 additions & 53 deletions crates/jolt/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::ffi::{c_uint, c_void};
use std::marker::PhantomData;
use std::ptr;
use jolt_sys::*;

use jolt_sys::{
JPC_BroadPhaseLayer, JPC_BroadPhaseLayerInterface, JPC_BroadPhaseLayerInterfaceFns,
JPC_BroadPhaseLayerInterface_new, JPC_ObjectLayer,
};
mod body_interface;
mod interfaces;
mod physics_system;

pub use crate::body_interface::*;
pub use crate::interfaces::*;
pub use crate::physics_system::*;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ObjectLayer(JPC_ObjectLayer);
Expand All @@ -32,49 +33,3 @@ impl BroadPhaseLayer {
self.0
}
}

pub trait BroadPhaseLayerInterface: Sized {
fn get_num_broad_phase_layers(&self) -> u32;
fn get_broad_phase_layer(&self, layer: ObjectLayer) -> BroadPhaseLayer;

fn as_raw(&self) -> *mut JPC_BroadPhaseLayerInterface {
jpc_bpli(self)
}
}

struct BroadPhaseLayerInterfaceBridge<T> {
_phantom: PhantomData<T>,
}

#[allow(non_snake_case)]
impl<T: BroadPhaseLayerInterface> BroadPhaseLayerInterfaceBridge<T> {
unsafe extern "C" fn GetNumBroadPhaseLayers(this: *const c_void) -> c_uint {
let this = this.cast::<T>().as_ref().unwrap();

this.get_num_broad_phase_layers()
}

unsafe extern "C" fn GetBroadPhaseLayer(
this: *const c_void,
layer: JPC_ObjectLayer,
) -> JPC_BroadPhaseLayer {
let this = this.cast::<T>().as_ref().unwrap();
let layer = ObjectLayer(layer);

this.get_broad_phase_layer(layer).raw()
}
}

fn jpc_bpli<T>(input: &T) -> *mut JPC_BroadPhaseLayerInterface
where
T: BroadPhaseLayerInterface,
{
type Bridge<T> = BroadPhaseLayerInterfaceBridge<T>;

let fns = JPC_BroadPhaseLayerInterfaceFns {
GetNumBroadPhaseLayers: Some(Bridge::<T>::GetNumBroadPhaseLayers as _),
GetBroadPhaseLayer: Some(Bridge::<T>::GetBroadPhaseLayer as _),
};

unsafe { JPC_BroadPhaseLayerInterface_new(ptr::from_ref(input).cast::<c_void>(), fns) }
}
53 changes: 53 additions & 0 deletions crates/jolt/src/physics_system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use jolt_sys::*;

use crate::{BodyInterface, IntoBroadPhaseLayerInterface};

pub struct PhysicsSystem(*mut JPC_PhysicsSystem);

impl PhysicsSystem {
pub fn new() -> Self {
unsafe { Self(JPC_PhysicsSystem_new()) }
}

/// # Safety
/// no
pub unsafe fn init(
&self,
max_bodies: u32,
num_body_mutexes: u32,
max_body_pairs: u32,
max_contact_constraints: u32,
broad_phase_layer_interface: impl IntoBroadPhaseLayerInterface,
object_vs_broad_phase_layer_interface: *mut JPC_ObjectVsBroadPhaseLayerFilter,
object_layer_pair_filter: *mut JPC_ObjectLayerPairFilter,
) {
unsafe {
JPC_PhysicsSystem_Init(
self.0,
max_bodies,
num_body_mutexes,
max_body_pairs,
max_contact_constraints,
broad_phase_layer_interface.as_raw(),
object_vs_broad_phase_layer_interface,
object_layer_pair_filter,
);
}
}

pub fn body_interface(&self) -> BodyInterface {
unsafe { BodyInterface::new(JPC_PhysicsSystem_GetBodyInterface(self.0)) }
}

pub fn as_raw(&self) -> *mut JPC_PhysicsSystem {
self.0
}
}

impl Drop for PhysicsSystem {
fn drop(&mut self) {
unsafe {
JPC_PhysicsSystem_delete(self.0);
}
}
}

0 comments on commit aaff39c

Please sign in to comment.