mlua_codemp_patch/
types.rs

1use std::cell::UnsafeCell;
2use std::fmt;
3use std::os::raw::{c_int, c_void};
4use std::rc::Rc;
5
6use crate::error::Result;
7#[cfg(not(feature = "luau"))]
8use crate::hook::Debug;
9use crate::state::{ExtraData, Lua, RawLua, WeakLua};
10
11// Re-export mutex wrappers
12pub(crate) use sync::{ArcReentrantMutexGuard, ReentrantMutex, ReentrantMutexGuard, XRc, XWeak};
13
14#[cfg(all(feature = "async", feature = "send"))]
15pub(crate) type BoxFuture<'a, T> = futures_util::future::BoxFuture<'a, T>;
16
17#[cfg(all(feature = "async", not(feature = "send")))]
18pub(crate) type BoxFuture<'a, T> = futures_util::future::LocalBoxFuture<'a, T>;
19
20pub use app_data::{AppData, AppDataRef, AppDataRefMut};
21pub use registry_key::RegistryKey;
22#[cfg(any(feature = "luau", doc))]
23pub use vector::Vector;
24
25/// Type of Lua integer numbers.
26pub type Integer = ffi::lua_Integer;
27/// Type of Lua floating point numbers.
28pub type Number = ffi::lua_Number;
29
30// Represents different subtypes wrapped to AnyUserData
31#[derive(Debug, Copy, Clone, Eq, PartialEq)]
32pub(crate) enum SubtypeId {
33    None,
34    #[cfg(feature = "luau")]
35    Buffer,
36    #[cfg(feature = "luajit")]
37    CData,
38}
39
40/// A "light" userdata value. Equivalent to an unmanaged raw pointer.
41#[derive(Debug, Copy, Clone, Eq, PartialEq)]
42pub struct LightUserData(pub *mut c_void);
43
44#[cfg(feature = "send")]
45unsafe impl Send for LightUserData {}
46#[cfg(feature = "send")]
47unsafe impl Sync for LightUserData {}
48
49#[cfg(feature = "send")]
50pub(crate) type Callback = Box<dyn Fn(&RawLua, c_int) -> Result<c_int> + Send + 'static>;
51
52#[cfg(not(feature = "send"))]
53pub(crate) type Callback = Box<dyn Fn(&RawLua, c_int) -> Result<c_int> + 'static>;
54
55pub(crate) struct Upvalue<T> {
56    pub(crate) data: T,
57    pub(crate) extra: XRc<UnsafeCell<ExtraData>>,
58}
59
60pub(crate) type CallbackUpvalue = Upvalue<Callback>;
61
62#[cfg(all(feature = "async", feature = "send"))]
63pub(crate) type AsyncCallback =
64    Box<dyn for<'a> Fn(&'a RawLua, c_int) -> BoxFuture<'a, Result<c_int>> + Send + 'static>;
65
66#[cfg(all(feature = "async", not(feature = "send")))]
67pub(crate) type AsyncCallback =
68    Box<dyn for<'a> Fn(&'a RawLua, c_int) -> BoxFuture<'a, Result<c_int>> + 'static>;
69
70#[cfg(feature = "async")]
71pub(crate) type AsyncCallbackUpvalue = Upvalue<AsyncCallback>;
72
73#[cfg(feature = "async")]
74pub(crate) type AsyncPollUpvalue = Upvalue<BoxFuture<'static, Result<c_int>>>;
75
76/// Type to set next Luau VM action after executing interrupt function.
77#[cfg(any(feature = "luau", doc))]
78#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
79pub enum VmState {
80    Continue,
81    Yield,
82}
83
84#[cfg(all(feature = "send", not(feature = "luau")))]
85pub(crate) type HookCallback = Rc<dyn Fn(&Lua, Debug) -> Result<()> + Send>;
86
87#[cfg(all(not(feature = "send"), not(feature = "luau")))]
88pub(crate) type HookCallback = Rc<dyn Fn(&Lua, Debug) -> Result<()>>;
89
90#[cfg(all(feature = "send", feature = "luau"))]
91pub(crate) type InterruptCallback = Rc<dyn Fn(&Lua) -> Result<VmState> + Send>;
92
93#[cfg(all(not(feature = "send"), feature = "luau"))]
94pub(crate) type InterruptCallback = Rc<dyn Fn(&Lua) -> Result<VmState>>;
95
96#[cfg(all(feature = "send", feature = "lua54"))]
97pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &str, bool) -> Result<()> + Send>;
98
99#[cfg(all(not(feature = "send"), feature = "lua54"))]
100pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &str, bool) -> Result<()>>;
101
102/// A trait that adds `Send` requirement if `send` feature is enabled.
103#[cfg(feature = "send")]
104pub trait MaybeSend: Send {}
105#[cfg(feature = "send")]
106impl<T: Send> MaybeSend for T {}
107
108#[cfg(not(feature = "send"))]
109pub trait MaybeSend {}
110#[cfg(not(feature = "send"))]
111impl<T> MaybeSend for T {}
112
113pub(crate) struct DestructedUserdata;
114
115pub(crate) struct ValueRef {
116    pub(crate) lua: WeakLua,
117    pub(crate) index: c_int,
118    pub(crate) drop: bool,
119}
120
121impl ValueRef {
122    #[inline]
123    pub(crate) fn new(lua: &RawLua, index: c_int) -> Self {
124        ValueRef {
125            lua: lua.weak().clone(),
126            index,
127            drop: true,
128        }
129    }
130
131    #[inline]
132    pub(crate) fn to_pointer(&self) -> *const c_void {
133        let lua = self.lua.lock();
134        unsafe { ffi::lua_topointer(lua.ref_thread(), self.index) }
135    }
136
137    /// Returns a copy of the value, which is valid as long as the original value is held.
138    #[inline]
139    pub(crate) fn copy(&self) -> Self {
140        ValueRef {
141            lua: self.lua.clone(),
142            index: self.index,
143            drop: false,
144        }
145    }
146}
147
148impl fmt::Debug for ValueRef {
149    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150        write!(f, "Ref({:p})", self.to_pointer())
151    }
152}
153
154impl Clone for ValueRef {
155    fn clone(&self) -> Self {
156        unsafe { self.lua.lock().clone_ref(self) }
157    }
158}
159
160impl Drop for ValueRef {
161    fn drop(&mut self) {
162        if self.drop {
163            if let Some(lua) = self.lua.try_lock() {
164                unsafe { lua.drop_ref(self) };
165            }
166        }
167    }
168}
169
170impl PartialEq for ValueRef {
171    fn eq(&self, other: &Self) -> bool {
172        assert!(
173            self.lua == other.lua,
174            "Lua instance passed Value created from a different main Lua state"
175        );
176        let lua = self.lua.lock();
177        unsafe { ffi::lua_rawequal(lua.ref_thread(), self.index, other.index) == 1 }
178    }
179}
180
181mod app_data;
182mod registry_key;
183mod sync;
184
185#[cfg(any(feature = "luau", doc))]
186mod vector;
187
188#[cfg(test)]
189mod assertions {
190    use super::*;
191
192    #[cfg(not(feature = "send"))]
193    static_assertions::assert_not_impl_any!(ValueRef: Send);
194    #[cfg(feature = "send")]
195    static_assertions::assert_impl_all!(ValueRef: Send, Sync);
196}