Put model state into an Arc (#28)
Previously the model state was in a `static STATE` to make it accessible to all the various subsystems. This moves it into an Arc and plumbs the reference around via function arguments. That allows us to do non-static initialization, eg based on user config. I also moved some things into dioxus context. Co-authored-by: Sam Sartor <me@samsartor.com> Co-committed-by: Sam Sartor <me@samsartor.com>
This commit was merged in pull request #28.
This commit is contained in:
+24
-19
@@ -1,7 +1,6 @@
|
||||
use app::Chat;
|
||||
use app::Command;
|
||||
use app::ConnectionState;
|
||||
use app::STATE;
|
||||
use asynchronous_codec::FramedRead;
|
||||
use asynchronous_codec::FramedWrite;
|
||||
use color_eyre::eyre::{bail, Error};
|
||||
@@ -27,6 +26,8 @@ use std::time::Duration;
|
||||
use tracing::error;
|
||||
use tracing::info;
|
||||
|
||||
use crate::app::SharedState;
|
||||
use crate::app::State;
|
||||
use crate::effects::AudioProcessor;
|
||||
use crate::imp::{
|
||||
AudioPlayer, AudioPlayerInterface as _, AudioSystem, AudioSystemInterface as _, Platform,
|
||||
@@ -38,7 +39,7 @@ mod effects;
|
||||
pub mod imp;
|
||||
mod msghtml;
|
||||
|
||||
pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>) {
|
||||
pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>, state: SharedState) {
|
||||
loop {
|
||||
let Some(Command::Connect {
|
||||
address,
|
||||
@@ -49,21 +50,23 @@ pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>) {
|
||||
panic!("did not receive connect command")
|
||||
};
|
||||
|
||||
*STATE.server.write() = Default::default();
|
||||
*STATE.status.write() = ConnectionState::Connecting;
|
||||
*state.server.write_unchecked() = Default::default();
|
||||
*state.status.write_unchecked() = ConnectionState::Connecting;
|
||||
if let Err(error) =
|
||||
Platform::network_connect(address, username, &mut event_rx, &config).await
|
||||
Platform::network_connect(address, username, &mut event_rx, &config, state.clone())
|
||||
.await
|
||||
{
|
||||
error!("could not connect {:?}", error);
|
||||
*STATE.status.write() = ConnectionState::Failed(error.to_string());
|
||||
*state.status.write_unchecked() = ConnectionState::Failed(error.to_string());
|
||||
} else {
|
||||
*STATE.status.write() = ConnectionState::Disconnected;
|
||||
*state.status.write_unchecked() = ConnectionState::Disconnected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn network_loop<R: AsyncRead + Unpin + 'static, W: AsyncWrite + Unpin + 'static>(
|
||||
username: String,
|
||||
state: SharedState,
|
||||
event_rx: &mut UnboundedReceiver<Command>,
|
||||
mut reader: FramedRead<R, ControlCodec<Serverbound, Clientbound>>,
|
||||
mut writer: FramedWrite<W, ControlCodec<Serverbound, Clientbound>>,
|
||||
@@ -149,7 +152,7 @@ pub async fn network_loop<R: AsyncRead + Unpin + 'static, W: AsyncWrite + Unpin
|
||||
if !matches!(msg, ControlPacket::UDPTunnel(_) | ControlPacket::Ping(_)) {
|
||||
info!("receiving packet {:#?}", msg);
|
||||
}
|
||||
let res = accept_packet(msg, &mut audio, &mut decoder_map);
|
||||
let res = accept_packet(msg, &mut audio, &mut decoder_map, &state);
|
||||
if let Err(err) = res {
|
||||
error!("error accepting packet {:?}", err)
|
||||
}
|
||||
@@ -168,7 +171,7 @@ pub async fn network_loop<R: AsyncRead + Unpin + 'static, W: AsyncWrite + Unpin
|
||||
match command {
|
||||
Some(Command::Disconnect) => break,
|
||||
Some(command) => {
|
||||
let res = accept_command(command, &mut send_chan, &mut audio);
|
||||
let res = accept_command(command, &mut send_chan, &mut audio, &state);
|
||||
if let Err(err) = res {
|
||||
info!("error accepting command {:?}", err)
|
||||
}
|
||||
@@ -187,9 +190,10 @@ fn accept_command(
|
||||
command: Command,
|
||||
send_chan: &mut UnboundedSender<ControlPacket<mumble_protocol::Serverbound>>,
|
||||
audio: &mut AudioSystem,
|
||||
state: &State,
|
||||
) -> Result<(), Error> {
|
||||
use Command::*;
|
||||
let Some(session) = STATE.server.read().session else {
|
||||
let Some(session) = state.server.read().session else {
|
||||
bail!("no session id")
|
||||
};
|
||||
|
||||
@@ -212,7 +216,7 @@ fn accept_command(
|
||||
};
|
||||
|
||||
{
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
let Some(me) = server.session else {
|
||||
bail!("not signed in with a session id")
|
||||
};
|
||||
@@ -253,7 +257,7 @@ fn accept_command(
|
||||
};
|
||||
|
||||
{
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
let Some(me) = server.session else {
|
||||
bail!("not signed in with a session id")
|
||||
};
|
||||
@@ -304,6 +308,7 @@ fn accept_packet(
|
||||
msg: ControlPacket<mumble_protocol::Clientbound>,
|
||||
audio_context: &mut AudioSystem,
|
||||
player_map: &mut HashMap<u32, AudioPlayer>,
|
||||
state: &State,
|
||||
) -> Result<(), Error> {
|
||||
match msg {
|
||||
ControlPacket::UDPTunnel(u) => {
|
||||
@@ -340,15 +345,15 @@ fn accept_packet(
|
||||
}
|
||||
}
|
||||
ControlPacket::ChannelState(u) => {
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
server.channels_state.update_from_channel_state(&u);
|
||||
}
|
||||
ControlPacket::ChannelRemove(u) => {
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
server.channels_state.update_from_channel_remove(&u);
|
||||
}
|
||||
ControlPacket::UserState(u) => {
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
let server = &mut *server;
|
||||
let id = u.get_session();
|
||||
|
||||
@@ -392,7 +397,7 @@ fn accept_packet(
|
||||
}
|
||||
}
|
||||
ControlPacket::UserRemove(u) => {
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
let id = u.get_session();
|
||||
if let Some(state) = server.users.remove(&id) {
|
||||
if let Some(parent) = server.channels_state.channels.get_mut(&state.channel) {
|
||||
@@ -401,7 +406,7 @@ fn accept_packet(
|
||||
}
|
||||
}
|
||||
ControlPacket::TextMessage(u) => {
|
||||
let mut server = STATE.server.write();
|
||||
let mut server = state.server.write_unchecked();
|
||||
if u.has_message() {
|
||||
let text = u.get_message().to_string();
|
||||
server.chat.push(Chat {
|
||||
@@ -416,8 +421,8 @@ fn accept_packet(
|
||||
}
|
||||
}
|
||||
ControlPacket::ServerSync(u) => {
|
||||
*STATE.status.write() = ConnectionState::Connected;
|
||||
let mut server = STATE.server.write();
|
||||
*state.status.write_unchecked() = ConnectionState::Connected;
|
||||
let mut server = state.server.write_unchecked();
|
||||
if u.has_welcome_text() {
|
||||
let text = u.get_welcome_text().to_string();
|
||||
server.chat.push(Chat {
|
||||
|
||||
Reference in New Issue
Block a user