New apis and clippy fixes
This commit is contained in:
parent
64ade67496
commit
85c1d6a82a
|
@ -109,7 +109,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gmod"
|
||||
version = "15.0.2"
|
||||
version = "16.0.0"
|
||||
dependencies = [
|
||||
"cfg_table",
|
||||
"cstr",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "gmod"
|
||||
version = "15.0.2"
|
||||
version = "16.0.0"
|
||||
authors = ["William Venner <william@venner.io>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
//! [Available Lua Functions](https://docs.rs/gmod/latest/gmod/lua/struct.State.html)
|
||||
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![allow(clippy::result_unit_err)]
|
||||
|
||||
#![feature(c_unwind)]
|
||||
#![feature(thread_id_value)]
|
||||
|
||||
|
@ -255,11 +258,11 @@ pub struct OpenGmodLibraryErrs(pub std::collections::HashMap<&'static str, liblo
|
|||
impl std::error::Error for OpenGmodLibraryErrs {}
|
||||
impl std::fmt::Display for OpenGmodLibraryErrs {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "")?;
|
||||
writeln!(f)?;
|
||||
for (path, err) in &self.0 {
|
||||
writeln!(f, "{} = {}", path, err)?;
|
||||
}
|
||||
writeln!(f, "")?;
|
||||
writeln!(f)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ impl std::ops::DerefMut for LuaSharedInterface {
|
|||
pub static mut LUA_SHARED: LuaSharedInterface = LuaSharedInterface(UnsafeCell::new(std::ptr::null_mut()), #[cfg(debug_assertions)] AtomicI64::new(-1));
|
||||
|
||||
pub struct LuaShared {
|
||||
pub(crate) library: &'static libloading::Library,
|
||||
pub lual_newstate: Symbol<'static, unsafe extern "C-unwind" fn() -> LuaState>,
|
||||
pub lual_openlibs: Symbol<'static, unsafe extern "C-unwind" fn(state: LuaState)>,
|
||||
pub lual_loadfile: Symbol<'static, unsafe extern "C-unwind" fn(state: LuaState, path: LuaString) -> i32>,
|
||||
|
@ -180,7 +181,7 @@ impl LuaShared {
|
|||
fn import() -> Self {
|
||||
unsafe {
|
||||
let (library, path) = Self::find_lua_shared();
|
||||
let library = Box::leak(Box::new(library)); // Keep this library referenced forever
|
||||
let library = Box::leak(Box::new(library));
|
||||
|
||||
macro_rules! find_symbol {
|
||||
( $symbol:literal ) => {
|
||||
|
@ -249,6 +250,7 @@ impl LuaShared {
|
|||
lua_status: find_symbol!("lua_status"),
|
||||
lua_xmove: find_symbol!("lua_xmove"),
|
||||
lua_equal: find_symbol!("lua_equal"),
|
||||
library,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use std::{mem::MaybeUninit, borrow::Cow, ffi::c_void};
|
||||
|
||||
use crate::lua::*;
|
||||
|
||||
use crate::userdata::TaggedUserData;
|
||||
use crate::{userdata::TaggedUserData, lua::*};
|
||||
|
||||
unsafe fn handle_pcall_ignore(lua: State) {
|
||||
crate::lua_stack_guard!(lua => {
|
||||
|
@ -219,7 +216,7 @@ impl LuaState {
|
|||
handle_pcall_ignore(*self);
|
||||
false
|
||||
}
|
||||
err @ _ => {
|
||||
err => {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!("[gmod-rs] pcall_ignore unknown error: {}", err);
|
||||
false
|
||||
|
@ -316,11 +313,52 @@ impl LuaState {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// Creates a closure, which can be used as a function with stored data (upvalues)
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// #[lua_function]
|
||||
/// unsafe fn foo(lua: gmod::lua::State) {
|
||||
/// lua.get_closure_arg(1);
|
||||
/// let hello = lua.get_string(-1);
|
||||
/// println!("{}", hello);
|
||||
/// }
|
||||
///
|
||||
/// lua.push_string("Hello, world!");
|
||||
/// lua.push_closure(foo, 1);
|
||||
/// ```
|
||||
pub unsafe fn push_closure(&self, func: LuaFunction, n: i32) {
|
||||
debug_assert!(n <= 255, "Can't push more than 255 arguments into a closure");
|
||||
(LUA_SHARED.lua_pushcclosure)(*self, func, n)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// Pushes the `n`th closure argument onto the stack
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// #[lua_function]
|
||||
/// unsafe fn foo(lua: gmod::lua::State) {
|
||||
/// lua.push_closure_arg(1);
|
||||
/// let hello = lua.get_string(-1);
|
||||
/// println!("{}", hello);
|
||||
/// }
|
||||
///
|
||||
/// lua.push_string("Hello, world!");
|
||||
/// lua.push_closure(foo, 1);
|
||||
/// ```
|
||||
pub unsafe fn push_closure_arg(&self, n: i32) {
|
||||
self.push_value(self.upvalue_index(n));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// Equivalent to C `lua_upvalueindex` macro
|
||||
pub const fn upvalue_index(&self, idx: i32) -> i32 {
|
||||
LUA_GLOBALSINDEX - idx
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn set_table(&self, index: i32) {
|
||||
(LUA_SHARED.lua_settable)(*self, index)
|
||||
|
@ -393,14 +431,12 @@ impl LuaState {
|
|||
}
|
||||
|
||||
pub unsafe fn test_userdata(&self, index: i32, name: LuaString) -> bool {
|
||||
if !(LUA_SHARED.lua_touserdata)(*self, index).is_null() {
|
||||
if self.get_metatable(index) != 0 {
|
||||
self.get_field(LUA_REGISTRYINDEX, name);
|
||||
let result = self.raw_equal(-1, -2);
|
||||
self.pop_n(2);
|
||||
if result {
|
||||
return true;
|
||||
}
|
||||
if !(LUA_SHARED.lua_touserdata)(*self, index).is_null() && self.get_metatable(index) != 0 {
|
||||
self.get_field(LUA_REGISTRYINDEX, name);
|
||||
let result = self.raw_equal(-1, -2);
|
||||
self.pop_n(2);
|
||||
if result {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
|
@ -463,6 +499,7 @@ impl LuaState {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(clippy::len_without_is_empty)]
|
||||
pub unsafe fn len(&self, index: i32) -> i32 {
|
||||
(LUA_SHARED.lua_objlen)(*self, index)
|
||||
}
|
||||
|
@ -527,7 +564,7 @@ impl LuaState {
|
|||
pub unsafe fn coroutine_resume_call(&self, narg: i32) {
|
||||
match (LUA_SHARED.lua_resume)(*self, narg) {
|
||||
LUA_OK => {},
|
||||
LUA_ERRRUN => self.error(self.get_string(-2).unwrap_or_else(|| Cow::Borrowed("Unknown error")).as_ref()),
|
||||
LUA_ERRRUN => self.error(self.get_string(-2).unwrap_or(Cow::Borrowed("Unknown error")).as_ref()),
|
||||
LUA_ERRMEM => self.error("Out of memory"),
|
||||
_ => self.error("Unknown internal Lua error")
|
||||
}
|
||||
|
@ -542,7 +579,7 @@ impl LuaState {
|
|||
handle_pcall_ignore(*self);
|
||||
Err(())
|
||||
},
|
||||
err @ _ => {
|
||||
err => {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!("[gmod-rs] coroutine_resume_pcall_ignore unknown error: {}", err);
|
||||
Err(())
|
||||
|
@ -631,10 +668,8 @@ impl LuaState {
|
|||
|
||||
pub unsafe fn debug_getinfo_at(&self, level: i32, what: LuaString) -> Option<LuaDebug> {
|
||||
let mut ar = MaybeUninit::uninit();
|
||||
if (LUA_SHARED.lua_getstack)(*self, level, ar.as_mut_ptr()) != 0 {
|
||||
if (LUA_SHARED.lua_getinfo)(*self, what, ar.as_mut_ptr()) != 0 {
|
||||
return Some(ar.assume_init());
|
||||
}
|
||||
if (LUA_SHARED.lua_getstack)(*self, level, ar.as_mut_ptr()) != 0 && (LUA_SHARED.lua_getinfo)(*self, what, ar.as_mut_ptr()) != 0 {
|
||||
return Some(ar.assume_init());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ pub use push::*;
|
|||
mod returns;
|
||||
pub use returns::ValuesReturned;
|
||||
|
||||
mod raw_bind;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LuaError {
|
||||
/// Out of memory
|
||||
|
@ -63,13 +65,13 @@ macro_rules! lua_string {
|
|||
///
|
||||
/// ```rust,norun
|
||||
/// lua_stack_guard!(lua => {
|
||||
/// lua.get_global(lua_string!("hook"));
|
||||
/// lua.get_field(-1, lua_string!("Add"));
|
||||
/// lua.push_string("PlayerInitialSpawn");
|
||||
/// lua.push_string("RustHook");
|
||||
/// lua.push_function(player_initial_spawn);
|
||||
/// lua.call(3, 0);
|
||||
/// // lua.pop();
|
||||
/// lua.get_global(lua_string!("hook"));
|
||||
/// lua.get_field(-1, lua_string!("Add"));
|
||||
/// lua.push_string("PlayerInitialSpawn");
|
||||
/// lua.push_string("RustHook");
|
||||
/// lua.push_function(player_initial_spawn);
|
||||
/// lua.call(3, 0);
|
||||
/// // lua.pop();
|
||||
/// });
|
||||
/// // PANIC: stack is dirty! We forgot to pop the hook library off the stack.
|
||||
/// ```
|
||||
|
@ -78,7 +80,7 @@ macro_rules! lua_stack_guard {
|
|||
( $lua:ident => $code:block ) => {{
|
||||
#[cfg(debug_assertions)] {
|
||||
let top = $lua.get_top();
|
||||
let ret = (|| $code)();
|
||||
let ret = $code;
|
||||
if top != $lua.get_top() {
|
||||
$lua.dump_stack();
|
||||
panic!("Stack is dirty! Expected the stack to have {} elements, but it has {}!", top, $lua.get_top());
|
||||
|
|
|
@ -98,7 +98,7 @@ impl PushToLua for Vec<u8> {
|
|||
impl PushToLua for &[u8] {
|
||||
#[inline]
|
||||
unsafe fn push_to_lua(self, lua: crate::lua::State) {
|
||||
lua.push_binary_string(&self);
|
||||
lua.push_binary_string(self);
|
||||
}
|
||||
}
|
||||
impl PushToLua for Duration {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
use crate::lua::*;
|
||||
|
||||
pub trait CLuaFunction: Copy {}
|
||||
|
||||
macro_rules! impl_c_lua_function {
|
||||
($($($arg:ident) *;)*) => {
|
||||
$(
|
||||
impl<$($arg, )* R> CLuaFunction for extern "C-unwind" fn($($arg),*) -> R {}
|
||||
impl<$($arg, )* R> CLuaFunction for unsafe extern "C-unwind" fn($($arg),*) -> R {}
|
||||
impl<$($arg, )* R> CLuaFunction for extern "C" fn($($arg),*) -> R {}
|
||||
impl<$($arg, )* R> CLuaFunction for unsafe extern "C" fn($($arg),*) -> R {}
|
||||
)*
|
||||
};
|
||||
}
|
||||
impl_c_lua_function!(
|
||||
;
|
||||
T1;
|
||||
T1 T2;
|
||||
T1 T2 T3;
|
||||
T1 T2 T3 T4;
|
||||
T1 T2 T3 T4 T5;
|
||||
T1 T2 T3 T4 T5 T6;
|
||||
T1 T2 T3 T4 T5 T6 T7;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15;
|
||||
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16;
|
||||
);
|
||||
|
||||
impl State {
|
||||
#[inline(always)]
|
||||
/// Binds to a raw Lua C function.
|
||||
///
|
||||
/// If anything is missing from this library, you can use this function to bind it yourself.
|
||||
///
|
||||
/// Note, this may be a somewhat expensive operation, so storing its result in some way is recommended.
|
||||
pub unsafe fn raw_bind<F: CLuaFunction>(&self, symbol: &[u8]) -> Result<F, libloading::Error> {
|
||||
LUA_SHARED.library.get::<F>(symbol).map(|f| *f)
|
||||
}
|
||||
}
|
|
@ -3,10 +3,10 @@ use std::{num::NonZeroI32, borrow::Cow};
|
|||
#[repr(transparent)]
|
||||
pub struct ValuesReturned(pub i32);
|
||||
|
||||
impl Into<i32> for ValuesReturned {
|
||||
impl From<ValuesReturned> for i32 {
|
||||
#[inline(always)]
|
||||
fn into(self) -> i32 {
|
||||
self.0
|
||||
fn from(v: ValuesReturned) -> Self {
|
||||
v.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,11 @@ impl From<Option<NonZeroI32>> for ValuesReturned {
|
|||
}
|
||||
|
||||
pub trait DisplayLuaError {
|
||||
fn display_lua_error<'a>(&'a self) -> Cow<'a, str>;
|
||||
fn display_lua_error(&self) -> Cow<'_, str>;
|
||||
}
|
||||
impl<E: std::fmt::Debug> DisplayLuaError for E {
|
||||
#[inline(always)]
|
||||
fn display_lua_error<'a>(&'a self) -> Cow<'a, str> {
|
||||
fn display_lua_error(&self) -> Cow<'_, str> {
|
||||
Cow::Owned(format!("{:?}", self))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ macro_rules! userdata {
|
|||
/// 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 {
|
||||
pub unsafe fn coerce_unchecked<'a, 'b, T: CoercibleUserData>(&'a self) -> &'b mut T {
|
||||
&mut *(self.data as *mut T)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue