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