refactor: clean up locking and convert to async
This commit is contained in:
		
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -1179,12 +1179,12 @@ dependencies = [ | ||||
|  "anyhow", | ||||
|  "azalea", | ||||
|  "clap", | ||||
|  "futures", | ||||
|  "http-body-util", | ||||
|  "hyper", | ||||
|  "hyper-util", | ||||
|  "log", | ||||
|  "mlua", | ||||
|  "parking_lot", | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
|   | ||||
| @@ -24,5 +24,5 @@ hyper = { version = "1", features = ["server"] } | ||||
| hyper-util = "0" | ||||
| log = { version = "0" } | ||||
| mlua = { version = "0", features = ["async", "luau", "send"] } | ||||
| parking_lot = { version = "0" } | ||||
| tokio = { version = "1", features = ["macros"] } | ||||
| futures = "0" | ||||
|   | ||||
| @@ -7,7 +7,7 @@ use azalea::{ | ||||
|     prelude::*, | ||||
| }; | ||||
| use bevy_ecs::{entity::Entity, query::With}; | ||||
| use parking_lot::Mutex; | ||||
| use futures::lock::Mutex; | ||||
|  | ||||
| pub type Ctx<'a> = CommandContext<Mutex<CommandSource>>; | ||||
|  | ||||
| @@ -40,35 +40,43 @@ impl CommandSource { | ||||
|  | ||||
| pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) { | ||||
|     commands.register(literal("reload").executes(|ctx: &Ctx| { | ||||
|         let source = ctx.source.lock(); | ||||
|         source.reply(&format!("{:?}", reload(&source.state.lua.lock()))); | ||||
|         let source = ctx.source.clone(); | ||||
|         tokio::spawn(async move { | ||||
|             let source = source.lock().await; | ||||
|             source.reply(&format!("{:?}", reload(&source.state.lua))); | ||||
|         }); | ||||
|         1 | ||||
|     })); | ||||
|  | ||||
|     commands.register( | ||||
|         literal("eval").then(argument("code", string()).executes(|ctx: &Ctx| { | ||||
|             let source = ctx.source.lock(); | ||||
|             source.reply(&format!( | ||||
|                 "{:?}", | ||||
|                 eval(&source.state.lua.lock(), &get_string(ctx, "code").unwrap()) | ||||
|             )); | ||||
|             let source = ctx.source.clone(); | ||||
|             let code = get_string(ctx, "code").unwrap(); | ||||
|             tokio::spawn(async move { | ||||
|                 let source = source.lock().await; | ||||
|                 source.reply(&format!("{:?}", eval(&source.state.lua, &code).await)); | ||||
|             }); | ||||
|             1 | ||||
|         })), | ||||
|     ); | ||||
|  | ||||
|     commands.register( | ||||
|         literal("exec").then(argument("code", string()).executes(|ctx: &Ctx| { | ||||
|             let source = ctx.source.lock(); | ||||
|             source.reply(&format!( | ||||
|                 "{:?}", | ||||
|                 exec(&source.state.lua.lock(), &get_string(ctx, "code").unwrap()) | ||||
|             )); | ||||
|             let source = ctx.source.clone(); | ||||
|             let code = get_string(ctx, "code").unwrap(); | ||||
|             tokio::spawn(async move { | ||||
|                 let source = source.lock().await; | ||||
|                 source.reply(&format!("{:?}", exec(&source.state.lua, &code).await)); | ||||
|             }); | ||||
|             1 | ||||
|         })), | ||||
|     ); | ||||
|  | ||||
|     commands.register(literal("ping").executes(|ctx: &Ctx| { | ||||
|         ctx.source.lock().reply("pong!"); | ||||
|         let source = ctx.source.clone(); | ||||
|         tokio::spawn(async move { | ||||
|             source.lock().await.reply("pong!"); | ||||
|         }); | ||||
|         1 | ||||
|     })); | ||||
| } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ use mlua::{Function, IntoLuaMulti, Table}; | ||||
| use tokio::net::TcpListener; | ||||
|  | ||||
| pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow::Result<()> { | ||||
|     let globals = state.lua.lock().globals(); | ||||
|     let globals = state.lua.globals(); | ||||
|  | ||||
|     match event { | ||||
|         Event::Chat(message) => { | ||||
| @@ -40,7 +40,7 @@ pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow: | ||||
|             call_lua_handler(&globals, "on_chat", ()); | ||||
|         } | ||||
|         Event::Death(Some(packet)) => { | ||||
|             let death_data = state.lua.lock().create_table()?; | ||||
|             let death_data = state.lua.create_table()?; | ||||
|             death_data.set("message", packet.message.to_string())?; | ||||
|             death_data.set("player_id", packet.player_id)?; | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/http.rs
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/http.rs
									
									
									
									
									
								
							| @@ -12,7 +12,7 @@ pub async fn serve( | ||||
|     let path = request.uri().path().to_owned(); | ||||
|  | ||||
|     Ok(match (request.method(), path.as_str()) { | ||||
|         (&Method::POST, "/reload") => match reload(&state.lua.lock()) { | ||||
|         (&Method::POST, "/reload") => match reload(&state.lua) { | ||||
|             Ok(()) => Response::new(empty()), | ||||
|             Err(error) => status_code_response( | ||||
|                 StatusCode::INTERNAL_SERVER_ERROR, | ||||
| @@ -23,14 +23,11 @@ pub async fn serve( | ||||
|         (&Method::POST, "/eval" | "/exec") => { | ||||
|             let bytes = request.into_body().collect().await?.to_bytes(); | ||||
|             match std::str::from_utf8(&bytes) { | ||||
|                 Ok(code) => { | ||||
|                     let lua = state.lua.lock(); | ||||
|                     Response::new(full(match path.as_str() { | ||||
|                         "/eval" => format!("{:?}", eval(&lua, code)), | ||||
|                         "/exec" => format!("{:?}", exec(&lua, code)), | ||||
|                         _ => unreachable!(), | ||||
|                     })) | ||||
|                 } | ||||
|                 Ok(code) => Response::new(full(match path.as_str() { | ||||
|                     "/eval" => format!("{:?}", eval(&state.lua, code).await), | ||||
|                     "/exec" => format!("{:?}", exec(&state.lua, code).await), | ||||
|                     _ => unreachable!(), | ||||
|                 })), | ||||
|                 Err(error) => status_code_response( | ||||
|                     StatusCode::BAD_REQUEST, | ||||
|                     full(format!("invalid utf-8 data received: {error:?}")), | ||||
|   | ||||
							
								
								
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -10,15 +10,15 @@ use azalea::{brigadier::prelude::CommandDispatcher, prelude::*}; | ||||
| use clap::Parser; | ||||
| use commands::{CommandSource, register}; | ||||
| use events::handle_event; | ||||
| use futures::lock::Mutex; | ||||
| use mlua::Lua; | ||||
| use parking_lot::Mutex; | ||||
| use std::{net::SocketAddr, path::PathBuf, sync::Arc}; | ||||
|  | ||||
| #[derive(Default, Clone, Component)] | ||||
| pub struct State { | ||||
|     commands: Arc<CommandDispatcher<Mutex<CommandSource>>>, | ||||
|     lua: Arc<Mutex<Lua>>, | ||||
|     lua: Lua, | ||||
|     http_address: Option<SocketAddr>, | ||||
|     commands: Arc<CommandDispatcher<Mutex<CommandSource>>>, | ||||
| } | ||||
|  | ||||
| #[tokio::main] | ||||
| @@ -42,9 +42,9 @@ async fn main() -> anyhow::Result<()> { | ||||
|     let Err(error) = ClientBuilder::new() | ||||
|         .set_handler(handle_event) | ||||
|         .set_state(State { | ||||
|             commands: Arc::new(commands), | ||||
|             lua: Arc::new(Mutex::new(lua)), | ||||
|             lua, | ||||
|             http_address: args.http_address, | ||||
|             commands: Arc::new(commands), | ||||
|         }) | ||||
|         .start( | ||||
|             if username.contains('@') { | ||||
|   | ||||
| @@ -28,10 +28,13 @@ pub fn reload(lua: &Lua) -> Result<(), Error> { | ||||
|     .map_err(Error::LoadChunk) | ||||
| } | ||||
|  | ||||
| pub fn eval(lua: &Lua, code: &str) -> Result<String, Error> { | ||||
|     lua.load(code).eval::<String>().map_err(Error::EvalChunk) | ||||
| pub async fn eval(lua: &Lua, code: &str) -> Result<String, Error> { | ||||
|     lua.load(code) | ||||
|         .eval_async::<String>() | ||||
|         .await | ||||
|         .map_err(Error::EvalChunk) | ||||
| } | ||||
|  | ||||
| pub fn exec(lua: &Lua, code: &str) -> Result<(), Error> { | ||||
|     lua.load(code).exec().map_err(Error::ExecChunk) | ||||
| pub async fn exec(lua: &Lua, code: &str) -> Result<(), Error> { | ||||
|     lua.load(code).exec_async().await.map_err(Error::ExecChunk) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user