Add better userdata api and type coercion, add Vector and Angle types
This commit is contained in:
parent
27857866c8
commit
b916d3ba19
|
@ -16,6 +16,9 @@ pub mod msgc;
|
||||||
/// Advanced dark magic utilities
|
/// Advanced dark magic utilities
|
||||||
pub mod hax;
|
pub mod hax;
|
||||||
|
|
||||||
|
/// Userdata types
|
||||||
|
pub mod userdata;
|
||||||
|
|
||||||
/// Returns whether this client is running the x86-64 branch
|
/// Returns whether this client is running the x86-64 branch
|
||||||
///
|
///
|
||||||
/// Current implementation checks the contents of the bin/ directory, so this is a blocking operation and requires syscalls, use sparingly
|
/// Current implementation checks the contents of the bin/ directory, so this is a blocking operation and requires syscalls, use sparingly
|
||||||
|
|
|
@ -2,6 +2,8 @@ use std::{mem::MaybeUninit, borrow::Cow, ffi::c_void};
|
||||||
|
|
||||||
use crate::lua::*;
|
use crate::lua::*;
|
||||||
|
|
||||||
|
use crate::userdata::UserData;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct LuaState(pub *mut std::ffi::c_void);
|
pub struct LuaState(pub *mut std::ffi::c_void);
|
||||||
|
|
|
@ -6,14 +6,6 @@ pub use import::*;
|
||||||
mod lua_state;
|
mod lua_state;
|
||||||
pub use lua_state::LuaState as State;
|
pub use lua_state::LuaState as State;
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct UserData
|
|
||||||
{
|
|
||||||
pub data: *mut core::ffi::c_void,
|
|
||||||
pub r#type: u8
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum LuaError {
|
pub enum LuaError {
|
||||||
/// Out of memory
|
/// Out of memory
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
pub enum UserData {
|
||||||
|
None = 255,
|
||||||
|
|
||||||
|
Nil = 0,
|
||||||
|
Bool,
|
||||||
|
LightUserData,
|
||||||
|
Number,
|
||||||
|
String,
|
||||||
|
Table,
|
||||||
|
Function,
|
||||||
|
UserData,
|
||||||
|
Thread,
|
||||||
|
|
||||||
|
// GMod Types
|
||||||
|
Entity,
|
||||||
|
Vector,
|
||||||
|
Angle,
|
||||||
|
PhysObj,
|
||||||
|
Save,
|
||||||
|
Restore,
|
||||||
|
DamageInfo,
|
||||||
|
EffectData,
|
||||||
|
MoveData,
|
||||||
|
RecipientFilter,
|
||||||
|
UserCmd,
|
||||||
|
ScriptedVehicle,
|
||||||
|
Material,
|
||||||
|
Panel,
|
||||||
|
Particle,
|
||||||
|
ParticleEmitter,
|
||||||
|
Texture,
|
||||||
|
UserMsg,
|
||||||
|
ConVar,
|
||||||
|
IMesh,
|
||||||
|
Matrix,
|
||||||
|
Sound,
|
||||||
|
PixelVisHandle,
|
||||||
|
DLight,
|
||||||
|
Video,
|
||||||
|
File,
|
||||||
|
Locomotion,
|
||||||
|
Path,
|
||||||
|
NavArea,
|
||||||
|
SoundHandle,
|
||||||
|
NavLadder,
|
||||||
|
ParticleSystem,
|
||||||
|
ProjectedTexture,
|
||||||
|
PhysCollide,
|
||||||
|
SurfaceInfo,
|
||||||
|
|
||||||
|
MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Vector {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
z: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Angle {
|
||||||
|
p: f32,
|
||||||
|
y: f32,
|
||||||
|
r: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
|
pub struct TaggedUserData
|
||||||
|
{
|
||||||
|
pub data: *mut core::ffi::c_void,
|
||||||
|
pub r#type: UserData
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CoercibleUserData {}
|
||||||
|
|
||||||
|
macro_rules! userdata {
|
||||||
|
($(UserData::$enum:ident => $struct:ident),+) => {
|
||||||
|
$(impl CoercibleUserData for $struct {})+
|
||||||
|
|
||||||
|
impl TaggedUserData {
|
||||||
|
/// Coerce this tagged UserData into its corresponding Rust struct, if possible.
|
||||||
|
///
|
||||||
|
/// This will perform a type check to ensure that the tagged userdata matches the user data you are coercing to.
|
||||||
|
pub fn coerce<'a, T: CoercibleUserData>(&self) -> Result<&mut T, UserData> {
|
||||||
|
match self.r#type {
|
||||||
|
$(UserData::$enum => Ok(unsafe { &mut *(self.data as *mut T) }),)+
|
||||||
|
_ => Err(self.r#type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Coerce this tagged UserData into its corresponding Rust struct, if possible.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// This will NOT perform a type check to ensure that the tagged userdata matches the user data you are coercing to.
|
||||||
|
///
|
||||||
|
/// Coercing to the wrong type is undefined behaviour and is likely to crash your program.
|
||||||
|
pub unsafe fn coerce_unchecked<T: CoercibleUserData>(&self) -> &mut T {
|
||||||
|
&mut *(self.data as *mut T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
userdata! {
|
||||||
|
UserData::Vector => Vector,
|
||||||
|
UserData::Angle => Angle
|
||||||
|
}
|
Loading…
Reference in New Issue