diff options
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | console/Cargo.toml | 4 | ||||
| -rw-r--r-- | console/src/lib.rs | 58 | ||||
| -rw-r--r-- | game.json | 2 | ||||
| -rw-r--r-- | profiler/src/lib.rs | 13 | ||||
| -rw-r--r-- | scripts/Cargo.toml | 2 | ||||
| -rw-r--r-- | scripts/src/wasm.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 82 | ||||
| -rw-r--r-- | sys/src/lib.rs | 2 | ||||
| -rw-r--r-- | sys/src/renderer.rs | 12 |
10 files changed, 101 insertions, 79 deletions
@@ -16,10 +16,11 @@ alligator_scripts = { path = "scripts" } alligator_sprites = { path = "sprites" } alligator_sys = { path = "sys" } -clap = "4" +clap = { version = "4", features=["derive"] } serde = "1" serde_json = "1" pollster = "0.3" +log = "0.4" sha3 = "0.10" [profile.release] diff --git a/console/Cargo.toml b/console/Cargo.toml index 0d23054..18ea28d 100644 --- a/console/Cargo.toml +++ b/console/Cargo.toml @@ -6,6 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -smol = "2" -log = "0.4" -pollster = "0.3"
\ No newline at end of file +log = "0.4"
\ No newline at end of file diff --git a/console/src/lib.rs b/console/src/lib.rs index d98183c..578d255 100644 --- a/console/src/lib.rs +++ b/console/src/lib.rs @@ -1,13 +1,9 @@ -use std::net::Ipv6Addr; +use std::io::{stdout, Write}; +use std::sync::mpsc::{Receiver, Sender}; use log::Level; -use pollster::FutureExt; -use smol::channel::{Receiver, Sender}; -use smol::io::AsyncWriteExt; -use smol::net::{TcpListener, TcpStream}; pub struct Console { - tcp_socket: TcpStream, messages: Receiver<ConsoleMessage>, sender: Sender<ConsoleMessage>, } @@ -41,11 +37,8 @@ pub enum ConsoleMessage { impl Console { pub async fn new(port: u16) -> Result<Self, std::io::Error> { - let tcp_listener = TcpListener::bind((Ipv6Addr::LOCALHOST, port)).await?; - let tcp_socket = tcp_listener.accept().await?.0; - let (sender, reciever) = smol::channel::unbounded(); + let (sender, reciever) = std::sync::mpsc::channel(); Ok(Self { - tcp_socket, messages: reciever, sender, }) @@ -59,9 +52,11 @@ impl Console { ConsoleLogger(self.sender()) } - pub async fn flush(&mut self) -> std::io::Result<()> { + pub fn flush(&self) -> std::io::Result<()> { + let mut stdout = stdout().lock(); + while let Ok(message) = self.messages.try_recv() { - match message { + let message = match message { ConsoleMessage::RuntimeLog { message, level, @@ -69,8 +64,7 @@ impl Console { line, } => { let message = message.replace('\n', "\\n"); - let msg = format!("runtimelog {level} {file}:{line} {message}\n"); - self.tcp_socket.write(msg.as_bytes()).await?; + format!("runtimelog {level} {file}:{line} {message}\n") } ConsoleMessage::ScriptLog { message, @@ -79,32 +73,31 @@ impl Console { line, } => { let message = message.replace('\n', "\\n"); - let msg = format!("scriptlog {level} {file}:{line} {message}\n"); - self.tcp_socket.write(msg.as_bytes()).await?; + format!("scriptlog {level} {file}:{line} {message}\n") } ConsoleMessage::FrameTime { timestamp: unix_timestamp, } => { - let msg = format!("frametime {unix_timestamp}"); - self.tcp_socket.write(msg.as_bytes()).await?; + format!("frametime {unix_timestamp}") } ConsoleMessage::ScopeStart { scope_name, timestamp: unix_timestamp, } => { - let msg = format!("scopestart {scope_name} {unix_timestamp}"); - self.tcp_socket.write(msg.as_bytes()).await?; + format!("scopestart {scope_name} {unix_timestamp}") } ConsoleMessage::ScopeEnd { timestamp: unix_timestamp, } => { - let msg = format!("scopeend {unix_timestamp}"); - self.tcp_socket.write(msg.as_bytes()).await?; + format!("scopeend {unix_timestamp}") } - } + }; + + stdout.write_all(message.as_bytes())?; + stdout.write_all(b"\n")?; } - self.tcp_socket.flush().await?; + stdout.flush()?; Ok(()) } @@ -112,7 +105,7 @@ impl Console { impl ConsoleLogger { pub fn send(&self, message: ConsoleMessage) { - _ = self.0.send(message).block_on(); + _ = self.0.send(message); } } @@ -122,15 +115,12 @@ impl log::Log for ConsoleLogger { } fn log(&self, record: &log::Record) { - let _ = self - .0 - .send(ConsoleMessage::RuntimeLog { - message: record.args().to_string(), - level: record.level(), - file: record.file().map(str::to_string).unwrap_or_default(), - line: record.line().unwrap_or_default(), - }) - .block_on(); + let _ = self.0.send(ConsoleMessage::RuntimeLog { + message: record.args().to_string(), + level: record.level(), + file: record.file().map(str::to_string).unwrap_or_default(), + line: record.line().unwrap_or_default(), + }); } fn flush(&self) {} @@ -1,5 +1,5 @@ {
- "alligator_version": 0,
+ "alligator_version": "0.1",
"scenes": {
"black": {
"initial_sprites": {},
diff --git a/profiler/src/lib.rs b/profiler/src/lib.rs index d23ad24..1a9558d 100644 --- a/profiler/src/lib.rs +++ b/profiler/src/lib.rs @@ -8,15 +8,11 @@ static GLOBAL_PROFILER: OnceLock<Profiler> = OnceLock::new(); struct Profiler { logger: ConsoleLogger, - start_time: DateTime<Utc>, } impl Profiler { fn new(logger: ConsoleLogger) -> Self { - Self { - logger, - start_time: Utc::now(), - } + Self { logger } } fn current_timestamp(&self) -> i64 { @@ -51,18 +47,17 @@ pub fn set_profiler(logger: ConsoleLogger) { } pub fn finish_frame() { - GLOBAL_PROFILER.get().unwrap().finish_frame(); + GLOBAL_PROFILER.get().inspect(|p| p.finish_frame()); } pub fn start_scope(scope_name: impl AsRef<str>) { GLOBAL_PROFILER .get() - .unwrap() - .start_scope(scope_name.as_ref().to_string()); + .inspect(|p| p.start_scope(scope_name.as_ref().to_string())); } pub fn end_scope() { - GLOBAL_PROFILER.get().unwrap().end_scope(); + GLOBAL_PROFILER.get().inspect(|p| p.end_scope()); } pub fn profile_scope(scope_name: impl AsRef<str>) -> ScopeGuard<(), impl FnOnce(())> { diff --git a/scripts/Cargo.toml b/scripts/Cargo.toml index a9fe5e4..8854678 100644 --- a/scripts/Cargo.toml +++ b/scripts/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -wasmtime = "15" +wasmtime = "24" rayon = "1" thiserror = "1" rand = "0.8" diff --git a/scripts/src/wasm.rs b/scripts/src/wasm.rs index 06d840f..7f8f0b5 100644 --- a/scripts/src/wasm.rs +++ b/scripts/src/wasm.rs @@ -72,7 +72,7 @@ fn validate_module(module: &Module) -> Result<(), InvalidWasmScript> { let Some(heap_base) = export.global() else {
return Err(InvalidWasmScript::HeapBaseIsNotGlobal);
};
- if *heap_base.content() != ValType::I32 {
+ if heap_base.content().matches(&ValType::I32) {
return Err(InvalidWasmScript::HeapBaseMustBeI32);
}
if heap_base.mutability() != Mutability::Const {
diff --git a/src/main.rs b/src/main.rs index c8d4618..100cfea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ use alligator_scripts::ScriptManager; use alligator_sprites::SpriteManager;
use alligator_sys::{Renderer, RendererConfig, Window, WindowConfig, WindowEvent};
+use clap::Parser;
use pollster::FutureExt;
use serde::Deserialize;
use sha3::{Digest, Sha3_256};
@@ -67,6 +68,19 @@ pub struct Config { vsync: bool,
}
+#[derive(Debug, Clone, Parser)]
+#[command(version, about, long_about = None)]
+pub struct CommandLineArguments {
+ /// The configuration, represented as a JSON object. If not specified,
+ /// this is retrieved from the game.json in the executable's directory.
+ #[arg(short, long)]
+ config: Option<Box<str>>,
+
+ /// Send and receive console commands through the stdio
+ #[arg(short, long)]
+ debug: bool,
+}
+
fn sprite_manager(config: &Config) -> SpriteManager {
SpriteManager::with_capacity(config.sprite_manager_capacity as usize)
}
@@ -98,10 +112,11 @@ fn script_manager(config: &Config) -> ScriptManager { fn window(config: &Config) -> Window {
let config = WindowConfig {
title: config.window_title.clone(),
- default_width: config.default_window_width.get(),
- default_height: config.default_window_height.get(),
- default_x: 100,
- default_y: 100,
+ // TODO set window size properly
+ default_width: config.default_window_width.unwrap().get(),
+ default_height: config.default_window_height.unwrap().get(),
+ default_x: 200,
+ default_y: 200,
borderless_fullscreen: config.default_window_mode == ConfigWindowMode::BorderlessFullscreen,
visible: false,
};
@@ -111,8 +126,9 @@ fn window(config: &Config) -> Window { fn renderer(config: &Config, window: &Window) -> Renderer {
let config = RendererConfig {
- width: config.default_window_width.get(),
- height: config.default_window_height.get(),
+ // TODO set window size properly
+ width: config.default_window_width.unwrap().get(),
+ height: config.default_window_height.unwrap().get(),
instance_capacity: config.sprite_manager_capacity,
fullscreen: false,
vsync: config.vsync,
@@ -122,14 +138,30 @@ fn renderer(config: &Config, window: &Window) -> Renderer { }
fn main() {
- let console = Console::new(26009)
- .block_on()
- .expect("The console should not fail to start");
- profile::set_profiler(console.logger());
+ let args = CommandLineArguments::parse();
+
+ let console = if args.debug {
+ let console = Console::new(26009)
+ .block_on()
+ .expect("The console should not fail to start");
+ log::set_logger(Box::leak(Box::new(console.logger())))
+ .expect("this should be the only logger");
+ profile::set_profiler(console.logger());
+
+ Some(console)
+ } else {
+ None
+ };
- std::env::set_current_dir(std::env::current_exe().unwrap().parent().unwrap()).unwrap();
- let config = File::open("game.json").unwrap();
- let config: Config = serde_json::from_reader(config).unwrap();
+ //std::env::set_current_dir(std::env::current_exe().unwrap().parent().unwrap()).unwrap();
+
+ let config = match args.config {
+ Some(config) => serde_json::from_str(&config).unwrap(),
+ None => {
+ let config = File::open("game.json").unwrap();
+ serde_json::from_reader(config).unwrap()
+ }
+ };
let sprites = sprite_manager(&config);
let scripts = script_manager(&config);
@@ -140,15 +172,21 @@ fn main() { let mut renderer = renderer(&config, &window);
window.set_visible(true);
- window.run(move |window, event| match event {
- Some(WindowEvent::RedrawRequest) => {
- renderer.render_frame();
- profile::finish_frame();
- }
- Some(WindowEvent::CloseRequest) => {
- std::process::exit(0);
+ window.run(move |window, event| {
+ match event {
+ Some(WindowEvent::RedrawRequest) => {
+ renderer.render_frame();
+ profile::finish_frame();
+ }
+ Some(WindowEvent::CloseRequest) => {
+ std::process::exit(0);
+ }
+ Some(_) => (),
+ None => window.request_redraw(),
+ };
+
+ if let Some(c) = &console {
+ c.flush().expect("why would this error?");
}
- Some(_) => (),
- None => window.request_redraw(),
})
}
diff --git a/sys/src/lib.rs b/sys/src/lib.rs index f3fae9c..ddce186 100644 --- a/sys/src/lib.rs +++ b/sys/src/lib.rs @@ -64,7 +64,7 @@ extern "C" { fn new_renderer(config: RendererConfig, window: CWindow) -> CRenderer; fn resize_renderer(renderer: CRenderer, width: c_uint, height: c_uint); fn set_vsync(renderer: CRenderer, vsync: bool); - fn create_vertex_buffer(renderer: CRenderer, count: c_uint, instances: *const Vertex); + //fn create_vertex_buffer(renderer: CRenderer, count: c_uint, instances: *const Vertex); fn set_camera( renderer: CRenderer, x: f32, diff --git a/sys/src/renderer.rs b/sys/src/renderer.rs index a4dab20..31431ea 100644 --- a/sys/src/renderer.rs +++ b/sys/src/renderer.rs @@ -24,12 +24,12 @@ impl Renderer { unsafe { crate::set_vsync(self.ptr, vsync) }
}
- pub fn create_vertex_buffer(&mut self, vertices: &[Vertex]) {
- assert!(vertices.len() < (u32::MAX as usize), "Too many triangles!");
- let ptr = vertices.as_ptr();
- let len = vertices.len();
- unsafe { crate::create_vertex_buffer(self.ptr, len as u32, ptr) }
- }
+ //pub fn create_vertex_buffer(&mut self, vertices: &[Vertex]) {
+ // assert!(vertices.len() < (u32::MAX as usize), "Too many triangles!");
+ // let ptr = vertices.as_ptr();
+ // let len = vertices.len();
+ // unsafe { crate::create_vertex_buffer(self.ptr, len as u32, ptr) }
+ //}
pub fn set_camera(
&mut self,
|
