#![allow(unused)]
#[macro_export]
macro_rules! cstr {
($rstring:literal) => {
concat!($rstring, "\0").as_ptr() as *const i8
};
($rstring:expr) => {
std::ffi::CString::new($rstring).expect("Couldn't make CString from rust string")
};
}
#[macro_export]
macro_rules! try_cstr {
($rstring:literal) => {
concat!($rstring, "\0").as_ptr() as *const i8
};
($rstring:expr) => {{
std::ffi::CString::new($rstring)
}};
}
#[macro_export]
macro_rules! rstr {
($cstring:expr) => {{
#[allow(unused_unsafe)]
let cstr = unsafe { std::ffi::CStr::from_ptr($cstring) };
cstr.to_str().expect("Couldn't unwrap CString")
}};
}
#[macro_export]
macro_rules! try_rstr {
($cstring:expr) => {{
#[allow(unused_unsafe)]
let cstr = unsafe { std::ffi::CStr::from_ptr($cstring) };
cstr.to_str()
}};
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! printgm {
($state:expr, $($x:expr),*) => {
{
let printargs = format!( $($x,)* );
if let Ok(fmt) = std::ffi::CString::new(printargs) {
$crate::lua::lua_getglobal( $state, $crate::cstr!("print") );
$crate::lua::lua_pushstring( $state, fmt.as_ptr() );
$crate::lua::lua_call( $state, 1, 0 );
}
}
};
}
#[macro_export]
macro_rules! reg {
( $( $name:expr => $func:expr ),* ) => {
&[ $( $crate::types::LuaReg { name: $crate::cstr!($name), func: Some($func) } ),*, $crate::types::LuaReg { name: std::ptr::null(), func: None } ]
};
}
#[cfg(feature = "interfaces")]
fn get_from_interface(
iface: &str,
factory: crate::interface::CreateInterfaceFn
) -> Result<*mut (), crate::interface::Error> {
let mut status = 0;
let iface = try_cstr!(iface)?;
let result = factory(iface.as_ptr(), &mut status);
if status == 0 && !result.is_null() {
Ok(result as *mut ())
} else {
Err(crate::interface::Error::FactoryNotFound(
iface.to_string_lossy().to_string()
))
}
}
#[macro_export]
macro_rules! iface {
( LuaShared ) => {
iface!("lua_shared", "LUASHARED003", $crate::interface::LuaShared)
};
( EngineClient ) => {
iface!(
"engine",
"VEngineClient015",
$crate::interface::EngineClient
)
};
( EngineServer ) => {
iface!(
"engine",
"VEngineServer021",
$crate::interface::EngineServer
)
};
( MdlCache ) => {
iface!("datacache", "MDLCache004", $crate::interface::MdlCache)
};
( MaterialSystem ) => {
iface!(
"materialsystem",
"VMaterialSystem080",
$crate::interface::MaterialSystem
)
};
( Panel ) => {
iface!("vgui2", "VGUI_Panel009", $crate::interface::Panel)
};
( ConVar ) => {
iface!("vstdlib", "VEngineCvar007", $crate::interface::ConVar)
};
( $name:literal, $iface:literal, $ty:ty ) => {{
match unsafe { $crate::interface::get_interface_handle($name) } {
Ok(handle) => {
let mut status = 0;
let result = handle(cstr!($iface), &mut status);
if status == 0 && !result.is_null() {
let ptr = result as *mut $ty;
unsafe { ptr.as_mut() }
.ok_or($crate::interface::Error::IFaceMut(String::from($iface)))
} else {
Err($crate::interface::Error::CreateInterface(
status,
String::from($iface),
))
}
}
Err(why) => Err($crate::interface::Error::Libloading(why)),
}
}};
}
use crate::types::LuaState;
pub fn dump_stack(l: LuaState) -> Result<String, std::fmt::Error> {
use std::fmt::Write;
use crate::lua::*;
let mut buf = String::new();
let top = lua_gettop(l);
for i in 1..=top {
write!(&mut buf, "[{}] '{}' = ", i, rstr!(luaL_typename(l, i)));
match lua_type(l, i) {
TNUMBER => write!(&mut buf, "{}", lua_tonumber(l, i)),
TSTRING => write!(&mut buf, "{}", rstr!(lua_tostring(l, i))),
TBOOLEAN => write!(
&mut buf,
"{}",
if lua_toboolean(l, i) == 1 {
"true"
} else {
"false"
}
),
TNIL => write!(&mut buf, "nil"),
TNONE => write!(&mut buf, "none"),
TUSERDATA | TLIGHTUSERDATA => write!(&mut buf, "{:p}", lua_touserdata(l, i)),
TTHREAD => write!(&mut buf, "{:p}", lua_tothread(l, i)),
_ => write!(&mut buf, "Unknown type")
}?
}
Ok(buf)
}