use crate::ffi::{NotThreadSafe, borrow_cstr, copy_cstr, vcall};
use std::ffi::{CStr, CString, c_int};
use std::marker::PhantomData;
use std::ptr::NonNull;
interface! {
#[doc(alias = "ICvar")]
pub struct Cvar(sys::ICvar) = Engine c"VEngineCvar004";
}
impl<'s> Cvar<'s> {
#[doc(alias = "FindVar")]
pub fn find_var(self, name: &CStr) -> Option<ConVar<'s>> {
let var = NonNull::new(unsafe { vcall!(self.as_ptr() => ICvar_FindVar(name.as_ptr())) })?;
Some(ConVar {
raw: var,
_scope: PhantomData,
_not_thread_safe: PhantomData,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConVar<'s> {
raw: NonNull<sys::ConVar>,
_scope: PhantomData<&'s ()>,
_not_thread_safe: NotThreadSafe,
}
impl<'s> ConVar<'s> {
pub const fn as_ptr(self) -> *mut sys::ConVar {
self.raw.as_ptr()
}
#[doc(alias = "GetName")]
pub fn name(self) -> &'s CStr {
unsafe { borrow_cstr((&raw const (*self.as_ptr())._base.m_pszName).read()) }
.unwrap_or_default()
}
#[doc(alias = "GetString")]
pub fn string(self) -> CString {
unsafe { copy_cstr((&raw const (*self.parent()).m_pszString).read()) }.unwrap_or_default()
}
#[doc(alias = "GetFloat")]
pub fn float(self) -> f32 {
unsafe { (&raw const (*self.parent()).m_fValue).read() }
}
#[doc(alias = "GetInt")]
pub fn int(self) -> c_int {
unsafe { (&raw const (*self.parent()).m_nValue).read() }
}
fn parent(self) -> *mut sys::ConVar {
let parent = unsafe { (&raw const (*self.as_ptr()).m_pParent).read() };
if parent.is_null() {
self.as_ptr()
} else {
parent
}
}
}