use sdk_raw::test_support::edicts::mock_edict;
use std::cell::{Cell, RefCell};
use std::ffi::c_int;
use std::ptr::null_mut;
thread_local! {
static ACCESSOR: Cell<*mut sys::IChangeInfoAccessor> = const { Cell::new(null_mut()) };
static EDICTS: Cell<(*mut sys::edict_t, usize)> = const { Cell::new((null_mut(), 0)) };
static FLAG_CHANGES: RefCell<Vec<c_int>> = const { RefCell::new(Vec::new()) };
static SHARED: Cell<*mut sys::CSharedEdictChangeInfo> = const { Cell::new(null_mut()) };
}
pub unsafe extern "C" fn change_accessor(
_: *mut sys::IVEngineServer,
_: *const sys::edict_t,
) -> *mut sys::IChangeInfoAccessor {
ACCESSOR.get()
}
pub unsafe extern "C" fn edict_of_index(
_: *mut sys::IVEngineServer,
index: c_int,
) -> *mut sys::edict_t {
let (table, len) = EDICTS.get();
match usize::try_from(index) {
Ok(slot) if slot < len => unsafe { table.add(slot) },
_ => null_mut(),
}
}
pub fn edict_table(len: usize, free: impl Fn(usize) -> bool) -> Box<[sys::edict_t]> {
(0..len)
.map(|slot| mock_edict(c_int::try_from(slot).unwrap(), free(slot)))
.collect()
}
pub unsafe extern "C" fn notify_edict_flags_change(_: *mut sys::IVEngineServer, edict: c_int) {
FLAG_CHANGES.with_borrow_mut(|changes| changes.push(edict));
}
pub fn serve_edicts(table: *mut sys::edict_t, len: usize) {
EDICTS.set((table, len));
}
pub fn set_change_accessor(accessor: *mut sys::IChangeInfoAccessor) {
ACCESSOR.set(accessor);
}
pub fn set_shared_change_info(shared: *mut sys::CSharedEdictChangeInfo) {
SHARED.set(shared);
}
pub unsafe extern "C" fn shared_change_info(
_: *mut sys::IVEngineServer,
) -> *mut sys::CSharedEdictChangeInfo {
SHARED.get()
}
pub fn take_flag_changes() -> Vec<c_int> {
FLAG_CHANGES.take()
}