flake-engine 0.1.1

Immediate-mode game framework built on wgpu + winit
use crate::state::State;
use std::cell::{Cell, RefCell};
use std::ptr::NonNull;
use winit::window::WindowLevel;
use crate::misc::font::Font;
use crate::misc::timer::Timer;
use crate::prelude::Color;

#[derive(Default, Clone)]
pub struct PendingConfig {
    pub window_title: Option<String>,
    pub window_x: Option<i32>,
    pub window_y: Option<i32>,
    pub window_width: Option<u32>,
    pub window_height: Option<u32>,
    pub window_visible: Option<bool>,
    pub window_transparent: Option<bool>,
    pub window_decorations: Option<bool>,
    pub window_passthrough: Option<bool>,
    pub window_level: Option<WindowLevel>,
    pub window_icon: Option<(Vec<u8>, u32, u32)>,
    pub window_clear_color: Option<Color>,
    pub skip_taskbar: Option<bool>,

    pub fps_capped: Option<bool>,
    pub target_fps: Option<usize>,
    
    pub fonts: Vec<Font>,
    pub timers: Vec<Timer>
}

thread_local! {
    pub static STATE: Cell<Option<NonNull<State>>> = const { Cell::new(None) };
    pub static PENDING_CONFIG: RefCell<PendingConfig> = RefCell::new(PendingConfig::default());
}

#[allow(unused)]
fn with_global<R>(state: &mut State, f: impl FnOnce() -> R) -> R {
    STATE.set(Some(NonNull::from(&mut *state)));
    let r = f();
    STATE.set(None);
    r
}

#[inline(always)]
pub(crate) fn ctx<R>(f: impl FnOnce(&mut State) -> R) -> R {
    STATE.with(|s| {
        let mut p = s
            .get()
            .expect("no active context (call only inside the run/update fn)");
        f(unsafe { p.as_mut() })
    })
}