New apis and clippy fixes
This commit is contained in:
parent
64ade67496
commit
85c1d6a82a
|
@ -109,7 +109,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gmod"
|
name = "gmod"
|
||||||
version = "15.0.2"
|
version = "16.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg_table",
|
"cfg_table",
|
||||||
"cstr",
|
"cstr",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "gmod"
|
name = "gmod"
|
||||||
version = "15.0.2"
|
version = "16.0.0"
|
||||||
authors = ["William Venner <william@venner.io>"]
|
authors = ["William Venner <william@venner.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
//! [Available Lua Functions](https://docs.rs/gmod/latest/gmod/lua/struct.State.html)
|
//! [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(c_unwind)]
|
||||||
#![feature(thread_id_value)]
|
#![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::error::Error for OpenGmodLibraryErrs {}
|
||||||
impl std::fmt::Display for OpenGmodLibraryErrs {
|
impl std::fmt::Display for OpenGmodLibraryErrs {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
writeln!(f, "")?;
|
writeln!(f)?;
|
||||||
for (path, err) in &self.0 {
|
for (path, err) in &self.0 {
|
||||||
writeln!(f, "{} = {}", path, err)?;
|
writeln!(f, "{} = {}", path, err)?;
|
||||||
}
|
}
|
||||||
writeln!(f, "")?;
|
writeln!(f)?;
|
||||||
Ok(())
|
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 static mut LUA_SHARED: LuaSharedInterface = LuaSharedInterface(UnsafeCell::new(std::ptr::null_mut()), #[cfg(debug_assertions)] AtomicI64::new(-1));
|
||||||
|
|
||||||
pub struct LuaShared {
|
pub struct LuaShared {
|
||||||
|
pub(crate) library: &'static libloading::Library,
|
||||||
pub lual_newstate: Symbol<'static, unsafe extern "C-unwind" fn() -> LuaState>,
|
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_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>,
|
pub lual_loadfile: Symbol<'static, unsafe extern "C-unwind" fn(state: LuaState, path: LuaString) -> i32>,
|
||||||
|
@ -180,7 +181,7 @@ impl LuaShared {
|
||||||
fn import() -> Self {
|
fn import() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let (library, path) = Self::find_lua_shared();
|
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 {
|
macro_rules! find_symbol {
|
||||||
( $symbol:literal ) => {
|
( $symbol:literal ) => {
|
||||||
|
@ -249,6 +250,7 @@ impl LuaShared {
|
||||||
lua_status: find_symbol!("lua_status"),
|
lua_status: find_symbol!("lua_status"),
|
||||||
lua_xmove: find_symbol!("lua_xmove"),
|
lua_xmove: find_symbol!("lua_xmove"),
|
||||||
lua_equal: find_symbol!("lua_equal"),
|
lua_equal: find_symbol!("lua_equal"),
|
||||||
|
library,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use std::{mem::MaybeUninit, borrow::Cow, ffi::c_void};
|
use std::{mem::MaybeUninit, borrow::Cow, ffi::c_void};
|
||||||
|
use crate::{userdata::TaggedUserData, lua::*};
|
||||||
use crate::lua::*;
|
|
||||||
|
|
||||||
use crate::userdata::TaggedUserData;
|
|
||||||
|
|
||||||
unsafe fn handle_pcall_ignore(lua: State) {
|
unsafe fn handle_pcall_ignore(lua: State) {
|
||||||
crate::lua_stack_guard!(lua => {
|
crate::lua_stack_guard!(lua => {
|
||||||
|
@ -219,7 +216,7 @@ impl LuaState {
|
||||||
handle_pcall_ignore(*self);
|
handle_pcall_ignore(*self);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
err @ _ => {
|
err => {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
eprintln!("[gmod-rs] pcall_ignore unknown error: {}", err);
|
eprintln!("[gmod-rs] pcall_ignore unknown error: {}", err);
|
||||||
false
|
false
|
||||||
|
@ -316,11 +313,52 @@ impl LuaState {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[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) {
|
pub unsafe fn push_closure(&self, func: LuaFunction, n: i32) {
|
||||||
debug_assert!(n <= 255, "Can't push more than 255 arguments into a closure");
|
debug_assert!(n <= 255, "Can't push more than 255 arguments into a closure");
|
||||||
(LUA_SHARED.lua_pushcclosure)(*self, func, n)
|
(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)]
|
#[inline(always)]
|
||||||
pub unsafe fn set_table(&self, index: i32) {
|
pub unsafe fn set_table(&self, index: i32) {
|
||||||
(LUA_SHARED.lua_settable)(*self, index)
|
(LUA_SHARED.lua_settable)(*self, index)
|
||||||
|
@ -393,14 +431,12 @@ impl LuaState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn test_userdata(&self, index: i32, name: LuaString) -> bool {
|
pub unsafe fn test_userdata(&self, index: i32, name: LuaString) -> bool {
|
||||||
if !(LUA_SHARED.lua_touserdata)(*self, index).is_null() {
|
if !(LUA_SHARED.lua_touserdata)(*self, index).is_null() && self.get_metatable(index) != 0 {
|
||||||
if self.get_metatable(index) != 0 {
|
self.get_field(LUA_REGISTRYINDEX, name);
|
||||||
self.get_field(LUA_REGISTRYINDEX, name);
|
let result = self.raw_equal(-1, -2);
|
||||||
let result = self.raw_equal(-1, -2);
|
self.pop_n(2);
|
||||||
self.pop_n(2);
|
if result {
|
||||||
if result {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -463,6 +499,7 @@ impl LuaState {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[allow(clippy::len_without_is_empty)]
|
||||||
pub unsafe fn len(&self, index: i32) -> i32 {
|
pub unsafe fn len(&self, index: i32) -> i32 {
|
||||||
(LUA_SHARED.lua_objlen)(*self, index)
|
(LUA_SHARED.lua_objlen)(*self, index)
|
||||||
}
|
}
|
||||||
|
@ -527,7 +564,7 @@ impl LuaState {
|
||||||
pub unsafe fn coroutine_resume_call(&self, narg: i32) {
|
pub unsafe fn coroutine_resume_call(&self, narg: i32) {
|
||||||
match (LUA_SHARED.lua_resume)(*self, narg) {
|
match (LUA_SHARED.lua_resume)(*self, narg) {
|
||||||
LUA_OK => {},
|
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"),
|
LUA_ERRMEM => self.error("Out of memory"),
|
||||||
_ => self.error("Unknown internal Lua error")
|
_ => self.error("Unknown internal Lua error")
|
||||||
}
|
}
|
||||||
|
@ -542,7 +579,7 @@ impl LuaState {
|
||||||
handle_pcall_ignore(*self);
|
handle_pcall_ignore(*self);
|
||||||
Err(())
|
Err(())
|
||||||
},
|
},
|
||||||
err @ _ => {
|
err => {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
eprintln!("[gmod-rs] coroutine_resume_pcall_ignore unknown error: {}", err);
|
eprintln!("[gmod-rs] coroutine_resume_pcall_ignore unknown error: {}", err);
|
||||||
Err(())
|
Err(())
|
||||||
|
@ -631,10 +668,8 @@ impl LuaState {
|
||||||
|
|
||||||
pub unsafe fn debug_getinfo_at(&self, level: i32, what: LuaString) -> Option<LuaDebug> {
|
pub unsafe fn debug_getinfo_at(&self, level: i32, what: LuaString) -> Option<LuaDebug> {
|
||||||
let mut ar = MaybeUninit::uninit();
|
let mut ar = MaybeUninit::uninit();
|
||||||
if (LUA_SHARED.lua_getstack)(*self, level, ar.as_mut_ptr()) != 0 {
|
if (LUA_SHARED.lua_getstack)(*self, level, ar.as_mut_ptr()) != 0 && (LUA_SHARED.lua_getinfo)(*self, what, ar.as_mut_ptr()) != 0 {
|
||||||
if (LUA_SHARED.lua_getinfo)(*self, what, ar.as_mut_ptr()) != 0 {
|
return Some(ar.assume_init());
|
||||||
return Some(ar.assume_init());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ pub use push::*;
|
||||||
mod returns;
|
mod returns;
|
||||||
pub use returns::ValuesReturned;
|
pub use returns::ValuesReturned;
|
||||||
|
|
||||||
|
mod raw_bind;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum LuaError {
|
pub enum LuaError {
|
||||||
/// Out of memory
|
/// Out of memory
|
||||||
|
@ -63,13 +65,13 @@ macro_rules! lua_string {
|
||||||
///
|
///
|
||||||
/// ```rust,norun
|
/// ```rust,norun
|
||||||
/// lua_stack_guard!(lua => {
|
/// lua_stack_guard!(lua => {
|
||||||
/// lua.get_global(lua_string!("hook"));
|
/// lua.get_global(lua_string!("hook"));
|
||||||
/// lua.get_field(-1, lua_string!("Add"));
|
/// lua.get_field(-1, lua_string!("Add"));
|
||||||
/// lua.push_string("PlayerInitialSpawn");
|
/// lua.push_string("PlayerInitialSpawn");
|
||||||
/// lua.push_string("RustHook");
|
/// lua.push_string("RustHook");
|
||||||
/// lua.push_function(player_initial_spawn);
|
/// lua.push_function(player_initial_spawn);
|
||||||
/// lua.call(3, 0);
|
/// lua.call(3, 0);
|
||||||
/// // lua.pop();
|
/// // lua.pop();
|
||||||
/// });
|
/// });
|
||||||
/// // PANIC: stack is dirty! We forgot to pop the hook library off the stack.
|
/// // 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 ) => {{
|
( $lua:ident => $code:block ) => {{
|
||||||
#[cfg(debug_assertions)] {
|
#[cfg(debug_assertions)] {
|
||||||
let top = $lua.get_top();
|
let top = $lua.get_top();
|
||||||
let ret = (|| $code)();
|
let ret = $code;
|
||||||
if top != $lua.get_top() {
|
if top != $lua.get_top() {
|
||||||
$lua.dump_stack();
|
$lua.dump_stack();
|
||||||
panic!("Stack is dirty! Expected the stack to have {} elements, but it has {}!", top, $lua.get_top());
|
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] {
|
impl PushToLua for &[u8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn push_to_lua(self, lua: crate::lua::State) {
|
unsafe fn push_to_lua(self, lua: crate::lua::State) {
|
||||||
lua.push_binary_string(&self);
|
lua.push_binary_string(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl PushToLua for Duration {
|
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)]
|
#[repr(transparent)]
|
||||||
pub struct ValuesReturned(pub i32);
|
pub struct ValuesReturned(pub i32);
|
||||||
|
|
||||||
impl Into<i32> for ValuesReturned {
|
impl From<ValuesReturned> for i32 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn into(self) -> i32 {
|
fn from(v: ValuesReturned) -> Self {
|
||||||
self.0
|
v.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +45,11 @@ impl From<Option<NonZeroI32>> for ValuesReturned {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DisplayLuaError {
|
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 {
|
impl<E: std::fmt::Debug> DisplayLuaError for E {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn display_lua_error<'a>(&'a self) -> Cow<'a, str> {
|
fn display_lua_error(&self) -> Cow<'_, str> {
|
||||||
Cow::Owned(format!("{:?}", self))
|
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.
|
/// 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.
|
/// 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)
|
&mut *(self.data as *mut T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue