summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 767eff9..1418ebd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,7 +1,163 @@
pub mod buffer;
pub mod file;
pub mod input;
+pub mod manifest;
pub mod scene;
pub mod script;
pub mod storage;
pub mod time;
+
+use crate::{
+ buffer::{Buffer, Event},
+ file::FileManager,
+ input::{Direction, InputManager, Position},
+ manifest::GameManifest,
+ scene::switch_scenes,
+ script::{ScriptContext, ScriptManager, WasmRunner},
+ storage::StorageManager,
+ time::TimeContext,
+};
+use crossterm::event::MouseEventKind;
+use etcetera::AppStrategy;
+use prologger::{ColorMode, ProLogger, RotationConfig};
+use std::{
+ fs::File,
+ io::{BufRead, BufWriter},
+ path::PathBuf,
+ time::{Duration, Instant},
+};
+
+pub fn apply_patches(
+ manifest: &mut GameManifest,
+ files: &mut FileManager,
+ wasm_compiler: &WasmRunner,
+) -> std::io::Result<()> {
+ let path = etcetera::choose_app_strategy(manifest.app_strategy_args())
+ .unwrap()
+ .in_config_dir("patches");
+ let patchfile = File::open(path)?;
+
+ let mut patches = Vec::new();
+ for line in std::io::BufReader::new(patchfile).lines() {
+ let Ok(line) = line else {
+ continue;
+ };
+ patches.push(line);
+ }
+
+ for path in patches {
+ let path = PathBuf::from(path).into_boxed_path();
+ let patch = files.load_file(path.clone(), wasm_compiler);
+ let patch = patch.as_ref().as_ref().unwrap();
+ let patch = wasm_compiler.patch(patch)?;
+ manifest.apply_wasm_patch(path, patch);
+ }
+
+ Ok(())
+}
+
+pub fn init_logger(manifest: &GameManifest) {
+ let path = etcetera::choose_app_strategy(manifest.app_strategy_args())
+ .unwrap()
+ .in_state_dir("log")
+ .unwrap();
+ let path = path.to_string_lossy();
+ ProLogger::builder()
+ .with_rotating_file(&path, RotationConfig::new(100_000, 2))
+ .with_color(ColorMode::Never)
+ .init()
+ .unwrap();
+}
+
+pub fn run_game(mut files: FileManager, wasm_runner: WasmRunner, manifest: GameManifest) {
+ let start = Instant::now();
+
+ let stdout = Box::new(BufWriter::new(std::io::stdout().lock()));
+ let mut framerate_limit: Option<Duration> = None;
+ let mut buffer = Buffer::new(stdout).unwrap();
+ let mut input = InputManager::new();
+ let mut time = TimeContext::new();
+ let mut storage = StorageManager::load(manifest.app_strategy_args()).unwrap();
+ let mut scripts = ScriptManager::new(&manifest.scripts);
+ let mut context = ScriptContext {
+ framerate_limit: &mut framerate_limit,
+ manifest: &manifest,
+ buffer: &mut buffer,
+ storage: &mut storage,
+ input: &input,
+ time: &time,
+ operation_queue: Vec::new(),
+ };
+
+ let scene_start = Instant::now();
+ switch_scenes(
+ &mut scripts,
+ &mut context,
+ &mut files,
+ &wasm_runner,
+ manifest.first_scene,
+ );
+ log::info!(
+ "Switch scenes time: {} ms",
+ scene_start.elapsed().as_millis()
+ );
+
+ 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);
+
+ log::info!("Total startup time: {} ms", start.elapsed().as_millis());
+ buffer
+ .render_loop(|buffer, event| match event {
+ Event::Key(event) => {
+ if event.is_press() {
+ input.press_key(event.code);
+ }
+ }
+ Event::Mouse(event) => {
+ match event.kind {
+ MouseEventKind::Down(_) => input.click_mouse(),
+ MouseEventKind::ScrollDown => input.scroll(Direction::Down),
+ MouseEventKind::ScrollUp => input.scroll(Direction::Up),
+ MouseEventKind::ScrollLeft => input.scroll(Direction::Left),
+ MouseEventKind::ScrollRight => input.scroll(Direction::Right),
+ _ => (),
+ }
+
+ input.move_mouse(Position {
+ x: event.column,
+ y: event.row,
+ });
+ }
+ Event::FocusChanged(is_focused) => {
+ if is_focused {
+ input.focus();
+ } else {
+ input.unfocus();
+ }
+ }
+ Event::Render => {
+ input.read_gil_events();
+ buffer.cells.clear();
+ let mut context = ScriptContext {
+ framerate_limit: &mut framerate_limit,
+ manifest: &manifest,
+ buffer,
+ storage: &mut storage,
+ input: &input,
+ time: &time,
+ operation_queue: Vec::new(),
+ };
+ scripts.run_scripts(&mut context, &wasm_runner, &mut files);
+ files.reload_files(&wasm_runner);
+ input.reset_next_frame();
+ if let Some(framerate_limit) = framerate_limit
+ && let Ok(elapsed) = time.system_now().elapsed()
+ {
+ std::thread::sleep(framerate_limit - elapsed);
+ }
+ time.next_frame();
+ }
+ })
+ .unwrap();
+}