use crate::error::Result;
use crate::state::Lua;
use crate::sys::*;
#[derive(Debug, Clone, Copy, Default)]
pub struct GcIncParams {
pub(crate) goal: Option<core::ffi::c_int>,
pub(crate) step_multiplier: Option<core::ffi::c_int>,
pub(crate) step_size: Option<core::ffi::c_int>,
}
impl GcIncParams {
pub fn goal(mut self, goal: u32) -> Self {
self.goal = Some(goal as core::ffi::c_int);
self
}
pub fn step_multiplier(mut self, mul: u32) -> Self {
self.step_multiplier = Some(mul as core::ffi::c_int);
self
}
pub fn step_size(mut self, size: u32) -> Self {
self.step_size = Some(size as core::ffi::c_int);
self
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct GcGenParams {
pub minor_multiplier: u32,
pub major_multiplier: u32,
}
#[derive(Debug, Clone, Copy)]
pub enum GcMode {
Incremental(GcIncParams),
Generational(GcGenParams),
}
impl Lua {
pub fn used_memory(&self) -> usize {
unsafe {
let g = (*self.state()).global;
(*g).totalbytes
}
}
pub fn gc_is_running(&self) -> bool {
lua_gc(self.state(), lua_GCOp::LUA_GCISRUNNING as c_int, 0) != 0
}
pub fn gc_stop(&self) {
lua_gc(self.state(), lua_GCOp::LUA_GCSTOP as c_int, 0);
}
pub fn gc_restart(&self) {
lua_gc(self.state(), lua_GCOp::LUA_GCRESTART as c_int, 0);
}
pub fn gc_count(&self) -> usize {
let kb = lua_gc(self.state(), lua_GCOp::LUA_GCCOUNT as c_int, 0).max(0) as usize;
kb
}
pub fn gc_step_kbytes(&self, kbytes: c_int) -> Result<bool> {
let finished = lua_gc(self.state(), lua_GCOp::LUA_GCSTEP as c_int, kbytes) != 0;
Ok(finished)
}
pub fn gc_step(&self) -> Result<bool> {
self.gc_step_kbytes(0)
}
pub fn gc_inc(&self, pause: c_int, step_multiplier: c_int, step_size: c_int) -> GcMode {
let state = self.state();
if pause > 0 {
lua_gc(state, lua_GCOp::LUA_GCSETGOAL as c_int, pause);
}
if step_multiplier > 0 {
lua_gc(state, lua_GCOp::LUA_GCSETSTEPMUL as c_int, step_multiplier);
}
if step_size > 0 {
lua_gc(state, lua_GCOp::LUA_GCSETSTEPSIZE as c_int, step_size);
}
GcMode::Incremental(GcIncParams::default())
}
pub fn gc_set_mode(&self, mode: GcMode) -> GcMode {
let state = self.state();
match mode {
GcMode::Incremental(p) => {
if let Some(goal) = p.goal {
lua_gc(state, lua_GCOp::LUA_GCSETGOAL as c_int, goal);
}
if let Some(mul) = p.step_multiplier {
lua_gc(state, lua_GCOp::LUA_GCSETSTEPMUL as c_int, mul);
}
if let Some(sz) = p.step_size {
lua_gc(state, lua_GCOp::LUA_GCSETSTEPSIZE as c_int, sz);
}
}
GcMode::Generational(_) => {
}
}
GcMode::Incremental(GcIncParams::default())
}
}