mujoco_rs/
util.rs

1//! Utility related data
2use std::ops::{Deref, DerefMut};
3
4
5/// Creates a [`PointerViewMut`] instance based on the pointer (`ptr`) and other
6/// lookup variables that define the mapping in MuJoCo's mjModel struct.
7/// Format: source pointer, item id, map from item id to index inside the array of all items' values,
8///         number of items, maximum number of elements inside the array of all items' values
9#[macro_export]
10macro_rules! mj_slice_view {
11    ($ptr:expr, $id:expr, $addr_map:expr, $njnt:expr, $max_n:expr) => {
12        {
13            let start_addr = *$addr_map.add($id) as isize;
14            if start_addr == -1 {
15                (0, 0)
16            }
17            else
18            {
19                let end_addr = if $id + 1 < $njnt {*$addr_map.add($id + 1) as usize} else {$max_n};
20                let n = end_addr - start_addr as usize;
21                (start_addr as usize, n)
22            }
23        }
24    };
25}
26
27/// Provides a more direct view to a C array.
28/// # Safety
29/// This does not check if the data is valid. It is assumed
30/// the correct data is given and that it doesn't get dropped before this struct.
31/// This does not break Rust's checks as we create the view each
32/// time from the saved pointers.
33/// This should ONLY be used within a wrapper who fully encapsulates the underlying data.
34#[derive(Debug)]
35pub struct PointerViewMut<T> {
36    ptr: *mut T,
37    len: usize,
38}
39
40impl<T> PointerViewMut<T> {
41    pub(crate) fn new(ptr: *mut T, len: usize) -> Self {
42        Self {ptr, len}
43    }
44
45    #[allow(unused)]
46    pub(crate) unsafe fn set_len(&mut self, len: usize) {
47        self.len = len;
48    }
49}
50
51/// Compares if the two views point to the same data.
52impl<T> PartialEq for PointerViewMut<T> {
53    fn eq(&self, other: &Self) -> bool {
54        self.ptr == other.ptr  // if the pointer differs, this isn't a view to the same data
55    }
56}
57
58impl<T> Deref for PointerViewMut<T> {
59    type Target = [T];
60    fn deref(&self) -> &Self::Target {
61        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
62    }
63}
64
65impl<T> DerefMut for PointerViewMut<T> {
66    fn deref_mut(&mut self) -> &mut Self::Target {
67        unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
68    }
69}
70
71/// Provides a more direct view to a C array.
72/// # Safety
73/// This does not check if the data is valid. It is assumed
74/// the correct data is given and that it doesn't get dropped before this struct.
75/// This does not break Rust's checks as we create the view each
76/// time from the saved pointers.
77/// This should ONLY be used within a wrapper who fully encapsulates the underlying data.
78#[derive(Debug)]
79pub struct PointerView<T> {
80    ptr: *const T,
81    len: usize,
82}
83
84impl<T> PointerView<T> {
85    pub(crate) fn new(ptr: *const T, len: usize) -> Self {
86        Self {ptr, len}
87    }
88    
89    #[allow(unused)]
90    pub(crate) unsafe fn set_len(&mut self, len: usize) {
91        self.len = len;
92    }
93}
94
95/// Compares if the two views point to the same data.
96impl<T> PartialEq for PointerView<T> {
97    fn eq(&self, other: &Self) -> bool {
98        self.ptr == other.ptr  // if the pointer differs, this isn't a view to the same data
99    }
100}
101
102impl<T> Deref for PointerView<T> {
103    type Target = [T];
104    fn deref(&self) -> &Self::Target {
105        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
106    }
107}