use std::io::BufWriter; use bpaf::Bpaf; use mimalloc::MiMalloc; use prologger::{ColorMode, ProLogger, RotationConfig}; use tortuise::{ buffer::{Buffer, Event}, file::{FileManager, TomlGameManifest, normalize_game_manifest}, input::InputManager, scene::switch_scenes, script::{ScriptContext, ScriptManager, WasmRunner}, storage::StorageManager, time::TimeContext, }; // #[global_allocator] // static GLOBAL: MiMalloc = MiMalloc; #[derive(Debug, Clone, Bpaf)] #[bpaf(options)] enum Options { #[bpaf(command)] Run, #[bpaf(command)] Compile, } fn main() { let options = options().run(); match options { Options::Compile => { let manifest = std::fs::read("tortuise.toml").unwrap(); let manifest = toml::from_slice::(&manifest).unwrap(); let manifest = normalize_game_manifest(manifest).unwrap(); let manifest_decl = format!( r#"let manifest = GameManifest {{ name: "{}".to_string(), first_scene: {}, scenes: Box::from([{}]), scripts: Box::from([]), }}"#, manifest.name, manifest.first_scene, manifest .scenes .iter() .map(|scene| format!( r#"Scene {{ name: \"{}\".to_string(), preload_scenes: Box::from([{}]), scripts: ResourceRequirements {{ required: Box::from([{}]), preload: Box::from([{}]), }} }}"#, scene.name, scene .preload_scenes .iter() .map(|i| i.to_string()) .collect::>() .join(","), scene .scripts .required .iter() .map(|i| i.to_string()) .collect::>() .join(","), scene .scripts .preload .iter() .map(|i| i.to_string()) .collect::>() .join(","), )) .collect::>() .join(",") ); } Options::Run => { ProLogger::builder() .with_rotating_file(".log", RotationConfig::new(100_000, 2)) .with_color(ColorMode::Never) .init() .unwrap(); let mut files = FileManager::default(); let wasm_runner = WasmRunner::new(); let manifest = files .load_file(Box::from("tortuise.toml".as_ref()), &wasm_runner) .unwrap() .unwrap_manifest() .clone(); let stdout = Box::new(BufWriter::new(std::io::stdout().lock())); let mut buffer = Buffer::new(stdout).unwrap(); let mut input = InputManager::new(); let mut time = TimeContext::new(); let mut storage = StorageManager::load(etcetera::AppStrategyArgs { top_level_domain: "com".into(), author: "botahamec".into(), app_name: manifest.name.to_string(), }) .unwrap(); let mut scripts = ScriptManager::new(&manifest.scripts); let mut context = ScriptContext { manifest: &manifest, buffer: &mut buffer, storage: &mut storage, input: &input, time: &time, operation_queue: Vec::new(), }; switch_scenes( &mut scripts, &mut context, &mut files, &wasm_runner, manifest.first_scene, ); let server_addr = format!("127.0.0.1:{}", puffin_http::DEFAULT_PORT); let _puffin_server = puffin_http::Server::new(&server_addr).unwrap(); puffin::set_scopes_on(true); buffer .render_loop(|buffer, event| match event { Event::Key(event) => { if event.is_press() { input.press_key(event.code); } } Event::Render => { buffer.cells.clear(); let mut context = ScriptContext { manifest: &manifest, buffer, storage: &mut storage, input: &input, time: &time, operation_queue: Vec::new(), }; scripts.run_scripts(&mut context, &wasm_runner, &mut files); input.reset_next_frame(); time.next_frame(); } }) .unwrap(); } } }